WEBOPIXEL

React Hook Form v7 でUIコンポーネントを使う方法

Posted: 2021.11.22 / Category: javascript / Tag: 

ReactでバリデーションするのにはReact Hook Formという便利なライブラリがありますが、フォーム作るのにはMUIみたいなUIコンポーネントを使うことが多いと思います。
そこで今回はUIコンポーネントでReact Hook Formを使う方法をご紹介します。

Sponsored Link

使用するバージョン
react: 17.0.2
@mantine/core: 3.1.0
react-hook-form: 7.19.1
@hookform/error-message: 2.0.0

通常のinputでの使い方

最初にUIコンポーネントを使わない例をみてみましょう。

import React from 'react'
import { useForm, SubmitHandler, Controller } from 'react-hook-form'
import { ErrorMessage } from '@hookform/error-message'

type Post = {
    title: string
    body: string
    status: number
}

const IssueForm: React.VFC = () => {
	const { register, handleSubmit, formState: { errors }, control } = useForm<Post>()

	const onSubmit: SubmitHandler<Post> = data => console.log(data);

	return (
		<form onSubmit={handleSubmit(onSubmit)}>
			<input
                type="text"
                {...register('title', {
                    required: "必ず入力してください。",
                    maxLength: {
                        value: 255,
                        message: "255文字以内で入力してください。"
                    }
                })}
            />
            <ErrorMessage
                errors={errors}
                name="title"
                render={({ message }) => <p className="error">{message}</p>}
            />
			<button type="submit">保存</button>
		</form>
	)
}

...registerの部分で、name・onBlur・onChange・refが展開されるのでUIコンポーネントを使用する場合でもPropsがサポートされていればそのまま使えると思います。

コンポーネントUIを使った例

ControllerというコンポーネントのrenderにUIコンポーネントを入れることで使用することができます。 MantineにはInputというコンポーネントがあるので、それを使う場合はControllerを使用してrenderにUIコンポーネントを書きます。

<Controller
	name="title"
	control={control}
	rules={{
		required: "必ず入力してください。",
		maxLength: {
			value: 255,
			message: "255文字以内で入力してください。"
		}
	}}
	defaultValue={''}
	render={({ field }) => (
		<>
			<Input
				{...field}
				invalid={errors.title !== undefined}
			/>
			<ErrorMessage
				errors={errors}
				name="title"
				render={({ message }) => <p className="error">{message}</p>}
			/>
		</>
	)}
/>

でも、MantineのInputはControllerをつかわなくても、そのまま最初の方法でバリデーションできます。
Selectとかは使えないのでこの方法を試してみてください。