如何使用自定义组件创建动态表单?

How to create a dynamic form with custom components?

我使用的是版本 7 的库,但我在两种情况下遇到问题:

  1. 我需要动态渲染控制器,因为表单是用后端响应的数据组装的;

  2. 我正在尝试为控制器创建一个特定的组件并在表单中重用它;

我正在尝试这样做,但它可能是错误的:

控制器组件

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 放在此处。