Сообщения проверки формы Antd 3.26 не повторяются с новым значением при изменении состояния / реквизитов

#javascript #reactjs #forms #antd

#javascript #reactjs #формы #antd

Вопрос:

У меня есть приложение React, которое использует Antd 3.26 (я не могу перенести его на новую версию). В этом приложении у меня есть простая функция перевода. Пользователь может изменить язык с помощью select, а пользовательский интерфейс обновляется метками, которые извлекаются из файла json. И здесь я столкнулся с этой проблемой:

Все метки обновляются до нового языка, за исключением сообщений о проверке при отправке формы. Я полагаю, что проблема в том, что компонент label не отображается повторно, но я понятия не имею, как я могу обойти или исправить это.

Вот код из тестового приложения, который я создал для этого вопроса, чтобы проиллюстрировать мою проблему:

 import React, { Component } from 'react';
import './App.css';
import { Form, Input, Button } from 'antd';

class App extends Component {
  state = {
    validationNameMessage: "Please input your name",
    validationPasswordMessage: "Please input your password",
  }


  onBtnClick = (e) => {
    e.preventDefault();
    this.props.form.validateFieldsAndScroll((err, values) => {
      // here is a simulated "request" to my backend server to get translation
      setTimeout(() => this.setState({ validationNameMessage: "Podaj nazwe", validationPasswordMessage: "Podaj haslo" }), 2000)
    });
  }
  render() {
    const { getFieldDecorator } = this.props.form;

    return (
      <div className="App">
        <div className="form-container">
          <Form name="test-form">
            <Form.Item label="Name">
              {getFieldDecorator("name", {
                rules: [
                  {
                    required: true,
                    message: this.state.validationNameMessage
                  }
                ]
              })(<Input />)}
            </Form.Item>
            <Form.Item style={{ marginTop: 12 }} label="Password">
              {getFieldDecorator("password", {
                rules: [
                  {
                    required: true,
                    message: this.state.validationPasswordMessage
                  }
                ]
              })(<Input />)}
            </Form.Item>
            <Form.Item>
              <Button onClick={this.onBtnClick} style={{ marginTop: 12 }} type="primary" htmlType="submit">
                Submit
              </Button>
            </Form.Item>
          </Form>
        </div>
      </div>
    );
  }
}
export default Form.create({ name: 'test-form' })(App);  

Ответ №1:

Проблема с приведенным вами примером заключается в том, что непереведенные проверки уже отрисованы до поступления переводов и, следовательно, будут отображаться, только если вы повторно запустите проверку после поступления переводов.

Одним из возможных решений будет использование setFields метода из Form API. Вы можете запустить переведенные проверки сразу после того, как вы установили их для состояния, вот так:

  this.setState(
          {
            validationNameMessage: "Podaj nazwe",
            validationPasswordMessage: "Podaj haslo"
          },
          //callback that triggers after the state has been updated
          () => {
            this.props.form.setFields({
              name: {
                value: values.name,
                errors: [
                  // only show the validation error if there is no value in the field
                  ...(values.name
                    ? []
                    : [new Error(this.state.validationNameMessage)])
                ]
              },
              password: {
                value: values.password,
                errors: [
                  ...(values.name
                    ? []
                    : [new Error(this.state.validationPasswordMessage)])
                ]
              }
            });
          }
        );
  

Это по-прежнему будет отображать непереведенные проверки в течение короткого времени (2 секунды в вашем примере), но переключится на переведенные проверки, как только они поступят.

Вот песочница, демонстрирующая предлагаемое решение на примере, который вы предоставили.