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

the*_*ist 16 javascript reactjs redux redux-form

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

Emr*_*oin 20

您无法从Field组件的render函数外部获取错误列表.这是因为错误未存储在redux存储中.

编辑26/12/2018:

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

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

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

第一种解决方案是使用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)
Run Code Online (Sandbox Code Playgroud)

解决方案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)
Run Code Online (Sandbox Code Playgroud)

解决方案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)
Run Code Online (Sandbox Code Playgroud)

最后一个解决方案是通过实现componentWillReceiveProps和调度操作来更新商店中的错误列表,将错误存储在商店中,但我认为这不是一个好主意.保持简单的无状态组件以呈现Field组件更好.

编辑26/12/2018:

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


nic*_*oqh 13

您可以使用redux-form提供状态选择器.

特别是,getFormSubmitErrors会给你提交验证错误:

import { getFormSubmitErrors } from 'redux-form';

// ...

const MyFormWithErrors = connect(state => ({
  submitErrors: getFormSubmitErrors('my-form')(state)
}))(MyForm);
Run Code Online (Sandbox Code Playgroud)

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

const MyForm = reduxForm({
  form: 'my-form',
})(ManageUserProfile);
Run Code Online (Sandbox Code Playgroud)

如果要显示同步验证错误,可以使用getFormSyncErrors选择器.