web-dev-qa-db-fra.com

React hook useEffect s'exécute en continu pour toujours / boucle infinie

J'essaye la nouvelle API React Hooks de useEffect et elle semble continuer de fonctionner pour toujours, dans une boucle infinie! Je souhaite que le rappel dans useEffect ne s'exécute qu'une seule fois. Voici mon code pour référence:

Cliquez sur "Exécuter l'extrait de code" pour voir la chaîne "Exécuter useEffect" imprimée à l'infini sur la console.

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/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>
17
Yangshun Tay

Cela se produit car useEffect est déclenché après chaque rendu, ce qui correspond à l'invocation de la fonction Counter() dans ce cas de composants fonctionnels sans état. Lorsque vous effectuez un appel setX renvoyé par useState dans un useEffect, React rendra à nouveau ce composant et useEffect s'exécute à nouveau, ce qui provoque une boucle infinie:

Counter()useEffect()setCount()Counter()useEffect() → ... (boucle)

Pour que votre useEffect ne s'exécute qu'une seule fois, passez un tableau vide [] comme deuxième argument, comme le montre l'extrait de code révisé ci-dessous.

L'intention du deuxième argument est d'indiquer React lorsque l'une des valeurs de l'argument tableau change:

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

Vous pouvez passer n'importe quel nombre de valeurs dans le tableau et useEffect ne s'exécutera que lorsque l'une des valeurs changera. En passant dans un tableau vide, nous disons à React de ne pas suivre les modifications, ne s'exécute qu'une seule fois, simulant efficacement 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/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

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

En savoir plus sur seEffect .

27
Yangshun Tay