我想以更改输入颜色并在页面顶部显示实际错误的方式使用 Redux-form。如何访问字段本身之外的当前字段错误列表?
Redux-form:在页面顶部显示错误列表
您无法从提供给 Field 组件的渲染函数外部获取错误列表。这是因为错误未存储在 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)
解决方案 2:使用全局错误props
第二种解决方案是使用全局错误props,但您必须使用reduxForm
.
请注意,这是一个完全的反模式!全局错误props用于与字段无关的错误。
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:从商店获取错误
通过将验证函数应用于存储中的值,您始终可以从存储中获取错误。对于大量验证,它可能没有性能,因为它在每次渲染时都经过验证,所以当值改变时它运行两次,如果其他一些 props 改变,它会运行两次。使用异步验证也很困难。
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 :
在我发布它时,这最后一个“解决方案”并不是一个好的解决方案。但由于componentWillReceiveProps
被弃用的react,它不是在所有的解决方案。请不要在您的应用程序中执行此操作。如果此答案链接到某处,我不会删除历史记录。
您可以使用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
选择器。