Violation invariante non détectée : rendu avec plus de hooks que le rendu précédent
P粉477369269
P粉477369269 2024-03-25 16:50:53
0
2
547

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.

P粉477369269
P粉477369269

répondre à tous(2)
P粉729198207

J'ai également rencontré le même problème. Ce que je fais, c'est ceci :

const Table = (listings) => {

    const {isLoading} = useSelector(state => state.tableReducer);

    if(isLoading){
        return <h1>Loading...</h1>
    }

    useEffect(() => {
       console.log("Run something")
    }, [])

    return (<table>{listings}</table>)
}

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 :

const Table = (listings) => {
    
    const {isLoading} = useSelector(state => state.tableReducer);
        
    useEffect(() => {
        console.log("Run something")
    }, [])
    
    if(isLoading){
        return <h1>Loading...</h1>
    }
    return (<table>{listings}</table>)
}
P粉448346289

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 ?

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!