嵌套redux表单字段以进行分组验证

时间:2018-03-13 16:58:00

标签: redux-form

以下是否认为是对redux-form字段的有效使用?

const ValidatedFieldGroup = (props) => {

    const { meta: {touched, error} } = props

    return( 
           <div className={touched && error ? 'has-error' : ''}>
              <Field name="one" .... />
              <Field name="two" .... />
           </div>
    )
}

const MyMainComponent = (props) => {

    return <Field name="twofields" component={ValidatedFieldGroup} validate={myValidator} .... />
}

const myValidator = (value, allValues) => {

    return (allValues.one === "pretend-this-is-valid" && allValues.two === "pretend-this-is-valid") ? undefined : 'One of the fields is invalid - sort it out!'

}

“无值”父级字段仅用于挂钩到同步字段级别验证管道。然后可以使用此组件的道具来改变其子项的UI /状态(其中包含一些实现实际表单值的RF字段)

真实世界的例子=假设有一组五个复选框......如果其中至少有两个没有被选中,那么它们应该全部被包裹在一个'红色边框'中。

到目前为止似乎工作,但我意识到可能有一种更简单/更好/更正确的方法来实现相同的结果,或者我实际上可能为未来的麻烦做好准备!!

提前致谢。

扎克。

1 个答案:

答案 0 :(得分:1)

虽然这种变通方法可以产生所需的用户界面(即一个div具有正确的class),但您最终会在redux-form商店中找到三个字段, onetwotwofields似乎不受欢迎。据推测,您永远不会对后端的twofields字段做任何事情,因为它仅用于演示。这违背了redux-form商店应该映射到后端字段(DB或其他......)的想法。

您可以使用Fields组件,这样您只需注册onetwo字段,这些字段更加一致:

import { Fields, ...} from "redux-form";

const renderValidatedFields = fields => {
    const { one, two } = fields;
    const showError = (one.meta.touched && one.meta.error) || (two.meta.touched && two.meta.error);
    return ( 
       <div className={showError ? 'has-error' : ''}>
          <input {...one.input} type="checkbox" />
          <input {...two.input} type="checkbox" />
       </div>
    )
}        

export default MyMainFieldComponent = props => {
    return <Fields names={["one", "two"]} component={renderValidatedFields} />
}

然后将验证码放在配置中的redux-form

import React from "react";
import { reduxForm } from "redux-form";

import MyMainFieldComponent from "./MyMainFieldComponent";

// validate the whole form
const myValidator = values => {
    const msg = "Invalid selection.";
    const errors = {};

    if (!values.one) {
        errors.one = msg;
    }

    if (!values.two) {
        errors.two = msg;
    }

    return errors;
}

...

let MyForm = props => {
    ...
    return (
        <form ...>
            <MyMainFieldComponent />
        </form>
    )
}

MyForm = reduxForm({
    ...,
    validate: myValidator
})(MyForm);

export default MyForm;