如何使用自定义组件创建动态表单?
How to create a dynamic form with custom components?
我使用的是版本 7 的库,但我在两种情况下遇到问题:
我需要动态渲染控制器,因为表单是用后端响应的数据组装的;
我正在尝试为控制器创建一个特定的组件并在表单中重用它;
我正在尝试这样做,但它可能是错误的:
控制器组件
import { Control, Controller, FieldValues } from 'react-hook-form';
import Select from '../../core/Select';
interface IProps {
name: string;
tabIndex: string;
// eslint-disable-next-line @typescript-eslint/ban-types
control: Control<FieldValues, object>;
isDisabled: boolean;
placeholder: string;
options: [
{
label: string;
value: string;
}
];
}
const SelectControllerForm = ({ name, control, ...props }: IProps) => (
<Controller
name={name}
control={control}
render={({ field, fieldState: { error } }) => (
<Select required={true} isClearable={true} error={!!error} {...field} {...props} />
)}
/>
);
FormComponent
const { register, control } = useForm({
resolver: yupResolver(schema),
});
const { fields, append, prepend, remove, swap, move, insert } = useFieldArray({
control, // control props comes from useForm (optional: if you are using FormContext)
name: 'test', // unique name for your Field Array
keyName: 'key', //default to "id", you can change the key name
});
const onSubmit = (data: any) => {
console.log('AQUI');
console.log(data);
};
useEffect(() => {
append({ firstName: 'bill', lastName: 'luo' });
append({ a: 'oi', b: 'aq' });
}, []);
return (
<form onSubmit={}>
{fields.map((field, index) => (
<SelectControllerForm
key={field.key}
name={index.toString()}
control={control}
tabIndex='-1'
isDisabled={false}
placeholder='ae'
options={[
{
label: 'string',
value: 'string',
},
]}
/>
))}
</form>
)
它一直在更新屏幕并出现 REF 错误:
您的代码有几个问题:
1- 你不能一个接一个地调用动作。每次渲染都需要触发操作,因此您需要像这样更改 apped
:
useEffect(() => {
append([
{ value: 'a', label: 'a' },
{ value: 'b', label: 'b' },
]);
}, []);
2- react-hook-form
不支持平面字段数组,所以需要将字段名称设置为arrayField的嵌套字段,如下所示:
{fields.map((field, index) => (
<SelectControllerForm
key={field.key}
name={`test.${index.toString()}`}
control={control}
...
/>
))}
我希望这些更改能解决您的问题,如果没有帮助,最好将您的代码包含在 Code sandbox
示例中并 link 放在此处。
我使用的是版本 7 的库,但我在两种情况下遇到问题:
我需要动态渲染控制器,因为表单是用后端响应的数据组装的;
我正在尝试为控制器创建一个特定的组件并在表单中重用它;
我正在尝试这样做,但它可能是错误的:
控制器组件
import { Control, Controller, FieldValues } from 'react-hook-form';
import Select from '../../core/Select';
interface IProps {
name: string;
tabIndex: string;
// eslint-disable-next-line @typescript-eslint/ban-types
control: Control<FieldValues, object>;
isDisabled: boolean;
placeholder: string;
options: [
{
label: string;
value: string;
}
];
}
const SelectControllerForm = ({ name, control, ...props }: IProps) => (
<Controller
name={name}
control={control}
render={({ field, fieldState: { error } }) => (
<Select required={true} isClearable={true} error={!!error} {...field} {...props} />
)}
/>
);
FormComponent
const { register, control } = useForm({
resolver: yupResolver(schema),
});
const { fields, append, prepend, remove, swap, move, insert } = useFieldArray({
control, // control props comes from useForm (optional: if you are using FormContext)
name: 'test', // unique name for your Field Array
keyName: 'key', //default to "id", you can change the key name
});
const onSubmit = (data: any) => {
console.log('AQUI');
console.log(data);
};
useEffect(() => {
append({ firstName: 'bill', lastName: 'luo' });
append({ a: 'oi', b: 'aq' });
}, []);
return (
<form onSubmit={}>
{fields.map((field, index) => (
<SelectControllerForm
key={field.key}
name={index.toString()}
control={control}
tabIndex='-1'
isDisabled={false}
placeholder='ae'
options={[
{
label: 'string',
value: 'string',
},
]}
/>
))}
</form>
)
它一直在更新屏幕并出现 REF 错误:
您的代码有几个问题:
1- 你不能一个接一个地调用动作。每次渲染都需要触发操作,因此您需要像这样更改 apped
:
useEffect(() => {
append([
{ value: 'a', label: 'a' },
{ value: 'b', label: 'b' },
]);
}, []);
2- react-hook-form
不支持平面字段数组,所以需要将字段名称设置为arrayField的嵌套字段,如下所示:
{fields.map((field, index) => (
<SelectControllerForm
key={field.key}
name={`test.${index.toString()}`}
control={control}
...
/>
))}
我希望这些更改能解决您的问题,如果没有帮助,最好将您的代码包含在 Code sandbox
示例中并 link 放在此处。