React Form组件的实现封装杂谈(4)
默认的校验时机是字段值改变的时候,可以通过Field的validateOnChange和validateOnBlur来改变校验时机。
<Field
validateOnChange={false}
validateOnBlur={false}
validations={{
required: true,
matchRegex: /^[a-zA-Z]+$/
}}
validationErrors={{
required: '值不能为空',
matchRegex: '只能为字母'
}}
/>
对应的,在Field组件中有2个方法来处理change和blur事件:
class Field extends Component {
handleChange = (event, options = { merge: false }) => {
...
this.setValue(newValue, validateOnChange);
...
}
handleBlur = (event, options = { merge: false }) => {
...
this.setValue(newValue, validateOnBlur);
...
}
setValue = (value, needValidate = true) => {
this.setState(
{
_value: value,
_isDirty: true,
},
() => {
needValidate && this.context.zentForm.validate(this);
}
);
};
}
当触发验证的时候,ZentForm是会对表单对所有字段进行验证,可以通过指定relatedFields来告诉表单哪些字段需要同步进行验证。
表单提交
表单提交时,一般会经历如下几个步骤
- 表单验证
- 表单提交
- 提交成功处理
- 提交失败处理
ZentForm通过handleSubmit高阶函数定义了上述几个步骤,只需要传入表单提交的逻辑即可:
const handleSubmit = (submit, zentForm) => {
const doSubmit = () => {
...
result = submit(values, zentForm);
...
return result.then(
submitResult => {
...
if (onSubmitSuccess) {
handleOnSubmitSuccess(submitResult);
}
return submitResult;
},
submitError => {
...
const error = handleSubmitError(submitError);
if (error || onSubmitFail) {
return error;
}
throw submitError;
}
);
}
const afterValidation = () => {
if (!zentForm.isValid()) {
...
if (onSubmitFail) {
handleOnSubmitError(new SubmissionError(validationErrors));
}
} else {
return doSubmit();
}
};
const allIsValidated = zentForm.fields.every(field => {
return field.props.validateOnChange || field.props.validateOnBlur;
});
if (allIsValidated) {
// 不存在没有进行过同步校验的field
afterValidation();
} else {
zentForm.validateForm(true, afterValidation);
}
}
使用方式如下:
const { handleSubmit } = this.props;
<Form onSubmit={handleSubmit(this.submit)} horizontal>
ZentForm不足之处
