Я хочу использовать форму Redux таким образом, чтобы изменить цвет ввода и отобразить фактическую ошибку в верхней части страницы. Как получить доступ к списку текущих ошибок полей за пределами самих полей?
Redux-form: отображает список ошибок поверх страницы
Ответ 1
Вы не можете получить список ошибок извне функции рендеринга, данной компоненту Field. Это связано с тем, что ошибки не сохраняются в хранилище избыточности.
ИЗМЕНИТЬ 26/12/2018:
Этот ответ занимает некоторое время. ReduxForm теперь хранит ошибки в магазине Redux. Посмотрите на ответ @nicoqh, который использует селекторы ReduxForm для получения ошибок в любом подключенном компоненте Redux.
Этот ответ не является полностью устаревшим, но это уже не самый чистый способ достичь этого imho.
Решение 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:
Это последнее "решение" не было хорошим, когда я его опубликовал. Но так как componentWillReceiveProps
устарел в React, это вовсе не решение. Пожалуйста, не делайте этого в вашем приложении. Я не удаляю это для истории, если этот ответ был где-то связан.
Ответ 2
Вы можете использовать селекторы состояний, предоставляемые при помощи редукционной формы.
В частности, 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
.
Ответ 3
вы можете использовать Fields
для сбора всей информации о поле, включая ошибки;
Нажмите Поля !
Насладись щелчком здесь !