使用 React-intl 的 Redux-form 字段级验证和错误翻译
Posted
技术标签:
【中文标题】使用 React-intl 的 Redux-form 字段级验证和错误翻译【英文标题】:Redux-form Field-Level Validation & error translation with React-intl 【发布时间】:2018-09-06 18:24:08 【问题描述】:使用 redux-form,我尝试将 Field-Level Validation 与 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");
问题:当我的字段标签出现错误时,如果我更改语言,我的字段状态会丢失并且我的错误消息会消失。
我认为 validate props 的值不应该在渲染之间改变,因为它会导致字段被重新注册。解决办法是什么?
如何在字段级验证中为验证消息正确集成 react-intl?有可能吗?
【问题讨论】:
【参考方案1】:你不能使用包装到另一个函数中的验证函数,每次渲染表单时都会构造一个新函数,这会导致字段重新渲染(因为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>;
;
【讨论】:
谢谢,非常好的解决方案(最后一个消息取决于验证错误)【参考方案2】:正如 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;
;
【讨论】:
以上是关于使用 React-intl 的 Redux-form 字段级验证和错误翻译的主要内容,如果未能解决你的问题,请参考以下文章
如何将 react-intl 2 与 redux 一起使用?
使用 React-intl 的 Redux-form 字段级验证和错误翻译