React Hook Form + MUI - 如何将观看的项目显示到另一个文本字段中
React Hook Form + MUI - How to display watched item into another textfield
使用 React hook Form V7,我试图从组件的文本字段中检索一个值,并将该值动态显示到另一个组件的文本字段中。
我试过观看它,它在文本字段之外工作得很好,但是一旦我插入值,我就会得到:"警告:组件正在将不受控制的输入更改为受控制"。 =25=]...
我已经尝试了所有我能想到的方法并在互联网上四处搜索,但找不到任何帮助...有没有办法实现这个目标?
到目前为止我的代码:
const watchCake = watch("cake");
<Controller
render={({ field: { onChange, onBlur, value, name, ref }, formState }) => (
<TextField
disabled
id="cakeName"
name="cakeName"
margin="dense"
variant="outlined"
onChange={onChange}
value={watch("cake")}
ref={register}
{...register("cakeName")}
/>
)}
control={control}
name="cakeName"
defaultValue=""
/>
<p>{watchCake}</p> //works perfect
@knoefel
我已将我的表单和输入拆分为多个组件以实现可重用性。该表单位于一个对话框中,该对话框将在需要时触发正确的组件部分。
所以我有一个带有文本字段的“ChildOne”组件。在运行中(不是在验证时)我需要将用户在那里输入的内容显示到“ChlidTwo”组件中的另一个文本字段中(这只是为了避免用户在 ChildTwo 中输入其他数据时造成混淆)
为了更好地理解,这里有一张图片:)
你的“蛋糕”TextField
的值发生变化后,你必须使用RHF提供的setValue
来更新“蛋糕名称”TextField
的值。
此外,如果您使用的是 Controller
,则不需要 register
,因为 Controller
负责注册您的外部组件。
<Controller
control={control}
name="cake"
defaultValue={""}
render={({ field: { onChange, value } }) => (
<TextField
label="Cake"
value={value}
onChange={({ target: { value } }) => {
setValue("cakeName", value);
onChange(value);
}}
/>
)}
/>
<Controller
control={control}
name="cakeName"
defaultValue={""}
render={({ field: { onChange, value } }) => (
<TextField label="Cake Name" value={value} onChange={onChange} />
)}
/>
更新
根据新要求,您最初使用 watch
的方法是正确的。您在这里有多个选项可以将当前输入值传递给您的子组件:
选项 1
将表单方法(useForm
挂钩的 return 值)传播到您的子组件并在那里使用 watch
。
选项 2
只需将 control
作为 prop 传递给您的子组件,并使用 useWatch
挂钩接收监视输入的当前值。使用 useWatch
执行此操作的行为与选项 1 类似。但是,这将在组件级别隔离重新渲染,并可能为您的应用程序带来更好的性能。如果您的子表单组件非常复杂并且有很多输入,我会走这条路。
选项 3
使用FormContext - 它解决了数据通过组件树传递的问题,而无需在每一层手动向下传递属性。当 React Hook Form 触发状态更新时,这也会导致组件树触发重新渲染,所以我会尽量避免它,因为它是所有选项中性能最差的,并且在您的用例中不是必需的。
使用 React hook Form V7,我试图从组件的文本字段中检索一个值,并将该值动态显示到另一个组件的文本字段中。 我试过观看它,它在文本字段之外工作得很好,但是一旦我插入值,我就会得到:"警告:组件正在将不受控制的输入更改为受控制"。 =25=]... 我已经尝试了所有我能想到的方法并在互联网上四处搜索,但找不到任何帮助...有没有办法实现这个目标?
到目前为止我的代码:
const watchCake = watch("cake");
<Controller
render={({ field: { onChange, onBlur, value, name, ref }, formState }) => (
<TextField
disabled
id="cakeName"
name="cakeName"
margin="dense"
variant="outlined"
onChange={onChange}
value={watch("cake")}
ref={register}
{...register("cakeName")}
/>
)}
control={control}
name="cakeName"
defaultValue=""
/>
<p>{watchCake}</p> //works perfect
@knoefel
我已将我的表单和输入拆分为多个组件以实现可重用性。该表单位于一个对话框中,该对话框将在需要时触发正确的组件部分。 所以我有一个带有文本字段的“ChildOne”组件。在运行中(不是在验证时)我需要将用户在那里输入的内容显示到“ChlidTwo”组件中的另一个文本字段中(这只是为了避免用户在 ChildTwo 中输入其他数据时造成混淆)
为了更好地理解,这里有一张图片:)
你的“蛋糕”TextField
的值发生变化后,你必须使用RHF提供的setValue
来更新“蛋糕名称”TextField
的值。
此外,如果您使用的是 Controller
,则不需要 register
,因为 Controller
负责注册您的外部组件。
<Controller
control={control}
name="cake"
defaultValue={""}
render={({ field: { onChange, value } }) => (
<TextField
label="Cake"
value={value}
onChange={({ target: { value } }) => {
setValue("cakeName", value);
onChange(value);
}}
/>
)}
/>
<Controller
control={control}
name="cakeName"
defaultValue={""}
render={({ field: { onChange, value } }) => (
<TextField label="Cake Name" value={value} onChange={onChange} />
)}
/>
更新
根据新要求,您最初使用 watch
的方法是正确的。您在这里有多个选项可以将当前输入值传递给您的子组件:
选项 1
将表单方法(useForm
挂钩的 return 值)传播到您的子组件并在那里使用 watch
。
选项 2
只需将 control
作为 prop 传递给您的子组件,并使用 useWatch
挂钩接收监视输入的当前值。使用 useWatch
执行此操作的行为与选项 1 类似。但是,这将在组件级别隔离重新渲染,并可能为您的应用程序带来更好的性能。如果您的子表单组件非常复杂并且有很多输入,我会走这条路。
选项 3
使用FormContext - 它解决了数据通过组件树传递的问题,而无需在每一层手动向下传递属性。当 React Hook Form 触发状态更新时,这也会导致组件树触发重新渲染,所以我会尽量避免它,因为它是所有选项中性能最差的,并且在您的用例中不是必需的。