1
votes

useEffect boucle infinie lors de l'obtention des données de la base de données

Dans mon projet, pour envoyer une demande pour récupérer mes données utilisateur et les montrer. J'ai écrit le code ci-dessus mais je me suis rendu compte que si je passe les "personnes" à la dépendance de useEffect (deuxième paramètre), react envoie une requête infinie à ma base de feu mais si je supprime et garde le deuxième paramètre vide, useEffect fonctionne correctement quelle est la différence entre ces derniers deux?

Voici le code qui va en boucle infinie:

const [people, setPeople]=useState([])

useEffect(() => {
    const unsubscribe=database.collection("people").onSnapshot(snapshot=>
        setPeople(snapshot.docs.map(doc=>doc.data()))
        )
        

    return () => {
        unsubscribe()
    }
}, [people]) // if i change the second parameter with an empty list this problem solved.

return (
    <div>
        <h1>TinderCards</h1>
        <div className="tinderCards_cardContainer">
        {people.map(person =>
           <TinderCard
            className="swipe"
            key={person.name}
            preventSwipe={["up","down"]}
           >
            <div style={{backgroundImage: `url(${person.url})`}} className="card">
                <h3>{person.name}</h3>

            </div>
            </TinderCard> 
            )}
        </div>

    </div>
)


1 commentaires

Utilisez simplement un tableau de dépendances vide comme [] ainsi il ne sera déclenché qu'une seule fois.


4 Réponses :


0
votes

PROBLÈME

useEffect s'exécute à chaque fois qu'une des valeurs données au tableau de dépendances change. Depuis, vous mettez à jour vos people après l'appel de la db . La référence au tableau people change, déclenchant ainsi une boucle infinie sur useEffect

SOLUTION

Vous n'avez pas besoin de placer des personnes dans le tableau de dépendances. Votre fonction useEffect ne dépend pas des people .

useEffect(() => {
    const unsubscribe=database.collection("people").onSnapshot(snapshot=>
        setPeople(snapshot.docs.map(doc=>doc.data()))
        )
        

    return () => {
        unsubscribe()
    }
}, [])

0 commentaires

1
votes

Le problème est qu'après avoir défini l'état dans useEffect, la valeur des people sera modifiée, ce qui déclenchera un autre appel useEffect, d'où une boucle infinie.

Vous pouvez le modifier comme suit: -

useEffect(() => {
    const unsubscribe=database.collection("people").onSnapshot(snapshot=>
        setPeople(snapshot.docs.map(doc=>doc.data()))
        )
        

    return () => {
        unsubscribe()
    }
}, [])


0 commentaires

1
votes

Essentiellement, le hook useEffect exécute le code de fonction interne à chaque fois que l'une des dépendances du tableau de dépendances (deuxième paramètre) change.

Puisque setPeople change les gens, l'effet continue de s'exécuter dans une boucle infinie:

const a = [1,2,3];
const b = [1,2,3];

console.log(a === b); // <- false

Si vous aviez besoin d'une manière ou d'une autre de la valeur de personnes et que vous devez l'avoir dans le tableau de dépendances, une façon de vérifier est si les people ne sont pas définies:

useEffect(() => {
  if (!people) {
    // ... do something
    setPeople(something);
  }
}, [people]);

Comme vous l'avez correctement souligné, le simple fait de retirer la dépendance people indique à l'effet de ne s'exécuter qu'une seule fois, lorsque le composant est "monté".

Sur une note supplémentaire, vous vous demandez peut-être pourquoi les people changent si vous obtenez exactement les mêmes résultats. C'est parce que la comparaison est superficielle, et chaque fois qu'un tableau est créé, c'est un objet différent:

useEffect(() => {
  ... setPeople() ... // <- people changed
}, [people]);         // <- run every time people changes

Vous auriez besoin de faire des vérifications d'égalité approfondies pour cela.


0 commentaires

-1
votes

Le problème principal est que le tableau de personnes qui est créé à chaque appel de poste n'est pas le même. L'objet est complètement différent. J'ai également eu ce problème car je veux afficher le contenu dès que de nouvelles "personnes" sont ajoutées à la base de données à partir du panneau d'administration, mais il s'avère que sans actualiser cette chose ne peut pas être résolue sinon vous pouvez créer votre propre crochet avec de bonnes comparaisons.

Peut-être que vous pouvez essayer en comparant la longueur du tableau PEOPLE. Je ne l'ai pas encore essayé mais je pense que cela fonctionnera.


0 commentaires