使用具有相同表单名称的多个组件时,Redux 表单验证会中断

Redux-form validation breaks when using multiple components with the same form name

我 运行 使用多个装饰有相同表单名称的组件进入验证问题。

假设我们有 SimpleForm1SimpleForm2。当使用 name 字段渲染 Only SimpleForm1 时,验证会按预期工作,当使用 surname 字段渲染 SimpleForm2 时也是如此。但是当在单个页面上呈现它们时,SimpleForm1 的验证被破坏了。

问题是如何避免这种行为并使两个验证函数都起作用。

Here is a fiddle which illustrates my problem

对多个表单使用相同的名称不是一个好主意。 据我了解,您需要动态添加表单输入(在您的示例中为 SimpleForm2),并且有可能通过一个按钮提交两个表单。 如果是,那么你可以只向第一个表单添加一个输入,你不需要第二个表单。

表格:

const SimpleFormComponent1 = props => {
    const {handleSubmit, pristine, reset, submitting, renderBoth} = props;
    const onSubmit = (values) => {
        alert(JSON.stringify(values));
    };

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            ...
            {
                renderBoth &&
                <Field
                    name="surname"
                    type="text"
                    component={renderField}
                    label="Surname"
                    validate={validateSurname}
                />
            }
            ...
        </form>
    )
};

渲染函数:

render() {
        const {renderBoth} = this.state;

        return (
            <div>
                <div className='forms'>
                    <SimpleForm renderBoth={renderBoth}/>
                </div>
                <button
                    type='button'
                    onClick={this.handleClick}>
                    {renderBoth ? 'Show Single' : 'Show Both'}
                </button>
            </div>
        );
    }

Updated example

解决方案 1

我干扰了 Redux 表单的 invalidvalid 道具,因为我在主表单组件的每个文件中都在 ReduxForm() 上编写了 validate 函数.

您不必更改表单名称即可解决此问题。您必须将验证功能放在父组件上。


这是一个例子:

[语境]

我有 3 个组件: 1.主要组件放置表单('editUserForm')元素(, , ...) 2. 更改用户全名的表单('editUserForm')的Field1。 3. 更改用户邮箱的表单('editUserForm')的Field2。

[解决方案]

主要成分: 在主框架内,您调用 reduxForm()(它创建一个装饰器,您可以使用 redux-form 将您的表单组件连接到 Redux。更多信息在这里 Redux Form docs)。您的代码将是这样的:

import...

class MainFrame ... {
   ...
   <form ...>
         <Field1 />
         <Field2 />
   </form>
   ...
}

const validate ({ name, email }, props) => {
    errors={}

    // Validation around Field1
    if (name === ...) errors.name = "Name error passed to Field1 component";

    // Validation around Field2
    if (email === ...) errors.email= "Email error passed to Field2 component";

    return errors;
}
...
export default reduxForm({
    form: 'editUserForm',
    validate // <--------- IMPORTANT: Only put this function on the parent component.
})(MainComponent);

FIELD1 和 FIELD2 组件: 此代码用于 2 个子组件。重要提示:您调用 reduxForm() 时没有 validate Redux Form docs 同步函数。

import...

class MainFrame ... {
   ...
   const { invalid } = this.props;
   ...
   <inputs
       error={invalid}
   >
         ...
   </input>
   ...
}

// IMPORTANT: Don't put the validation function in Field1 and Field2 components, because their local validations will interfere with the validation of the other Field component.
reduxForm({
    form: 'editUserForm'
})

现在,道具:validinvalid 将在子组件(Field1Field2)中完美运行。


解决方案 2

用户 Redux 表单 FormSection (docs) 将表单拆分为更小的组件,这些组件可在多个表单中重复使用。