С помощью обработчиков реакции установить состояние, в каких случаях мне нужно передать функцию для установки состояния? - PullRequest
1 голос
/ 28 июня 2019

вот мой код:

function Tiker() {
  var [count, setCount] = useState(0);

  useEffect(() => {
    var timerID = setInterval(_=>
      setCount(count=>count+1)//setCount(count+1) wont work
    , 1000);

    return function cleanup() {
      clearInterval(timerID);
    };
  }, []);
  return <div>
      this is ticker   
      <button onClick={() => 
        setCount(count + 1)//setCount(count+1) does work
      }>up </button>
      {count}
      </div>
}

Методом проб и ошибок я обнаружил, что если я использую setCount из обратного вызова setinterval, я должен передать обратный вызов в установленное состояние, а не просто в значение.

это не тот случай, если я звоню из onclick.

Почему это?

Ответы [ 2 ]

2 голосов
/ 28 июня 2019

Проблема заключается во втором аргументе useEffect

useEffect(() => {
    var timerID = setInterval(_=>
        setCount(count=>count+1)//setCount(count+1) wont work
    , 1000);

    return function cleanup() {
        clearInterval(timerID);
    };
}, []);

Это пустой массив ([]).Он определяет список зависимостей для ловушки.Поскольку он пуст, это означает, что ловушка не зависит от какого-либо значения состояния или реквизита.Таким образом, переменная count используется при первом вызове useEffect, а затем остается устаревшей.

Чтобы исправить это, вы должны либо полностью удалить второй аргумент useEffect, либо сделать массив, содержащий [count].

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

Таким образом, правильный код будет выглядеть как

function Tiker() {
    var [count, setCount] = useState(0);

    useEffect(() => {
        var timerID = setInterval(_=>
            setCount(count + 1)
        , 1000);

        return function cleanup() {
            clearInterval(timerID);
        };
    }, [count]);  // Put variable that useHook depends on

    return <div>
        this is ticker   
        <button onClick={() => 
            setCount(count + 1) //setCount(count+1) does work
        }>up </button>
        {count}
    </div>
}
0 голосов
/ 28 июня 2019

Похоже, что использование обратного вызова - это самый простой способ изменить состояние при вызове из setInterval. как видно из комментария Фродора выше и из https://overreacted.io/making-setinterval-declarative-with-react-hooks/

...