如何检查redux-form中是否存在任何错误

6
我正在使用React + Redux,以及redux-form来进行表单处理和验证。到目前为止,使用起来非常简单,我可以轻松地使用field.touched和field.error来检查单个表单字段的验证状态,但是我似乎找不到任何方法或属性来告诉我整个表单是否存在任何错误。因为React的工作方式,任何表单一旦加载就会生成一堆错误,这就是为什么需要使用field.touched来测试单个字段的原因。
我希望能够在整个表单中有任何错误时显示一些通用的标记,但只显示一次。所以,我真的希望有像form.touched和form.error这样的东西。我心中有一个辅助函数的设计,它将检查表单中的所有字段并返回一个布尔值,但如果可能的话,我更愿意避免这样做。
更新: 根据Andy_D的答案,我已经更新了我的代码,使用了表单级别的属性dirty和invalid,但是dirty似乎没有正确更新。在提交表单并看到单个字段级别的错误后,表单仍然显示dirty:false。
以下是我的代码的简化版本以及提交表单后this.props对象的内容。
import React, { Component } from 'react';
import { reduxForm } from 'redux-form';
import { makeBooking } from '../actions/index';

class PaymentBooking extends Component {
    render() {
        const { fields: { school }, handleSubmit } = this.props;

        return (
            <form className="form-horizontal" onSubmit={handleSubmit(this.props.makeBooking)}>
                {
                    console.log(this)
                }
                {
                    this.props.dirty && this.props.invalid ? <div className="alert alert-danger" role="alert">Test error wrapper</div> : ''
                }
                <h2>Make a New Payment Booking</h2>
                <div className="panel panel-default">
                    <div className="panel-heading">Payment Information</div>
                    <div className="panel-body">
                        <div className={`form-group ${school.touched && school.invalid ? 'has-error' : ''}`}>
                            <label htmlFor="school" className="col-lg-2 control-label">Your School</label>
                            <div className="col-lg-10">
                                <select name="school" className="form-control" {...school}>
                                    <option value="MIT">MIT</option>
                                    <option value="Stanford">Stanford</option>
                                    <option value="Arizona">Arizona</option>
                                </select>
                            </div>
                        </div>
                    </div>
                </div>
                </div>
                <div className="form-submit">
                    <button type="submit" className="btn btn-primary">Book a Payment</button>
                </div>
            </form>
        );
    }
}

function validate(values) {
    const errors = {};

    if (!values.school)
        errors.school = 'School is a required field';

    return errors;
}

export default reduxForm({
    form: 'PaymentBookingForm',
    fields: ['school'],
    validate
}, null, {makeBooking})(PaymentBooking);

提交后的this.props:
{
  "readonly": false,
  "asyncValidating": false,
  "dirty": false,
  "errors": {
    "school": "School is a required field"
  },
  "fields": {
    "school": {
      "name": "school",
      "defaultChecked": false,
      "valid": false,
      "invalid": true,
      "dirty": false,
      "pristine": true,
      "error": "School is a required field",
      "active": false,
      "touched": true,
      "visited": false
    }
  },
  "invalid": true,
  "pristine": true,
  "submitting": false,
  "submitFailed": true,
  "valid": false,
  "values": {}
}
2个回答

10

在 props 中有一个适用于您的表单级别的 pristinevalid 属性。

提交后,pristine 将被重置,但如果请求失败,您将获得一个 submitFailed 属性。

(!pristine || submitFailed) && !valid && <ErrorMessage />

还有反操作的属性,因此您可以使用

(dirty || submitFailed) && invalid

正如我在评论中提到的那样,如果表单无效,我会阻止提交。

<button
  type="submit"
  className="btn btn-primary"
  disabled={pristine || invalid}
>Book a Payment</button>

谢谢。我觉得问题可能很简单。不幸的是,它对我没有用。当我提交表格时,我的字段级别属性会更新并显示各个错误,但字段级别属性似乎没有更新。至少,pristine保持不变,dirty保持不变。我将尝试在我的问题中添加代码,看看是否有人可以识别更具体的问题。再次感谢。 - T Nguyen
问题在于提交后它仍然是原始的,尽管存在错误? - Andy_D
是的,没错。字段错误显示,这意味着更新了各个字段的touched属性,但在错误/提交后pristine仍然为true,而dirty也仍然为false。 - T Nguyen
我可能对你的用例有所遗漏,但如果表单无效,为什么不防止提交(禁用按钮/提交输入)?尽管如此,我认为你可以使用submitFailed - 编辑答案。 - Andy_D
我原本以为handleSubmit()函数的工作是在表单无效时阻止其提交?不管怎样,我已经更新了代码以使用submitFailed,这很有效,但我会记住你有关禁用提交按钮的建议,以备将来参考。谢谢。 - T Nguyen

0
我很晚才开始学习这个,最近遇到了一个问题。我需要知道Redux-Form中是否有任何活动字段错误,以便禁用表单中的提交按钮。
我的用例可能与OP的不太相同,但Andy_D的回复让我朝着正确的方向前进;然而,在我的情况下,我没有发现 pristine, dirtypure 对我有用。一旦它们从默认值切换,它们就保持那样,直到组件重新加载。 validinvalid 根据表单是否存在错误而来回切换。所以在我的情况下,我可以这样做:
<button 
    disabled={ this.props.invalid }
    type='submit' 
    className='btn btn-primary'
>
    Submit
</button>

我尝试使用类似Redux-Form的formValueSelector(),但是没有成功,所以这是我能找到的最好的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接