Разница в доступе к реквизитам после изменения в хранилище redux между компонентом класса React и функциональным компонентом React

У меня проблема с пониманием, почему в компоненте на основе класса и функциональном компоненте одни и те же шаги приводят к разному результату. Ниже у меня есть пример, демонстрирующий эту разницу.

   class Test extends Component {
      handleSubmit = e => {
        e.preventDefault();
        this.props.form.validateFields(async (err, values) => {
 
            await this.props.saveUserDetailsAction(values);

            const { error } = this.props; // expected modified prop 

            if (!error.status) {
              this.props.router.push("/route");
            } 
        });
      };
    }

const mapStateToProps = ({ app }) => ({
 error: app.error
});

const mapDispatchToProps = {
  saveUserDetailsAction,
};

export default compose(
  withRouter,
  connect(
    mapStateToProps,
    mapDispatchToProps
  )
)(Test);

Текущая ошибка в компоненте класса отражает изменения в хранилище redux после завершения асинхронной функции saveUserDetailsAction, в этом случае отправляя действие в случае сбоя запроса.

Доступ к реквизитам ошибок после того, как функция saveUserDetailsAction показывает обновленное свойство.

Тот же код, написанный как функциональный компонент, не дает такого же результата. Доступ к опоре ошибки после завершения функции saveUserDetailsAction еще не отражает изменения в хранилище.

  const Test = (props) => {
      const handleSubmit = e => {
        e.preventDefault();
        props.form.validateFields(async (err, values) => {     

            await props.saveUserDetailsAction(values);

            const { error } = props;  // unchanged prop when accessed here

            if (!error.status) {
              props.router.push("/route");
            }
        });
      };
    }

const mapStateToProps = ({ app }) => ({
 error: app.error
});

const mapDispatchToProps = {
  saveUserDetailsAction,
};

export default compose(
  withRouter,
  connect(
    mapStateToProps,
    mapDispatchToProps
  )
)(Test);

1 ответ

На мой взгляд, это антипаттерн, вам нужно дождаться следующего цикла, чтобы получить правильные пропсы ошибок. Функциональная составляющая - это правильное поведение. Что вам нужно сделать, так это найти способ вернуть здесь ошибку:

const { error } = await props.saveUserDetailsAction(values);

Переменная ошибки хранилища Redux все еще может использоваться в другом компоненте

Другой способ сделать это - использовать useEffect(() => {}, [error]) и различать 3 состояния "Еще не отправлено", "Отправлено без ошибок", "Отправлено с ошибкой", но я не рекомендую это

Другие вопросы по тегам