nomurabbitのブログ

nomurabbitのブログはITを中心にした技術ブログです。

nomurabbitのブログ

【React】React Hook Formの "はじめる" を始めてみた Part3【Typescript】

この記事はReact Hook Formの公式サイトにあるはじめるの項目を元に構成されています。ReactとTypescriptのサンプルコードを使って解説しています。

こんにちは!らびです。今回はReact Hook Formに関する記事です。

公式サイトのチュートリアルを使って一緒に勉強していきましょう。

バリデーションを適用する

今回もサンプルコードを解説していきます。React Hook FormのサンプルコードをReactのプロジェクトにうつしたものがこちらです。

import React from 'react';
import { useForm, SubmitHandler } from "react-hook-form";
import {List, ListItem} from '@mui/material';
import ResponsiveDrawer from '../components/layout/ResponsiveDrawer';

interface IFormInput {
  firstName: string;
  lastName: string;
  age: number;
}

const Home3 = () => {
  const { register, handleSubmit } = useForm<IFormInput>();
  const onSubmit: SubmitHandler<IFormInput> = (data) => {
    console.log(data);
  }
  
  return (
    <ResponsiveDrawer>
      <div>
        <form onSubmit={handleSubmit(onSubmit)}>
          <List>
            <ListItem>
              <label>First Name</label>
              <input {...register("firstName", { required: true, maxLength: 20 })} />
            </ListItem><ListItem>
              <label>Last Name</label>
              <input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
            </ListItem><ListItem>
              <label>Age</label>
              <input type="number" {...register("age", { min: 18, max: 99 })} />
            </ListItem><ListItem>
              <input type="submit" />
            </ListItem>
          </List>
        </form>
      </div>
    </ResponsiveDrawer>
  );
}
  
export default Home3;

実行結果はこんな感じだジョ。

f:id:nomurabbit:20220110075025p:plain

import

まずはimportです。前回前々回と同じくuseFormSubmitHandlerをインポートしています。

import { useForm, SubmitHandler } from "react-hook-form";

useFormは入力コンポーネントの登録、SubmitHandlerはサブミット時の処理を制御でしたね。だいぶ覚えてきました!

interface IFormInput {
  firstName: string;
  lastName: string;
  age: number;
}

…省略
const { register, handleSubmit } = useForm<IFormInput>();

useFormのジェネリクスパラメータとしてIFormInputを渡しているジョ。

firstNamelastNameageという名前の入力コンポーネントを扱います。

register

次は入力コンポーネントの登録です。firstNamelastNameageに対して、それぞれ入力コンポーネントを登録しています 。注目すべきはregisterの第二引数です。

const onSubmit: SubmitHandler<IFormInput> = (data) => {
  console.log(data);
}

return (
  <ResponsiveDrawer>
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        <List>
          <ListItem>
            <label>First Name</label>
            <input {...register("firstName", { required: true, maxLength: 20 })} />
          </ListItem><ListItem>
            <label>Last Name</label>
            <input {...register("lastName", { pattern: /^[A-Za-z]+$/i })} />
          </ListItem><ListItem>
            <label>Age</label>
            <input type="number" {...register("age", { min: 18, max: 99 })} />
          </ListItem><ListItem>
            <input type="submit" />
          </ListItem>
        </List>
      </form>
    </div>
  </ResponsiveDrawer>
);

requiredとかmaxLengthとかpatternとかminとかmaxとか渡しているジョ。

registerの第二引数には入力コンポーネントバリデーションに関するパラメータを指定できます。指定できるパラメータはTypescriptの型で確認することができます。

export declare type RegisterOptions<TFieldValues extends FieldValues = 
  FieldValues, TFieldName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = 
  Partial<{
    required: Message | ValidationRule<boolean>;
    min: ValidationRule<number | string>;
    max: ValidationRule<number | string>;
    maxLength: ValidationRule<number>;
    minLength: ValidationRule<number>;
    pattern: ValidationRule<RegExp>;
    validate: Validate<FieldPathValue<TFieldValues, TFieldName>> | Record<string, Validate<FieldPathValue<TFieldValues, TFieldName>>>;
    valueAsNumber: boolean;
    valueAsDate: boolean;
    value: FieldPathValue<TFieldValues, TFieldName>;
    setValueAs: (value: any) => any;
    shouldUnregister?: boolean;
    onChange?: (event: any) => void;
    onBlur?: (event: any) => void;
    disabled: boolean;
    deps: InternalFieldName[];
  }>;

まとめ

というわけで、今回もReact Hook Formはじめるについて勉強してきましたが、いかがでしたでしょうか?

今回は入力コンポーネントのバリデーションについて勉強できましたね。

次回もぜひご覧ください。では!

参考

React Hook Form
react-hook-form.com