1

In my project, for sending a request for getting my user data and show them. I wrote the above code but i realised that if i pass the "people" to useEffect's dependency (second parameter) react sends infinite request to my firebase but if i delete and keep the second parameter empty the useEffect works correct what is the difference between these two?

Here is the code that goes to infinite loop:

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
  • Simply use an empty dependency array there as [] thus it will be triggered only once. Commented Oct 6, 2020 at 13:22

4 Answers 4

4

Essentially, the useEffect hook runs the inner function code every time any of the dependencies in the dependency array (second parameter) change.

Since setPeople changes people, the effect keeps running in an infinite loop:

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

If you needed somehow the value of people and you need to have it in the dependency array, one way to check is if people is not defined:

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

As you correctly pointed out, simply taking off the people dependency tells the effect to only run once, when the component is "mounted".

On an extra note, you may be wondering why people is changing if you are fetching the same exact results. This is because the comparison is shallow, and every time an array is created, it's a different object:

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

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

You would need to do deep equality checks for that.

Sign up to request clarification or add additional context in comments.

Comments

1

The issue is after you set state in useEffect, the people value will be changed which will trigger another useEffect call hence an infinite loop.

You can modify it to this:-

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

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

Comments

0

PROBLEM

useEffect runs every time when any one of values given to dependency array changes. Since, you're updating your people after the db call. The reference to array people changes, hence triggering an infinite loop on useEffect

SOLUTION

You do not need to put people in the dependency array. Your useEffect function doesn't depend on people.

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

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

Comments

-1

main problem is that the people array which is being created at every set-call is not the same. The object is completely different. I also had this trouble as i want to display the contents as soon as the some new "people" is added to the database from the admin panel, but it turns out that without refreshing this thing cannot be solved otherwise u can make your own hook with PROPER comparisons .

Maybe u can try by comparing the length of the PEOPLE array. I haven't tried it yet but i think it will work.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.