Состояние реакции не обновляется в правиле проверки формы - PullRequest
0 голосов
/ 25 января 2019

Как заявление об отказе, я новичок в React , Redux и Redux-saga .Я пытаюсь реализовать пользовательское правило проверки , используя реагировать-материал-пользовательский-валидатор .У меня есть поле формы TextValidator для ввода имени человека, и я хотел бы, чтобы оно возвращало false, когда введенное имя уже существует.У меня есть компонент React с ValidatorForm и пользовательское правило внутри componentDidMount(), которое выглядит примерно так:

class NameCollector extends React.Component {
  constructor(props) {
    super(props);
    const { nameIsUnique} = this.props;
    this.state = {
      nameIsUnique,
    };
  }

  componentDidMount() {
    // custom rule below
    ValidatorForm.addValidationRule('nameIsUnique', () => {
      const { nameIsUnique } = this.state;
      return !nameIsUnique;
    });
  }

  static getDerivedStateFromProps(props, state) {
    if (props.nameIsUnique !== state.nameIsUnique) {
      return {
        nameIsUnique: props.nameIsUnique,
      };
    }
    return null;
  }

  render() {
    const {
      personsName,
      handleNameChange,
    } = this.props;

    const {
      personsName,
    } = this.state;

    return (
  <ValidatorForm>
    <TextValidator
      value={personsName}
      validators={['nameIsUnique']}
      errorMessages={['Name exists already']}
      onChange={
        event => handleNameChange({ personsName: event.target.value })
      }
    />
  </ValidatorForm>
    );
  }
}

Проблема: Значение nameIsUnique внутри правила проверки остаетсясинхронизации от значения, которое передается через реквизиты в этот компонент.За кулисами я использую наблюдатель Redux-saga для получения значения nameIsUnique из веб-службы.Возвращаемое значение асинхронно обновляется в родительском компоненте и передается в качестве опоры моему компоненту NameCollector.Вот как выглядит родительский компонент контейнера:

import React from 'react';
import { connect } from 'react-redux';
import {
  actionTypes,
  updateName,
} from '../../reducers/nameCollector';
import NameCollector from './NameCollector';

class NameCollectorContainer extends React.Component {
  render() {
    const {
      personsName,
      nameIsUnique,
      handleNameChange,
    } = this.props;

    return (
      <NameCollector
        personsName={personsName}
        nameIsUnique={nameIsUnique}
        handleNameChange={handleNameChange}
      />
    );
  }
}

const mapStateToProps = state => ({
  personsName: state.personsName,
  nameIsUnique: state.nameIsUnique,
});

const mapDispatchToProps = dispatch => ({
  handleNameChange: (value) => {
    dispatch(updateName(value));
    dispatch({
      type: actionTypes.FETCH_NAME_EXISTS,
      name: value.personsName,
    });
  },
});

export default connect(mapStateToProps, mapDispatchToProps)(NameCollectorContainer);

Я подтвердил, что функция handleNameChange отправляет в мою сагу, а значение nameIsUnique, сопоставленное в mapStateToProps, успешно обновляется с помощьюправильное значение.Проблема в том, что NameCollector дочерний компонент не точно отражает значение nameIsUnique, когда оно передается для использования при пользовательской проверке.

В коде для дочернего компонента NameCollector значение nameIsUnique передается в виде реквизита и отображается в состояние React внутри конструктора.Я подозреваю, что проблема связана с асинхронной природой значения, которое возвращает mapStateToProps, и с чем-то в жизненном цикле React, что я не понимаю.Вы можете видеть в компоненте NameCollector, я пытался принудительно обновить это состояние, проверяя getDerivedStateFromProps, чтобы попытаться обновить состояние при обновлении значения проп.К сожалению, кажется, что значение nameIsUnique всегда отстает от правильного значения, возвращенного моим запросом API.Я подтвердил это, написав операторы console.log внутри функции проверки и внутри метода рендеринга дочернего компонента.

Как правильно убедиться, что мое значение состояния nameIsUnique всегда самое последнее?Я хотел бы использовать компонент реагировать-материал-ui-форма-валидатор для этой проверки и несколько других, но я не уверен, является ли моя проблема ограничением компонента или способомЯ использую React и Redux.Буду признателен за любую помощь или совет!

...