J'ai un composant qui ressemble à ceci (version très simplifiée) :
const component = (props: PropTypes) => { const [allResultsVisible, setAllResultsVisible] = useState(false); const renderResults = () => { return ( <section> <p onClick={ setAllResultsVisible(!allResultsVisible) }> More results v </p> { allResultsVisible && <section className="entity-block--hidden-results"> ... </section> } </section> ); }; return <div>{ renderResults() }</div>; }
Lorsque je charge une page qui utilise ce composant, j'obtiens cette erreur : Uncaught Invariant Violation: Rendered more hooks than during the previous render.
J'ai essayé de trouver une explication à cette erreur, mais ma recherche n'a renvoyé aucun résultat.
Quand je modifie légèrement le composant :
const component = (props: PropTypes) => { const [allResultsVisible, setAllResultsVisible] = useState(false); const handleToggle = () => { setAllResultsVisible(!allResultsVisible); } const renderResults = () => { return ( <section> <p onClick={ handleToggle }> More results v </p> { allResultsVisible && <section className="entity-block--hidden-results"> ... </section> } </section> ); }; return <div>{ renderResults() }</div>; }
Je n'obtiens plus cette erreur. Est-ce parce que je suis dans la fonction renderResults
返回的 jsx 中包含了 setState
? Ce serait formidable s'il y avait une explication sur la raison pour laquelle ce correctif fonctionne.
J'ai également rencontré le même problème. Ce que je fais, c'est ceci :
Je pense que ce qui se passe, c'est que lors du premier rendu, le composant revient plus tôt et useEffect ne s'exécute pas. Lorsque l'état isLoading change et que useEffect s'exécute, j'obtiens l'erreur : Le hook s'affiche plus de fois qu'auparavant.
Un simple changement a résolu le problème :
Le correctif fonctionne car le premier exemple de code (le code incriminé) appelle
onClick
内的函数,而第二个代码示例(有效的代码示例)则将函数传递给了onClick
. La différence réside dans ces parenthèses très importantes, qui en JavaScript signifient « appeler ce code ».Pensez-y de cette façon : dans le premier exemple de code, vous effectuez le rendu
component
时,都会调用renderResults
。每次发生这种情况时,都会调用setAllResultsVisible(!allResultsVisible)
à chaque fois au lieu d'attendre un clic. Étant donné que React effectue le rendu selon son propre calendrier, il n'existe aucun moyen de déterminer combien de fois cela se produira.De la documentation React :
React gère les documents d'événements
Remarque : je ne parviens pas à obtenir le message d'erreur exact lors de l'exécution du premier exemple de code dans le bac à sable. Mon erreur implique une boucle infinie. Peut-être qu'une version plus récente de React produit l'erreur décrite ?