代码之家  ›  专栏  ›  技术社区  ›  Arian

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

  •  1
  • Arian  · 技术社区  · 6 年前

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

    场渲染方法:

    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,并且 错误 undefiend

    更新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 回复  |  直到 6 年前
        1
  •  3
  •   Dario    6 年前

    代码中不清楚如何触发验证(是提交还是字段级?)。总之我组装了一个沙箱 here 。 我所做的是将validation属性添加到字段中

    <Field validate={validateImage} name="image" component={renderDropzoneField} />
    

    和使用 dirty 而不是 touch

    {dirty &&(error && <span>{error}</span>)}
    
        2
  •  0
  •   Lucas Kellner    6 年前

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

    在里面 handleSubmit(event) 您应该包括以下行:

    event.preventDefault();

    这将阻止在单击提交时刷新页面。