我正在尝试根据每个字段上的验证器来集体验证Redux表单。是的,我知道我可以让Redux在表单级别执行此操作,但是我将此组件仅用作多部分,多步骤表单的一部分,因此我需要能够自行验证字段分组。我遇到的问题是,当我绑定更改或更新处理程序时,通过Redux字段验证的数据是陈旧的。看来我正在尝试在新状态传播到字段之前针对旧状态进行验证。如何通过某种处理程序,回调等对字段中的当前值进行验证? (我在其中留下了控制台语句,以说明出现滞后的地方。我对React和Redux还是很陌生,所以请保持友善。)
这是我的组件代码和字段/验证器代码:
AccountCreationCreateAccountStep.js:
-------------------------------------
import React from "react"
import PropTypes from "prop-types"
import { Field, reduxForm } from 'redux-form'
import { TextField } from '../helpers/reduxFieldRenderers'
import { requiredValidator, emailValidator, phoneValidator } from '../helpers/validators'
class AccountCreationCreateAccountStep extends React.Component {
constructor(props) {
super(props);
this.valid = this.valid.bind(this);
this.handleChange = this.handleChange.bind(this);
}
valid() {
return ["account_name", "account_contact_email", "account_phone_number", "account_address"].map((f) => this.refs[f].getRenderedComponent().props.meta.valid, this).reduce((a, b) => a && b, true);
}
handleChange() {
console.log("Changed " + this.valid());
}
componentDidUpdate() {
console.log("Update " + this.valid());
}
render () {
return (
<React.Fragment>
<div className="account-creation-wizard-form-container">
<h4>Create Account</h4>
<Field type="text" withRef ref="account_name" onChange={this.handleChange} id="account_name" label="Account Name" component={TextField} name="account[name]" className="form-control string" validate={requiredValidator}/>
<Field type="text" withRef ref="account_contact_email" onChange={this.handleChange} id="account_contact_email" label="Contact Email" component={TextField} name="account[contact_email]" className="form-control string" validate={[requiredValidator, emailValidator]}/>
<Field type="text" withRef ref="account_phone_number" onChange={this.handleChange} id="account_phone_number" label="Phone Number" component={TextField} name="account[phone_number]" className="form-control string" validate={[requiredValidator, phoneValidator]}/>
<Field type="text" withRef ref="account_address" onChange={this.handleChange} id="account_address" label="Address" component={TextField} name="account[address]" className="form-control string"/>
</div>
</React.Fragment>
);
}
}
export default AccountCreationCreateAccountStep
-----------------------
reduxFieldRenderers.js
-----------------------
import React from "react"
class TextField extends React.Component {
render() {
const { input, label, type, name, id, className, meta: { touched, error, warning } } = this.props;
return (
<div className="form-group string">
<label className="from-control-label" htmlFor={id}>{label}</label>
{ touched && ((error && <span className="field-error">{error}</span>) || (warning && <span className="field-error">{warning}</span>))}
<input {...input} type={type} name={name} id={id} className={className} />
</div>
)
}
}
export { TextField }
------------------------
validators.js
------------------------
const requiredValidator = value => value ? undefined : 'Required'
const maxLengthValidator = max => value =>
value && value.length > max ? `Must be ${max} characters or less` : undefined
const minLengthValidator = min => value =>
value && value.length < min ? `Must be as least ${min} characters` : undefined
const numericValidator = value => value && isNaN(Number(value)) ? 'Must be a number' : undefined
const minValueValidator = min => value =>
value && value < min ? `Must be at least ${min}` : undefined
const emailValidator = value =>
value && !/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/i.test(value) ?
'Invalid email address' : undefined
const phoneValidator = value =>
value && !/^(\+[0-9]{1,2})?((\([0-9]{3}\))|([0-9]{3}))[0-9]{3}-?[0-9]{4}$/i.test(value) ?
'Invalid phone number' : undefined
export { requiredValidator, maxLengthValidator, minLengthValidator, numericValidator, minValueValidator, emailValidator, phoneValidator };