😀
React Hook Formで独自の複数選択を実装する
前回書いたタグ入力のコンポーネントをReact Hook Formで組み込んだメモです。
簡易実装は以下になります。
環境
- React 18.2.0
- React Hook Form 7.47.0
- TailwindCSS 2.2.19
- clsx 2.0
- TypeScript
実装
独自の複数選択を処理するにはControllerを使うのが良さそうです。
他にもReact-SelectやAntD、MUIなどの外部制御コンポーネントとの連携を容易してくれます。
Propsの定義
普通のフォームは入力項目が複数あると思いますが今回はとりあえずタグ入力のみのフォームとして定義しています。
App.tsx
type TagForm = {
tags: string[]
}
フォーム
Controllerは使用したい外部コンポーネントをラップして利用します。(renderから返す)
必要な項目はname
、contrl
、render
になります。
controlはどのuseFormかを登録するものです。
renderの処理は特に記述するような内容ではありませんが変更を検知してsetValue()
で値の更新を行います。
Controllerでは他にもdefaultValue
やrules
なども渡すことができます。
詳細はドキュメントを確認してください。
App.tsx
const App: React.FC = () => {
const [formValues, setFormValues] = React.useState({})
const {control, handleSubmit, setValue, formState: { errors }} = useForm<TagForm>()
const onSubmit = (form: TagForm) => {
//APIへ送信するなどの処理
console.log(form)
setFormValues(form)
}
return <form onSubmit={handleSubmit(onSubmit)}>
<Controller
name="tags"
control={control}
defaultValue={["hoge"]}
rules={{required: true}}
render={({field: { value }} ) => {
return (
<TagsInput tags={value}
onChangeTags={(tags) => setValue('tags', tags)}
/>
)
}}
/>
{errors.tags && (<div className={"text-red-500"}>tag is required.</div>)}
<button type="submit" className={"mt-2 bg-green-500 text-white py-2 px-4 text-m rounded"}>送信する</button>
<div className={"mt-2 p-4 bg-gray-100"}>{JSON.stringify(formValues)}</div>
</form>
}
ReactDOM.render(<App />,
document.getElementById('root'));
最後に
いかがだったでしょうか。
参考になったよっという方はぜひいいねよろしくお願いします!!
Discussion