aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMasaya Tojo <masaya@tojo.tokyo>2024-08-05 23:26:43 +0900
committerMasaya Tojo <masaya@tojo.tokyo>2024-08-05 23:26:43 +0900
commit7fa73728582e2dfb26ff89786c27dd9da97bebc2 (patch)
treef0bf9963b8e88bde91cf5dc3d0049bf063d5b886 /src
parentff4f0419c31c93399c38a689c2a2c9b0114d7b49 (diff)
zod でバリデーションを試す
Diffstat (limited to 'src')
-rw-r--r--src/SignUp.css10
-rw-r--r--src/SignUp.tsx64
2 files changed, 74 insertions, 0 deletions
diff --git a/src/SignUp.css b/src/SignUp.css
index e69de29..602ed0a 100644
--- a/src/SignUp.css
+++ b/src/SignUp.css
@@ -0,0 +1,10 @@
+.SignUpForm {
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+}
+
+.error {
+ margin: 0;
+ color: red;
+}
diff --git a/src/SignUp.tsx b/src/SignUp.tsx
index d812b35..2a7f448 100644
--- a/src/SignUp.tsx
+++ b/src/SignUp.tsx
@@ -1,9 +1,73 @@
import './SignUp.css'
+import { useState } from "react";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import * as z from "zod"
+
+const schema = z.object({
+ name: z.string(),
+ email: z.string().email("それメアドじゃないよ"),
+ birthday: z.coerce.date().max(new Date(), { message: "まだ生まれてないじゃん" }),
+ language: z.string(),
+})
+
+type Answer = {
+ name: string,
+ email: string,
+ birthday: Date,
+ language: string,
+}
export const SignUp = () => {
+ const { register, handleSubmit, reset, formState: { errors } } = useForm<Answer>({
+ resolver: zodResolver(schema)
+ });
+ const [answer, setAnswer] = useState<Answer | null>(null);
+
+ const yourAnswer = answer ? (
+ <>
+ <h2>あなたの情報です</h2>
+ <dl>
+ <dt>おぬしの名前は…</dt>
+ <dd>{answer.name}</dd>
+ <dt>おぬしのメアドは…</dt>
+ <dd>{answer.email}</dd>
+ <dt>あなたの誕生日</dt>
+ <dd>{answer.birthday.getFullYear()}年{answer.birthday.getMonth()}月{answer.birthday.getDay()}日</dd>
+ <dt>おぬしの好きなプログラミング言語は…</dt>
+ <dd>{answer.language}</dd>
+ </dl>
+ </>
+ ) : (<></>)
+
return (
<>
<h1>会員登録</h1>
+ <form className="SignUpForm" onSubmit={handleSubmit((data) => setAnswer(data))}>
+ <label>お名前:</label>
+ <input {...register("name")} placeholder="おなまえ" />
+ {errors.name?.message}
+ <label>めるあど</label>
+ <input {...register("email", { required: true })} placeholder="めるあど" />
+ {errors.email?.message && <p className="error">{errors.email?.message}</p>}
+ <label>生まれた日</label>
+ <input {...register("birthday", { required: true })} placeholder="yyyy/mm/dd" />
+ {errors.birthday?.message && <p className="error">{errors.birthday?.message}</p>}
+ <label>好きなプログラミング言語</label>
+ <select {...register("language", { required: true })}>
+ <option value="">Select...</option>
+ <option value="Gulie">Guile</option>
+ <option value="Gauche">Gauche</option>
+ <option value="Racket">Racket</option>
+ <option value="Larceny">Larceny</option>
+ <option value="Chicken">Chicken</option>
+ </select>
+ {errors.language?.message && <p className="error">{errors.language?.message}</p>}
+ <input type="submit" />
+ <button type="button" onClick={() => reset()}>消す</button>
+ </form>
+
+ {yourAnswer}
</>
);
}