Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Redux表单验证在onChange处理程序函数之后运行_Javascript_Redux_Redux Form - Fatal编程技术网

Javascript Redux表单验证在onChange处理程序函数之后运行

Javascript Redux表单验证在onChange处理程序函数之后运行,javascript,redux,redux-form,Javascript,Redux,Redux Form,我有以下redux表单: import React, { Component } from 'react'; import { connect } from 'react-redux'; import { Field, reduxForm, getFormSyncErrors } from 'redux-form'; import { createExpense } from '../../actions'; import { validateName, validateImage } fro

我有以下redux表单:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Field, reduxForm, getFormSyncErrors } from 'redux-form';

import { createExpense } from '../../actions';
import { validateName, validateImage } from '../../helpers/expense_utils';
import { renderInputField, validate, renderTextAreaField, renderDropzoneField } from '../../helpers/form_utils';

const validators = [
  {
    field: 'title',
    validator: validateName
  },
  {
    field: 'description',
    validator: validateDescription
  },
  {
    field: 'amount',
    validator: validateAmount
  },
  {
    field: 'image',
    validator: validateImage
  }
];

class NewExpense extends Component {

  constructor(props) {
    super(props);
    this.state = {
      error: undefined,
      imagePreviewUrl: undefined
    };
  }

  _onSubmit = values => {
    let formData = new FormData();
    formData.append('title', values.title);
    formData.append('description', values.description);
    formData.append('amount', values.amount);
    formData.append('file', values.image[0]);
    this.props.createExpense(formData, this.props.groupId, () => this.props.onClose(), error => this.setState({error: error}));
  }

  _onImagePreviewChange = files => {
    //this.props.inputErrors.image is one step behind 
    this.setState({
      imagePreviewUrl: files[0].preview
    });
  }

  render() {
    const { handleSubmit } = this.props;
    const { imagePreviewUrl } = this.state;
    return (
      <div>
        <form onSubmit={ handleSubmit(this._onSubmit.bind(this)) }>
          <Field name="title" label="Name" type="text" component={ renderInputField }/>
          <Field onChange={this._onImagePreviewChange.bind(this)} previewUrl={ imagePreviewUrl } name="image" label="Image" component={ renderDropzoneField } />
          <button type="submit" className="btn btn-primary">Create</button>
          <button type="button" className="btn btn-primary" onClick={this.props.onClose}>Cancel</button>
        </form>
        { this.state.error ? <span>{this.state.error}</span> : <noscript/> }
      </div>
    );
  }
}

export default connect(state => ({
  inputErrors: getFormSyncErrors('NewExpense')(state)
}), { createExpense })(reduxForm({
  validate,
  form:'NewExpense',
  validators
})(NewExpense));
import React,{Component}来自'React';
从'react redux'导入{connect};
从'redux form'导入{Field,reduxForm,getFormSyncErrors};
从“../../actions”导入{createExpense};
从“../../helpers/expense_utils”导入{validateName,validateImage};
从“../../helpers/form_utils”导入{renderInputField,validate,renderTextAreaField,renderDropzoneField};
常量验证器=[
{
字段:“标题”,
验证程序:validateName
},
{
字段:“说明”,
验证器:validateDescription
},
{
字段:“金额”,
验证器:validateAmount
},
{
字段:“图像”,
验证器:validateImage
}
];
类NewExpense扩展组件{
建造师(道具){
超级(道具);
此.state={
错误:未定义,
imagePreviewUrl:未定义
};
}
_onSubmit=值=>{
设formData=new formData();
formData.append('title',values.title);
formData.append('description',values.description);
formData.append('amount',value.amount);
formData.append('file',values.image[0]);
this.props.createExpense(formData,this.props.groupId,()=>this.props.onClose(),error=>this.setState({error:error}));
}
_onImagePreviewChange=文件=>{
//此.props.inputErrors.image落后一步
这是我的国家({
imagePreviewUrl:文件[0]。预览
});
}
render(){
const{handleSubmit}=this.props;
const{imagePreviewUrl}=this.state;
返回(
创造
取消
{this.state.error?{this.state.error}:}
);
}
}
导出默认连接(状态=>({
输入者:getFormSyncErrors('NewExpense')(状态)
}),{createExpense})(reduxForm({
验证
表格:'NewExpense',
验证器
})(新费用);
我想访问
\u onImagePreviewChange
中表单的字段级错误,并在
MapStateTops
中设置
输入错误

问题是验证函数在
onChange
handler函数之后运行。因此,错误消息总是过时的。例如,如果用户选择了一个不允许类型的文件,消息将是
未定义的
,下一次如果用户选择了允许类型的文件,这一次它将不会是
未定义的
,因为在上一步中分配了一个错误


为什么会发生这种情况?我应该如何修复它?

验证只能在某些字段更改后运行,这就是为什么第一次使用无效值调用
\u onImagePreviewChange
时,仍然没有验证错误(如您所说,验证落后一步)

我建议使用
componentWillReceiveProps
方法,在此方法中访问下一个和当前的验证错误,检查是否修复或生成了某些错误,并采取需要采取的措施。例如:

 componentWillReceiveProps(newProps) {
    // here newProps.inputErrors is up-to-date while this.props.inputErrors is the current
    if (newProps.inputErrors && newProps.inputErrors !== this.props.inputErrors) {
      console.log(newProps.inputErrors); // up-to-date input errors
      if (newProps.inputErrors.image) {
        // clear invalid image field if you need to
        this.props.change('image', '');
      }
    }
  }

您应该使用
this.props.change
而不是
this.setState({preview:undefined})
,对吗?是的,这取决于您需要什么:
this.props.change
重置无效字段,
setState
只会隐藏预览,但会使字段无效。