有没有办法使用带有 useFieldArray 钩子的反应钩子形式在子组件中设置默认值 - 不使用 useForm 钩子?
Is there a way to set defaultValues in a child component using react hook form with useFieldArray hook - not using the useForm hook?
问题
我想在用户可以添加的表单中实现 key/value 对输入字段。
- 参见 animated gif on dynamic fields。
另外,我想在用户提交表单并再次显示页面时显示保存的数据。
- 见animated gif on displaying saved dynamic fields。
先决条件
- 我正在使用
react-hook-form V7
(RHF) 及其 useFieldArray
挂钩。
- 因为我使用 Material-UI 我必须使用
controlled components
.
工作解决方案
在一个简化的应用程序中,我有一个使用 useForm
挂钩的父组件和两个子组件,一个用于演示保存普通表单字段的目的,另一个 <ArrayFields />
组件保存数组字段.
昨天我从 那里了解到,一种方法是在父级的 useForm 挂钩中设置 defaultValues
对象,如下所示:
const methods = useForm({
defaultValues: {
email: "john.smith@example.com",
firstName: "John",
lastName: "Smith",
systemRole: "Admin",
envRoles: [ // <-- saved dynamic fields
{ envName: "foo1", envRole: "bar1" },
{ envName: "foo2", envRole: "bar2" }
]
}
});
这里可以看到一个codesandbox of this working solution.
问题
尽管如此,我想知道是否可以在 <ArrayFields />
子组件中设置 defaultValues
?
使用FormContext方法
例如像这样使用 useFormContext
钩子:
//
const ArrayFields = ({ fieldset }) => {
const { control, getValues } = useFormContext({
defaultValues: {
envRoles: [
{ envName: "foo1", envRole: "bar1" },
{ envName: "foo2", envRole: "bar2" }
]
}
});
const { fields, append, remove } = useFieldArray({
control,
name: "envRoles"
});
...
}
- 但这根本不显示保存的字段
- 看这里a codesandbox version of the useFormContext approach
道具接近
接下来,我尝试将字段(别名 envRoles
)作为 props 传递,并将 defaultValues
直接设置到 Controller
// index.js:30
<ArrayFields
fieldset={[
{ envName: "foo1", envRole: "bar1" },
{ envName: "foo2", envRole: "bar2" }
]}
/>
// ArrayFields.js:35
<Controller
render={({ field }) => <input {...field} />}
defaultValue={item.envName} {/* <-- defaultValue on Controller */}
name={`envRoles[${index}].envName`}
control={control}
/>
- 这显示
defaultValues
- 但单击添加或删除按钮时不起作用
- 见this codesandbox of the props approach
再提问
那么 RHF 是否真的不允许在该组件内部处理所有对组件重要的事情?
提前感谢您的提示。
我想我找到了答案。
In the documentation of useFieldArray
你会找到 replace
方法。
replace (obj: object[]) => void Replace the entire field array values.
所以使用 useEffect
钩子终于很容易了。
useEffect(() => {
replace(fieldset);
}, [fieldset, replace]);
在 this codesandbox 中,您将找到最终在子组件中设置默认值的示例。
问题
我想在用户可以添加的表单中实现 key/value 对输入字段。
- 参见 animated gif on dynamic fields。
另外,我想在用户提交表单并再次显示页面时显示保存的数据。
- 见animated gif on displaying saved dynamic fields。
先决条件
- 我正在使用
react-hook-form V7
(RHF) 及其useFieldArray
挂钩。 - 因为我使用 Material-UI 我必须使用
controlled components
.
工作解决方案
在一个简化的应用程序中,我有一个使用 useForm
挂钩的父组件和两个子组件,一个用于演示保存普通表单字段的目的,另一个 <ArrayFields />
组件保存数组字段.
昨天我从 defaultValues
对象,如下所示:
const methods = useForm({
defaultValues: {
email: "john.smith@example.com",
firstName: "John",
lastName: "Smith",
systemRole: "Admin",
envRoles: [ // <-- saved dynamic fields
{ envName: "foo1", envRole: "bar1" },
{ envName: "foo2", envRole: "bar2" }
]
}
});
这里可以看到一个codesandbox of this working solution.
问题
尽管如此,我想知道是否可以在 <ArrayFields />
子组件中设置 defaultValues
?
使用FormContext方法
例如像这样使用 useFormContext
钩子:
//
const ArrayFields = ({ fieldset }) => {
const { control, getValues } = useFormContext({
defaultValues: {
envRoles: [
{ envName: "foo1", envRole: "bar1" },
{ envName: "foo2", envRole: "bar2" }
]
}
});
const { fields, append, remove } = useFieldArray({
control,
name: "envRoles"
});
...
}
- 但这根本不显示保存的字段
- 看这里a codesandbox version of the useFormContext approach
道具接近
接下来,我尝试将字段(别名 envRoles
)作为 props 传递,并将 defaultValues
直接设置到 Controller
// index.js:30
<ArrayFields
fieldset={[
{ envName: "foo1", envRole: "bar1" },
{ envName: "foo2", envRole: "bar2" }
]}
/>
// ArrayFields.js:35
<Controller
render={({ field }) => <input {...field} />}
defaultValue={item.envName} {/* <-- defaultValue on Controller */}
name={`envRoles[${index}].envName`}
control={control}
/>
- 这显示
defaultValues
- 但单击添加或删除按钮时不起作用
- 见this codesandbox of the props approach
再提问
那么 RHF 是否真的不允许在该组件内部处理所有对组件重要的事情?
提前感谢您的提示。
我想我找到了答案。
In the documentation of useFieldArray
你会找到 replace
方法。
replace (obj: object[]) => void Replace the entire field array values.
所以使用 useEffect
钩子终于很容易了。
useEffect(() => {
replace(fieldset);
}, [fieldset, replace]);
在 this codesandbox 中,您将找到最终在子组件中设置默认值的示例。