入力色を変更し、ページの上部に実際のエラーを表示する方法でReduxフォームを使用したいと思います。現在のフィールドエラーのリストにフィールド自体の外でアクセスするにはどうすればよいですか?
Fieldコンポーネントに与えられたレンダリング関数の外部からエラーのリストを取得することはできません。これは、エラーがreduxストアに格納されないためです。
この答えは少し時間がかかります。 ReduxFormは、エラーをReduxストアに格納するようになりました。 @ nicoqhの回答 を見てください。これは、ReduxFormのセレクターを使用して、Reduxに接続されたコンポーネントでエラーを取得しています。
この答えは完全に古くなっているわけではありませんが、この無差別を達成するための最もクリーンな方法ではありません。
最初の解決策は、同じ値に対して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)
ストアに存在する値に検証関数を適用することで、常にストアからエラーを取得できます。レンダリングごとに検証を実行するため、厳密な検証ではパフォーマンスが低下する可能性があります。したがって、値が変更されると2回実行され、他のプロパティが変更されると1回実行されます。また、非同期検証を行うのが難しい場合もあります。
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コンポーネントをレンダリングするには、単純なステートレスコンポーネントを保持することをお勧めします。
この最後の「解決策」は、私が投稿した時点では適切ではありませんでした。しかし、componentWillReceiveProps
はReactではdeprecatedなので、まったく解決策ではありません。アプリケーションではこれを行わないでください。この回答がどこかにリンクされている場合に備えて、履歴からこれを削除しません。
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
セレクターを使用できます。