はじめに
使用ライブラリ
React-hook-form
: フォームの値の制御やValidationが簡単でできるすごいやつ
zod
: 型定義が便利らしい。
使用経験
React-hook-form
: メインで触ってはないですが、業務で 触っていました。
zod
:触ったことないですが、便利らしいのでこの機会に学んでみようかと
設計
下記で作成した、ものを対象に React-hook-form
ログイン時にValitadion をつけていきましょう。
import { Box, Button, Paper, TextField, Typography } from '@mui/material';
export const Login = () => {
return (
<>
<Paper
elevation={3}
sx={{
borderRadius: 6,
p: 4,
height: '70vh',
width: '280px',
m: '20px auto',
}}
>
<Box
mt={8}
display='flex'
flexDirection='column'
gap={5}
alignItems='center'
>
<Typography variant='h5' fontWeight="bold">ログイン画面</Typography>
<TextField
type='id'
name='user_id'
variant='standard'
placeholder='ユーザーIDを入力してください'
fullWidth
/>
<TextField
type='password'
name='password'
variant='standard'
placeholder='パスワードを入力してください'
fullWidth
/>
<Button type='submit' color='primary' variant='contained' fullWidth>
ログイン
</Button>
</Box>
</Paper>
</>
);
}
上記の ログインをクリックしたら、Validation で引っかかる or 成功する といった風に実装していきましょう。
普通ログイン画面でこういう Validation はかけませんが、想定として
ID : メースアドレスの形式
PW : 8文字以上、32文字以下、半角英語、半角数字を含む
このような形で想定しておきます。
じゃあ実装しましょ〜
実装
react-hook-form
npm i react-hook-form
で react-hook-form を install します。
import { Box, Button, Paper, TextField, Typography } from '@mui/material';
// import する
import { useForm } from "react-hook-form";
export const Login = () => {
const { register, handleSubmit, watch, formState: { errors } } = useForm();
return (
--- 省略 ---
);
}
const { register, handleSubmit, watch, formState: { errors } } = useForm();
のように、useFormを使用します。
下記簡単な解説です。あとで実装時に見返してもらえればここでわからなくてもいいです。
-
register
: 各 input 要素に どのような名前が対応するか設定するためのもの、Validationもこの中でかけれる。 -
handleSubmit
: form にわたして、登録ボタン押下時に行う処理を記述 -
watch
: リアルタイムで今入っている値を管理する。 -
errors
: validation に引っかかった場合のエラーを管理する。
登録時の処理を設定
登録時の処理を関数とする。
/**
* 登録時の処理を関数化
* @param data formから受け取る値
*/
const onSubmit = (data) => {
// アラートで結果出してみる (見やすいようにJSON 形式にする)
alert(JSON.stringify(data));
};
form タグに 登録時処理を渡す。
<form onSubmit={handleSubmit(onSubmit)}>
各要素への命名を設定
適当な命名を 各TextFieldへregisterを用いて設定する。
<TextField
type='id'
name='id'
{...register('id')}
variant='standard'
placeholder='ユーザーIDを入力してください'
fullWidth
/>
<TextField
type='password'
name='password'
{...register('password')}
variant='standard'
placeholder='パスワードを入力してください'
fullWidth
/>
この段階で、Validation は設定できていないが、ログインボタンを押すと、値が受け取れていることを確認する。
Validation の実装
<TextField
type='id'
name='id'
{...register('id', { required: true })}
error={errors.id}
helperText={errors.id?.message}
variant='standard'
placeholder='ユーザーIDを入力してください'
fullWidth
/>
<TextField
type='password'
name='password'
{...register('password', { required: true })}
error={errors.password}
helperText={errors.password?.message}
variant='standard'
placeholder='パスワードを入力してください'
fullWidth
/>
とりあえずこんな感じで、値がない場合はのみフォームを赤くするように設定。
(うまくhelperText
出てないけど一旦無視)
挙動としてはこんな感じ
zod
項目に対しての簡単な Validation は上でできたいので、zod を用いて詳細な Validation をかけていきましょう。
npm install zod
で zod のインストールを行いましょう。
import { z } from "zod";
/**
* zod での Validation
*/
const FormData = z.object({
id: z.string().email("メアドじゃない"),
password: z
.string()
.min(8, "8文字以下だ")
.max(32, "32文字以上だ")
.regex(/^(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,100}$/i, "PWに半角英数字入れて"),
});
onSubmit 時点でvalidation を追加してみる。
import { z, ZodError } from "zod";
/**
* 登録時の処理を関数化
* @param data formから受け取る値
*/
const onSubmit = (data) => {
try {
FormData.parse(data);
// アラートで結果出してみる (見やすいようにJSON 形式にする)
alert(JSON.stringify(data));
} catch (e) {
if (e instanceof ZodError) {
alert(JSON.stringify(e.flatten().fieldErrors));
} else {
console.log(e);
}
}
};
挙動確認
失敗
失敗
- ID:
aaaaa@gmail.com
- PW:
aaaaaa
成功
- ID:
aaaaa@gmail.com
- PW:
aaaaa12345
あとがき
今回は Project を typeScript化 していないですが無理やり、Validation として zod
を使用してみました。
正直今回のケースだと、 react-hook-form
標準装備の Validation で十分だったかな。
ただ、 zod
自体は非常に直感的でわかりやすいものでした。
zod
が本領発揮するのは TypeScript の プロジェクトで複雑な Schema の型のやり取りなどかなと感じました。
Zod
を使用することで 型安全な開発ができるので、最近の流行りというのも納得ですね、何よりわかりやすかったです。
じゃあまた ˙︶˙)ノ"マタネー