React hook useEffect выполняется постоянно навсегда / бесконечный цикл - PullRequest
0 голосов
/ 10 ноября 2018

Я пробую новый React Hooks useEffect API, и он, кажется, продолжает работать вечно, в бесконечном цикле! Я только хочу, чтобы обратный вызов в useEffect запускался один раз. Вот мой код для справки:

Нажмите «Выполнить фрагмент кода», чтобы увидеть, как строка «Выполнить useEffect» печатается на консоли бесконечно.

function Counter() {
  const [count, setCount] = React.useState(0);

  React.useEffect(() => {
    console.log('Run useEffect');
    setCount(100);
  });

  return (
    <div>
      <p>Count: {count}</p>
    </div>
  );
}

ReactDOM.render(<Counter />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

1 Ответ

0 голосов
/ 10 ноября 2018

Это происходит потому, что useEffect запускается после каждого рендеринга, который является вызовом функции Counter() в этом случае функциональных компонентов без сохранения состояния. Когда вы выполняете вызов setX, возвращенный из useState в useEffect, React снова отобразит этот компонент, и useEffect снова запустится. Это вызывает бесконечный цикл:

Counter()useEffect()setCount()Counter()useEffect() → ... (цикл)

Чтобы ваш useEffect запускался только один раз, передайте пустой массив [] в качестве второго аргумента, как показано в исправленном фрагменте ниже.

Целью второго аргумента является сообщить React, когда изменяется любое из значений в аргументе массива:

useEffect(() => {
  setCount(100);
}, [count]); // Only re-run the effect if count changes

Вы можете передать любое количество значений в массив, и useEffect будет работать только при изменении любого из значений. Передавая пустой массив, мы говорим React не отслеживать какие-либо изменения, только запускать один раз, эффективно имитируя componentDidMount.

function Counter() {
  const [count, setCount] = React.useState(0);

  React.useEffect(() => {
    console.log('Run useEffect');
    setCount(100);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
    </div>
  );
}

ReactDOM.render(<Counter />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>

<div id="app"></div>

Узнайте больше о useEffect .

...