[英]react-hook-form FormProvider performance with controlled components (or, how to memoize controlled components)
我正在使用FormProvider
来处理动态创建的“深度嵌套”表单。 FormProvider 性能文档说,“...[FormProvider] 还会导致组件树在 React Hook Form 触发 state 更新时触发重新渲染”,并建议记忆组件来解决这个问题。 我正在使用受控组件 (MUI),但不知道如何进行记忆。 这是返回表单输入控件的深层嵌套部分:
const FormContent = ( {content} ) => {
return content.map((item, i) => {
const name = item.component.props.name;
return (
<ConnectForm key={name + '_' + i}>
{() => <Controller
name={name}
defaultValue=''
render={({ field: { onChange, onBlur, value, name, ref },
fieldState: { error },
formState: { isDirty } }) => {
return React.cloneElement(item.component, {
name: name,
value: value,
onChange: onChange,
inputRef: ref,
error: isDirty && !!error,
helperText: isDirty && error?.message,
FormHelperTextProps: { error: true }
})
}
}
/>}
</ConnectForm>
);
});
}
我试着做
render={
memo(({ field: { onChange, onBlur, value, name, ref },
return React.cloneElement(item.component, {
...
})
},
(prevProps, nextProps) =>
prevProps.formState.isDirty === nextProps.formState.isDirty)
}
但Controller
会引发 TypeDef 错误,即“props.render 不是函数”。 如果我做
{() => memo(<Controller
...
/>,
(prevProps, nextProps) =>
prevProps.formState.isDirty === nextProps.formState.isDirty
)}
或者
memo(<ConnectForm key={name + '_' + i}>
{() => <Controller
...
/>}
</ConnectForm>,
(prevProps, nextProps) =>
prevProps.formState.isDirty === nextProps.formState.isDirty
)
它警告memo
“第一个参数必须是一个组件。而不是接收:对象”,并且ConnectForm
(或第二个实例中的FormContent
)抛出一个错误,“对象作为 React 子项无效”。
我如何使用受控组件实现这种“性能增强”?
嘿,不确定您是否仍然遇到此问题,但我已经构建了一个新的表单库,它没有任何这些问题。 您可以拥有嵌套组件而无需执行任何特殊操作。
它处于测试阶段,目前正在开发中,但它可能会解决您遇到的问题。
如果您愿意,可以在这里查看: https://react-formz.zerry.dev/docs/intro/
import {
Form,
TextField,
NumberField,
DependentTextField,
} from "@zerry/react-formz";
const NestedInput = () => {
return (
<TextField
required
name="name"
as={({ input }) => <input {...input} />}
/>
)
}
const MyForm = () => {
return (
<Form initialValues={{ name: "", age: "" }}>
<NestedInput />
<NumberField
required
name="age"
as={({ input }) => <input {...input} />}
/>
</Form>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.