Stack Overflow Asked by Leo S on January 18, 2021
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>
)
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
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()
}
}, [])
Correct answer by Prateek Thapa on January 18, 2021
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.
Answered by hopper01 on January 18, 2021
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.
Answered by Yuan-Hao Chiang on January 18, 2021
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()
}
}, [])
Answered by maya_nk99 on January 18, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP