首页 > 解决方案 > react-hook-form v6 中父组件如何订阅子组件的“formState.isDirty”?

问题描述

我的用户案例是,如果最终用户想要离开特定屏幕,并且该屏幕中有未保存的更改,那么应用程序会警告用户。

现在我的子组件(这个用于检查脏的特定屏幕)是一个建立在 react-hook-form v6 之上的表单,它提供了“formState.isDirty”。我的父组件位于“react-router”之上以路由到适当的屏幕

我尝试过的一件事是,在我的父组件中,利用 useState 钩子并将回调传递给子组件:

const [userDirty, setDirty] = useState(undefined)

然后在我的子组件中,我有这个:

const methods = useForm() 
useEffect(() => {
    setDirty(methods.formState.isDirty)
}, )

它仅在最终用户与子表单交互导致重新渲染时才有效。但是有时最终用户对表单进行了更改并且没有重新渲染,那么上面的代码将不起作用,因为“useEffect”仅在每次重新渲染时运行。这是一个不起作用的示例——最终用户编辑文本输入:

<Form.Control  type="text"  name="customDisplayName"
                        defaultValue={xxx}
                        ref={register}  
>

我知道一种方法是为我的子组件中的每个输入添加一个“onChange”处理程序,然后在那里“setDirty”。但它是一个复杂的表单,有很多子输入。

    <Form.Control  type="text"  name="customDisplayName"
                        defaultValue={xxx}
                        ref={register}  
                         onChange={()=>{
                          setDirty(true)
                        }}
>

有没有一种简单的方法可以做到这一点?

标签: reactjsreact-hooksreact-hook-form

解决方案


我找到了答案。API 文档有这个:(https://react-hook-form.com/v6/api/#formState

如果您想在 useEffect 订阅 formState 更新,请确保将整个 formState 放在可选数组中。

因此,一旦我将“useEffect”调整到下面,它就会按预期工作

useEffect(() => {
    seteDirty(methods.formState.isDirty)
}, [methods.formState])

推荐阅读