使用 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 消息的多次使用?

使用 React-intl 的 Redux-form 字段级验证和错误翻译

有没有办法使用 React-Intl 访问当前的语言环境?

是否可以通过使用react-intl库在clojurescript中实现本地化?

如何使用 React-Intl 插入带有 injectIntl​​ formatMessage 的 HTML 标记?