【问题标题】:Redux-form Field-Level Validation & error translation with React-intl使用 React-intl 的 Redux-form 字段级验证和错误翻译
【发布时间】: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?有可能吗?

【问题讨论】:

    标签: javascript reactjs redux redux-form 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;
      };
    

    【讨论】:

      猜你喜欢
      • 2018-02-16
      • 1970-01-01
      • 2017-12-19
      • 2017-01-22
      • 2016-08-07
      • 2022-06-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      相关资源
      最近更新 更多