微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Redux-Form 字段和表单级同步验证

如何解决Redux-Form 字段和表单级同步验证

我正在使用 Redux-Form 8.3.6 并且有一个表单,每个字段都带有同步字段级验证表单级同步验证来测试字段之间的关系。我没有得到我期望的结果,也找不到这是一个 redux 形式的问题还是我对它的工作原理的理解上的一个漏洞。

一个简单的(ish)示例来演示。这实现了三个字段,每个字段都可能包含 0 到 100 之间的数值。必须填写这些字段中的一个或多个字段才能提交表单。

可以选择挂载或卸载表单,并且将 destroyOnUnmount 设置为 false 以保留挂载之间的值。

import React,{ useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Field,reduxForm,getFormSyncErrors } from 'redux-form';


const formName = 'SimpleForm';

// validators
const isNumeric = value => (value === undefined || /^[-+]?([0-9]\d*)$|^$/.test(value) ? undefined : 'must be numeric');
const inRange = value => (value === undefined || (value >= 0 && value <= 100) ? undefined : 'must be in range 0-100');
const validate = values => {
    if ((values.field1 && values.field1.length) ||
        (values.field2 && values.field2.length) ||
        (values.field3 && values.field3.length)) {
        return ({});
    } else {
        return ({ error: 'At least one field must me filled' });
    }
};

// Submit handler
const logValues = values => {
    console.log(values);
};

// render the individual fields
const renderField = ({
    input,label,type,Meta: { touched,error,warning },}) => (
    <div>
        {label}
        <div>
            <input {...input} placeholder={label} type={type} />
            {touched &&
                ((error && <span>{error}</span>) ||
                    (warning && <span>{warning}</span>))}
        </div>
    </div>
);

// Define the form
const TestForm = reduxForm({
    form: formName,destroyOnUnmount: false,validate,})(({ handleSubmit }) =>
    <form onSubmit={handleSubmit}>
        <Field
            name="field1"
            component={renderField}
            type="text"
            label="Field One"
            validate={[isNumeric,inRange]}
        />
        <Field
            name="field2"
            component={renderField}
            type="text"
            label="Field Two"
            validate={[isNumeric,inRange]}
        />
        <Field
            name="field3"
            component={renderField}
            type="text"
            label="Field Three"
            validate={[isNumeric,inRange]}
        />
        <button type="submit">
            Submit
        </button>
    </form>,);

// Define the Page
const TestPage = ({ formErrors }) => {
    const [show,setShow] = useState(false);

    return (
        <div>
            <button
                type="button"
                onClick={() => setShow(!show)}
            >
                {show ? 'Hide Form' : 'Show Form'}
            </button>
            {show && formErrors && <div>{formErrors.error}</div>}
            {show && <TestForm onSubmit={logValues} />}
        </div>
    );
};

TestPage.propTypes = {
    formErrors: PropTypes.object,};

TestPage.defaultProps = {
    formErrors: {},};

const getFormErrors = getFormSyncErrors(formName);

const mapStatetoProps = state => ({
    formErrors: getFormErrors(state),});

export default connect(mapStatetoProps)(TestPage);

这一切都按预期工作除了表单的每个备用安装字段级别验证都被删除,然后表单可以提交错误数据。

这可能与这样一个事实有关,即在挂载时 redux-form 将在调度 UPDATE_SYNC_ERRORS 之前调度 REGISTER_FIELD,而在下一次挂载时将在 REGISTER_FIELD 之前调度 UPDATE_SYNC_ERRORS。

有没有什么方法可以实现我想要的,而无需在表单验证函数中对每个字段进行验证?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。