Странная проблема подпоследовательности с useState - PullRequest
0 голосов
/ 28 марта 2020

С компонентами на основе класса я могу (например) сделать следующее:

doThing = () => {
    this.setState({
        test: 'Zest'
    })

    setTimeout(() => {
        console.log(this.state.test) // will return 'Zest'
    },1000)

}

Однако в функциональном компоненте с хуком useState состояние выиграло ' не обновляется до тех пор, пока не будет вызван другой прослушиватель событий. Мой пример наиболее очевиден при использовании слушателя setTimeout, но он проявляется и во многих других контекстах.

После вызова прослушивателя событий обновления состояния не принимаются до вызова другого.

До сих пор, каждый раз, когда эта странная причуда вызывала какие-либо проблемы, я просто заменял компонент обратно на классовый, но мне всегда было интересно, о чем он.

Может ли кто-нибудь объяснить, почему или предложить способы получения обновленного состояния в рамках функции обратного вызова / тайм-аута / интервала / et c с использованием функционального компонента и реагирующих перехватчиков?

Ответы [ 2 ]

0 голосов
/ 28 марта 2020

Я не могу понять, почему вы используете setTimeout, может быть, вы знаете, что this.setState является асинхронной функцией, и вы использовали setTimeout для обработки действия после изменения состояния. если это ваша цель, вы должны написать это следующим образом:

doThing = () => {
  this.setState(
    {
      test: 'Zest'
    },
    () => {
      console.log(this.state.test) // **
    }
  );
}

На самом деле, исходя из ReactJS документов , setState может получить обратный вызов. поэтому, если вы хотите сделать что-то сразу после изменения состояния, используйте функцию обратного вызова setState.

NOW для компонента Function

Для того, чтобы описанная выше ситуация для компонента функции была написана, как показано ниже :

import React, { useState, useEffect, useCallback } from 'react';

const FunctionComponent = () => {
  const [test, setTest] = useState('');
  const doThing = useCallback(() => {
    setTest('Zest');
  }, []);

  useEffect(() => {
    console.log(test) // here is exactly like **
  }, [test]);

  return (
    <div // etc...
  );
};

Функция doThing создается только один раз при монтировании FunctionComponent, потому что мы используем useCallback и передаем [] зависимость от нее. тогда обратный вызов useEffect часто выполняется сразу после изменения состояния test.

0 голосов
/ 28 марта 2020

Я не уверен, в чем твоя проблема. Это связано с setTimeout? Потому что есть ловушка в ответных хуках для setTimeout setInterval ). setTimeout является закрытием, поэтому, когда запланировано setTimeout, оно использует значение count в тот момент времени, которое является начальным значением.

Для правильного использования setTimeout в хуках, см. Этот вопрос .

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

function App() {
  const [test] = useState("Zest");

  setTimeout(() => {
    console.log(test);
  }, 1000);

Не могли бы вы продемонстрировать проблему AddEventlistener, с которой вы столкнулись?

Кроме того, я немного подозреваю, что вам нужно добавить прослушиватели событий в программе реакции. Обычно это можно сделать, просто используя обработчики реагирования onChange и т. П.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...