Material UI 表单重置时切换输入未更新
Material UI switch inputs not updating on form reset
我正在使用 react-hook-form
来构建我的表单,这是一个很棒的工具。但是,我似乎无法根据 redux 的 return 值让 <Switch />
元素滑动(false/true)。 当我点击表单上的“重置”时,我所有的输入都会重置。我的 Switch 控件没有重置,它们仍然停留在它们的最后一个值上,不管它是否可能被重置。关于如何解决这个问题有什么想法吗?
我的开关
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
{...register('content.isFamilySafe')}
/>
}
label="Family Friendly"
/>
重置按钮
<button
type="button"
onClick={() => {
reset(formState, {
keepErrors: true,
keepDirty: true,
keepIsSubmitted: false,
keepTouched: false,
keepIsValid: false,
keepSubmitCount: false,
});
}}
>
reset
</button>
useForm挂钩
const formState = useSelector(selectDynamicForm);
const {
register,
control,
handleSubmit,
reset,
formState: { errors },
} = useForm<IFormInput>({});
我认为 react-hook-form
需要知道它“关注”的是复选框而不是文本输入。由于 <Switch />
是一个包装组件,ref 现在以 div 元素而不是 input 元素为目标。但是,有一个 inputRef
道具 material-ui 转发到输入元素。
const { ref, ...rest } = register('content.isFamilySafe');
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
inputRef={ref}
{...rest}
/>
}
label="Family Friendly"
/>
或者您可以围绕 <Switch />
个组件的注册函数创建一个包装器:
function registerSwitch(name) {
const { ref: inputRef, ...rest } = register(name);
return { inputRef, ...rest };
}
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
{...registerSwitch('content.isFamilySafe')}
/>
}
label="Family Friendly"
/>
第三种解决方案是使用辅助函数重写道具:
const fixSwitchProps = ({ ref: inputRef, ...rest }) => ({ inputRef, ...rest });
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
{...fixSwitchProps(registerSwitch('content.isFamilySafe'))}
/>
}
label="Family Friendly"
/>
MUI 的 <Switch />
组件使用 checked
而不是 value
的实际值界面略有不同。 RHF 的 register
returns 一个 value
属性 你散布在 <Switch />
组件上,所以 checked
永远不会在 RHF 和 [=11 之间链接=] 组件.
所以你应该使用RHF的<Controller />
组件来控制这个外控组件。查看 here 了解更多信息。
<FormControlLabel
control={
<Controller
control={control}
name="content.isFamilySafe"
render={({ field: { value, ...field } }) => (
<Switch {...field} checked={!!value} size="medium" />
)}
/>
}
label="Family Friendly"
/>
您还需要通过 useForm
为您的输入设置 defaultValue
,因为这是 reset
正常工作所必需的。来自 docs:
If your form will invoke reset
with default values, you will need to
call useForm with defaultValues
instead of setting the defaultValue
on
individual fields.
我正在使用 react-hook-form
来构建我的表单,这是一个很棒的工具。但是,我似乎无法根据 redux 的 return 值让 <Switch />
元素滑动(false/true)。 当我点击表单上的“重置”时,我所有的输入都会重置。我的 Switch 控件没有重置,它们仍然停留在它们的最后一个值上,不管它是否可能被重置。关于如何解决这个问题有什么想法吗?
我的开关
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
{...register('content.isFamilySafe')}
/>
}
label="Family Friendly"
/>
重置按钮
<button
type="button"
onClick={() => {
reset(formState, {
keepErrors: true,
keepDirty: true,
keepIsSubmitted: false,
keepTouched: false,
keepIsValid: false,
keepSubmitCount: false,
});
}}
>
reset
</button>
useForm挂钩
const formState = useSelector(selectDynamicForm);
const {
register,
control,
handleSubmit,
reset,
formState: { errors },
} = useForm<IFormInput>({});
我认为 react-hook-form
需要知道它“关注”的是复选框而不是文本输入。由于 <Switch />
是一个包装组件,ref 现在以 div 元素而不是 input 元素为目标。但是,有一个 inputRef
道具 material-ui 转发到输入元素。
const { ref, ...rest } = register('content.isFamilySafe');
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
inputRef={ref}
{...rest}
/>
}
label="Family Friendly"
/>
或者您可以围绕 <Switch />
个组件的注册函数创建一个包装器:
function registerSwitch(name) {
const { ref: inputRef, ...rest } = register(name);
return { inputRef, ...rest };
}
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
{...registerSwitch('content.isFamilySafe')}
/>
}
label="Family Friendly"
/>
第三种解决方案是使用辅助函数重写道具:
const fixSwitchProps = ({ ref: inputRef, ...rest }) => ({ inputRef, ...rest });
<FormControlLabel
control={
<Switch
size="medium"
name="familyFriendly"
defaultChecked={formState.content.isFamilySafe}
{...fixSwitchProps(registerSwitch('content.isFamilySafe'))}
/>
}
label="Family Friendly"
/>
MUI 的 <Switch />
组件使用 checked
而不是 value
的实际值界面略有不同。 RHF 的 register
returns 一个 value
属性 你散布在 <Switch />
组件上,所以 checked
永远不会在 RHF 和 [=11 之间链接=] 组件.
所以你应该使用RHF的<Controller />
组件来控制这个外控组件。查看 here 了解更多信息。
<FormControlLabel
control={
<Controller
control={control}
name="content.isFamilySafe"
render={({ field: { value, ...field } }) => (
<Switch {...field} checked={!!value} size="medium" />
)}
/>
}
label="Family Friendly"
/>
您还需要通过 useForm
为您的输入设置 defaultValue
,因为这是 reset
正常工作所必需的。来自 docs:
If your form will invoke
reset
with default values, you will need to call useForm withdefaultValues
instead of setting thedefaultValue
on individual fields.