Closed8

[スクラップ] react-hook-form で新規登録フォームを作る

へぶんへぶん

練習に react-hook-form を使用してフォームを作る。今後実装する際の自分向けの参考資料として置いておく。

へぶんへぶん

以下の要件

  • 新規登録画面
  • 入力項目
    • ニックネーム
    • email
    • password
  • バリデーション
    • 全フィールド必須
    • nickname
      • 2文字以上, 20文字以下
    • email
      • email の形式
    • password
      • 8文字以上
    • バリデーションに引っ掛かったら、文字列を表示する
  • 最後コンポーネント化までする。パスワードとかも一緒にコンポーネント化できるのかよく分からない。
へぶんへぶん

yup のバリデーションメッセージ

yup ではバリデーションメッセージを設定しなければ、デフォルトの英語のエラーメッセージを伝えてくれるので、
各ルールを生やした際に日本語のメッセージも渡しておく。(ローカライズは一旦後回し)

const schema = yup.object().shape({
    nickname: yup.string()
        .min(2, 'ニックネームは2文字以上20文字以下で入力してください')
        .max(20, 'ニックネームは2文字以上20文字以下で入力してください')
        .required('ニックネームは必須項目です'),
})
へぶんへぶん

registerinput 要素に渡すことで接続されるので、忘れないように注意する。

const Form = () => {
    const {register, handleSubmit, formState: {errors}} = useForm({
        resolver: yupResolver(schema)
    })
    return (
        <form >
            <input
                id="nickname"
                {...register("nickname")}
            />
        </form>
    )
}
へぶんへぶん

エラーサマリー

エラーメッセージをまとめて表示するときは、以下のようにエラーメッセージをリンクにして、指定の ID に飛べるようにしておくのが良さそう。

<div>
    <h2>問題があります</h2>
    <ul>
        <li>
            <a href="#email">メールアドレスを入力してください</a>
        </li>
    </ul>
</div>

note

  • こういうユースケースを考えると、多分フィールドの ID はサーバーサイドに送信するパラメータ名になっている方が良さそう。
    • いざ、サーバーサイドから返却されたエラーメッセージを表示させたくなった場合に、id とフィールド名が異なっていたら混乱の元になるし、後から修正することになりそう。
  • エラーメッセージの文言考えるのも面倒だし、テイストブレそうだから spreadsheet 上で考えるとかした方が良さそう。

参考:
https://www.amazon.co.jp/dp/4862464513/ref=cm_sw_r_tw_dp_YTS93ZTMKGSFSSHHXASH

へぶんへぶん

yup の shape の key を型で縛る

shape の key として使用する値はデフォルトで string になっている。

  • 型で縛りたい
  • shap の key を <input>id と一致させたい

... ような場合は以下のように書く

type InputId = 'nickname'

type CustomFormRecord = Record<InputId, any>

const schema = yup.object().shape<CustomFormRecord>({
    nickname: yup.string()
        .min(2, 'ニックネームは2文字以上20文字以下で入力してください')
        .max(20, 'ニックネームは2文字以上20文字以下で入力してください')
        .required('ニックネームは必須項目です'),
})
このスクラップは2021/09/05にクローズされました