使用redux-form,我尝试使用i18n进行字段级验证。我使用的是react-intl(https://github.com/yahoo/react-intl),所以我尝试了这个:
<Field name="Label" component={renderField} validate={[required(this.props.intl)]}
使用验证功能:
const required = (intl) => (value) => {return value ? undefined : intl.formatMessage({id:"Required"})};
问题:当我的字段标签出现错误时,如果我更改语言,我的字段状态将丢失,我的错误消息将消失。
我认为验证道具的价值不应该在渲染之间发生变化,因为它会导致重新注册该字段。解决方案是什么?
如何在Field-Level Validation中正确地将react-intl集成到验证消息中?有可能吗?
答案 0 :(得分:5)
你不能将验证函数包装到另一个函数中,每次渲染表单时它都会构造一个新函数,这将导致字段重新渲染(因为this.props.validate !== nextProps.validate
)。
但是您可以创建Field
渲染组件并将本地化验证消息作为道具传递给它。这是一个例子:
<form>
<Field
name='Label'
component={RenderField} //here you pass field render component
validate={required}
validationMessage={this.props.intl.formatMessage({id: 'Required'})}
/>
{/*rest of the form*/}
</form>
RenderField组件:
const RenderField = (props) => {
const {validationMessage, meta: {touched, error}} = props;
return <div>
<input
{...props}
/>
{touched &&
(error &&
<div className='error'>
{validationMessage}
</div>)}
</div>;
};
export default RenderField;
或者,如果您需要具有不同的验证消息取决于验证错误,您可以创建将返回formatMessageId
并将intl
传递给RenderField
的特定验证函数:
const RenderField = (props) => {
const {intl, meta: {touched, error}} = props;
return <div>
<input
{...props}
/>
{touched &&
(error &&
<div className='error'>
{intl.formatMessage(error)}
</div>)}
</div>;
};
答案 1 :(得分:0)
正如 Igor 所提到的,这是实现目标的好方法。
React intl 有一种以基本方式注入 intl 的新方法,通过注入,您无需在 RenderField
中传递 intl:
<Form onSubmit={handleSubmit(onSubmit)}>
<Form.Row >
<Field name="shortName" component={RenderField}
label={intl.formatMessage({ id: "component.userShippingAddress.shortNameLabel" })}
placeholder={intl.formatMessage({ id: "component.userShippingAddress.shortNamePlaceholder" })}
>
</Field>
</Form.Row>
{/*rest of the form*/}
</Form>
渲染字段:
import React from 'react'
import { Form } from 'react-bootstrap'
import { injectIntl } from "react-intl"
const RenderField = injectIntl(({intl, ...props}) => {
const {input, label, placeholder, type, meta: {touched, error}} = props;
const hasError = touched && error
return (
<Form.Group controlId={input.name} >
<Form.Label>{label}</Form.Label>
<Form.Control isInvalid={hasError}
{...input}
type={type}
placeholder={placeholder ? placeholder : label}
>
</Form.Control>
{hasError && <Form.Control.Feedback type="invalid">{intl ? intl.formatMessage({id: error}) : error}</Form.Control.Feedback>}
</Form.Group>
);
});
export default RenderField;
您可以在验证中呈现自定义错误,只需从 intl 传递您的 id:
export const validate = formValues => {
const errors = {};
if (!formValues.shortName) {
errors.shortName = 'component.userShippingAddress.shortNameNotEmpty';
}
return errors;
};