Redux-form:在页面顶部显示错误列表

时间:2016-09-06 10:41:35

标签: javascript reactjs redux redux-form

我想以改变输入颜色和方式的方式使用Redux-form。在页面顶部显示实际错误。如何访问字段本身之外的当前字段错误列表?

2 个答案:

答案 0 :(得分:19)

您无法从提供给Field组件的渲染函数外部获取错误列表。这是因为错误未存储在redux存储中。

编辑26/12/2018:

这个答案需要一些年龄。 ReduxForm现在将错误存储在Redux存储中。看看正在使用ReduxForm选择器的@nicoqh's answer来获取任何Redux连接组件中的错误。

这个答案并非完全过时,但它不再是实现这个目标的最简洁方法。

解决方案1:对同一个值使用多个字段

第一种解决方案是将多个Field实例用于相同的值。如果多个Field组件具有相同的名称并连接到相同的表单名称,则它们将全部连接到相同的值和相同的错误处理。

因此,您可以使用Field组件并仅渲染错误。

import React from 'react'
import {reduxForm} from 'redux-form'

const renderError = ({input, meta, ...props}) => (
    <span {...props} className='error'>Error : {meta.error}</span>
)

const renderInput = ({input, meta, ...props}) => (
    <input {...input} {...props} className={meta.error ? 'error' : null} />
)

const FormWithError = ({handleSubmit}) => (
    <div>
        <div className='errorContainer'>
            <Field name='myInput' component={renderError} />
        </div>
        <form onSubmit={handleSubmit}>
            <Field name='myInput' component={renderInput} />
        </form>
    </div>
)

const validate = (values, props) => {
    const errors = {}
    /* calculate errors here by appending theim to errors object */
    return errors
}

export default reduxForm({form: 'myForm', validate})(FormWithError)

解决方案2:使用全局错误道具

第二种解决方案是使用全局错误道具,但您必须使用reduxForm显示容器组件中的错误。

注意这是一个完整的反模式!全局错误道具是针对字段无关的错误。

import React from 'react'
import {reduxForm} from 'redux-form'

const renderInput = ({input, meta, ...props}) => (
    <input {...input} {...props} className={meta.error ? 'error' : null} />
)

const FormWithError = ({handleSubmit, error}) => (
    <div>
        <div className='errorContainer'>
            <span {...props} className='error'>Error : {error}</span>
        </div>
        <form onSubmit={handleSubmit}>
            <Field name='myInput' component={renderInput} />
        </form>
    </div>
)

const validate = (values, props) => {
    const errors = {}
    /* calculate errors here by appending theim to errors object */
    if(Object.keys(errors) > 0) {
        //You can concatenate each error in a string
        for(key in errors) errors._error += key + ': ' + errors[key]
        //or juste put the errors object in the global error property
        errors._error = {...errors}
    }
    return errors
}

export default reduxForm({form: 'myForm', validate})(FormWithError)

解决方案3:从商店获取错误

通过对商店中显示的值应用验证功能,您始终可以从商店获得错误。它可能无法进行大量验证,因为它在每次渲染时都会通过验证,因此在值更改时会运行两次,如果某些其他道具发生更改则会运行一次。使用异步验证也很困难。

import React from 'react'
import {reduxForm, formValueSelector} from 'redux-form'
import {connect} from 'redux'

const renderErrors = errors => {
    const errorNodes = []
    for(key in errors) errorNodes.push(<span className='error'>{key}: {errors[key]}</span>)
    return errorNodes
}

const renderInput = ({input, meta, ...props}) => (
    <input {...input} {...props} className={meta.error ? 'error' : null} />
)

let FormWithError = ({handleSubmit, values, ...otherProps}) => (
    <div>
        <div className='errorContainer'>
            {renderErrors(validate(values, otherProps))}
        </div>
        <form onSubmit={handleSubmit}>
            <Field name='myInput1' component={renderInput} />
            <Field name='myInput2' component={renderInput} />
        </form>
    </div>
)

const validate = (values, props) => {
    const errors = {}
    /* calculate errors here by appending theim to errors object */
    return errors
}

FormWithError = reduxForm({form: 'myForm', validate})(FormWithError)
FormWithError = connect(
    state => formValueSelector('myForm')(state, 'myInput1', 'myInput2')
)(FormWithError)
  

最后一个解决方案是将错误存储在商店中,方法是实施componentWillReceiveProps并调度操作以更新商店中的错误列表但我不认为它真的存在一个好主意。保持简单的无状态组件以渲染Field组件会更好。

编辑26/12/2018:

最后一个&#34;解决方案&#34;在我发布它的时候,它并不是一个好的。但是,由于React中componentWillReceiveProps 已弃用,因此根本不是解决方案。请不要在您的申请中这样做。如果这个答案被链接到某处,我不会删除此历史记录。

答案 1 :(得分:11)

您可以使用state selectors provided by redux-form

特别是,getFormSubmitErrors会为您提供提交验证错误

import { getFormSubmitErrors } from 'redux-form';

// ...

const MyFormWithErrors = connect(state => ({
  submitErrors: getFormSubmitErrors('my-form')(state)
}))(MyForm);

原始未连接的MyForm组件可能如下所示:

const MyForm = reduxForm({
  form: 'my-form',
})(ManageUserProfile);

如果您想显示同步验证错误,则可以使用getFormSyncErrors选择器。