react-hook-form中的useForm和useFormContext有什么区别?
这是GLOBIS Advent Calendar 2023的第六篇文章。
你好 (nǐ
很荣幸有机会加入Groovis公司。
我是Yoshinyan。
我将参加Advent日历活动。
我收到了@hackpopo的棒,现在正在写作。
写这篇文章的动机
在实际工作中,我第一次使用React和React Hook Form,但对于useForm和useFormContext的关系,或者说它们的用法没有特别清楚的理解。即使我查阅了官方文档,上面也没有详细的解释,所以我无法理解。所以我写了一篇文章,可能会有其他人也有同样的想法。
React Hook Form (简称 RHF) 是一个 JavaScript 库,提供了一个简单且高效的方式来处理表单验证和数据获取。
从初步阅读的感觉来看,这是为了简化表单处理并提高执行速度而存在的。
使用react-hook-form库可以更简洁地隐藏处理,而不是直接在React中编写。如果有其他好的库,请在评论栏中告诉我。
useForm和useFormContext是什么
这是 react-hook-form 的 API。
这是用于表单相关的自定义钩子。
得出结论
useForm在管理表单的状态。
虽然可以单独使用useForm,但对于复杂的表单,可以使用useFormContext,通过useFormContext将useForm的状态和方法传递给子组件。
区分清晰的技巧
如果表单只包含一个组件,可以只使用useForm。如果表单跨越多个组件,则可以使用useFormContext将其分割成多个组件,以改善源代码的可读性,并使其更加简洁和易于重复使用。
使用方法
通过在父组件中定义useForm并用FormProvider包裹子组件,使得子组件可以使用方法等。在子组件中,通过useFormContext获取状态和方法并进行使用。
示例代码
为了使内容具有实际意义,我使用了zod在typescript中进行类型定义和验证定义。
由于只有一个输入元素,所以它变得简单。
如果表单只有一个组件的情况下。
// 親の親コンポーネント(参考までに書きました)
import React from 'react'
import { SampleForm } from './SampleForm'
const App = () => {
return (
<div>
<SampleForm />
</div>
)
}
export default App
// 親コンポーネントのみ
import * as react from "react";
import { useForm, SubmitHandler } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from 'zod'
const userSchema = z.object({
name: z.string().min(1, '名前を入力してください')
})
type UserData = z.infer<typeof userSchema>
export const SampleForm:React.FC = () => {
const { register, handleSubmit, formState: { errors } } = useForm<UserData>({
resolver: zodResolver(userSchema)
})
const onSubmit: SubmitHandler<UserData> = data => {console.log(data)}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="name">なまえ</label>
<input id="name" {...register('name')} />
<p>{errors.name?.message}</p>
</div>
<button type="submit">送信</button>
</form>
)
}
由于其简单的形式,只需要使用”useForm”。
当表单跨越多个组件时
// 親コンポーネント
import * as react from "react";
import {useForm, SubmitHandler, FormProvider} from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from 'zod'
import NameInput from "./NameInput";
const userSchema = z.object({
name: z.string().min(1, '名前を入力してください')
})
export type UserData = z.infer<typeof userSchema>
export const SampleForm:React.FC = () => {
const methods = useForm<UserData>({
resolver: zodResolver(userSchema)
})
const onSubmit: SubmitHandler<UserData> = data => {console.log(data)}
return (
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(onSubmit)}>
<NameInput />
<button type="submit">送信</button>
</form>
</FormProvider>
)
}
// 子コンポーネント
import * as react from "react";
import { useFormContext } from "react-hook-form";
import { UserData } from "./SampleForm"
import React from "react";
const NameInput: React.FC = () => {
const { register, formState: { errors } } = useFormContext<UserData>()
return (
<div>
<label htmlFor="name">なまえ</label>
<input id="name" {...register('name')} />
<p>{errors.name?.message}</p>
</div>
)
}
export default NameInput
透過FormProvider,將useForm方法傳遞給子組件(NameInput),以便子組件也能使用。
雖然此次簡單一些,但是在創建大量表單的情況下,建議使用useFormContext。
为那些想要调控手边物品的人提供的命令备忘录
npx create-react-app sample-react-hook-form --template typescript
cd sample-react-hook-form
npm install react-hook-form zod @hookform/resolvers
npm start
我的解释可能太过简洁,也许代码的含义不太容易理解,但我在本篇文章的标题范围内进行了解释。
适合想要更深入学习的人们的参考文献
useContext -React 在React中使用Context
在 `useFormContext` 中似乎使用了 `useContext`。
提供者模式
最终
感谢您一直以来的关注。
欢迎留言分享关于削弱攻击力的评论。
如果喜欢的话,请给个赞、收藏和分享。
传递给下一个人
明天是@g-ss先生的文章,拜托了。