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先生的文章,拜托了。

广告
将在 10 秒后关闭
bannerAds