React Dropzone + Redux表单验证不起作用

时间:2018-04-07 21:16:02

标签: javascript reactjs redux-form

我正在使用React Dropzone向Redux表单添加文件输入。调用验证函数并返回正确的错误,但我errortocuhed的值不会更改:

字段渲染方法:

export const renderDropzoneField = function({ input, name, id, meta: { touched, error } }) {
  return (
    <div>
      <Dropzone
        name={name}
        onDrop={filesToUpload => input.onChange(filesToUpload)}
      >
        Import image to upload
        {touched && error && <span>{error}</span>}
      </Dropzone>
    </div>
  );
}

验证方法:

export const validateImage = imageList => {
  if (imageList) {
    if (imageList.length > 1) {
      return "You can upload one image at a time";
    } else if (imageList.length === 1) {
      let selectedImage = imageList[0];
      if (!selectedImage.type.match('image.*')) {
        return "Only image files are allowed";
      } else if (selectedImage.size > 1048576) {
        return "Maximum file size exceeded";
      }
    }
  }
};

渲染方法:

render() {
  const { handleSubmit } = this.props;
  return (
    <div>
      <form onSubmit={handleSubmit(this._onSubmit.bind(this))}>
        <Field name="title" label="Name" type="text" component={renderInputField}/>
        <Field name="description" label="Description" type="text" component={renderTextAreaField}/>
        <Field name="amount" label="Amount" type="text" component={renderInputField}/>
        <Field name="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>
  );
}

当我加载'pdf'文件(导致错误消息)时,touched值仍为false,而errorundefiend

更新1

验证在表单级别完成:

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
    };
  }

  _onSubmit = values => {
    let reader = new FileReader();
    reader.onloadend = e => {
      var imageValue = reader.result;
      this.props.createExpense(values, imageValue, this.props.groupId, () => this.props.onClose(), error => this.setState({error: error}));
    };
    reader.readAsDataURL(values.image[0]);
  }

  _onImagePreviewChange = files => {
    debugger;
  }

  render() {
    const { handleSubmit } = this.props;
    return (
      <div>
        <form onSubmit={ handleSubmit(this._onSubmit.bind(this)) }>
          <Field name="title" label="Name" type="text" component={ renderInputField }/>
          <Field name="description" label="Description" type="text" component={ renderTextAreaField }/>
          <Field name="amount" label="Amount" type="text" component={ renderInputField }/>
          <Field onChange={this._onImagePreviewChange.bind(this)} 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(null, { createExpense })(reduxForm({
  validate,
  form:'NewExpense',
  validators
})(NewExpense));

2 个答案:

答案 0 :(得分:3)

从您的代码中不清楚如何触发验证(是提交还是字段级别?)。无论如何,我组装了一个工作here的沙箱。 我所做的是在你的领域添加验证属性

private static Point CalculateDiff(Point first, Point second)
{
    return second.Offset(-first.X, -first.Y);
}

并使用<Field validate={validateImage} name="image" component={renderDropzoneField} /> 代替dirty

touch

答案 1 :(得分:0)

您是否阻止在提交表单时发生默认操作?如果不是,页面将刷新并消除触摸和错误状态。

handleSubmit(event)中,您应该包含以下行:

event.preventDefault();

这会阻止页面在单击“提交”时刷新。