Reputation: 187
when Im using the useEffect hook with the setState hook, the state isn't updated if I only want the useEffect to run once (i.e. pass an empty array as the second parameter).
If i pass the array that Im updating as the second parameter, the state gets updated but then the useEffect keeps running in an infinite loop...
Here is the code that Im trying to run: In this example when printing out memes or endPage - they still hold their initial state values ([] and 0)
function ImageContainer() {
const [memes, setMemes] = useState([]);
const [currentIndex, setIndex] = useState(0);
const [currentPage, setPage] = useState(1);
const [endPage, setEndPage] = useState(0);
useEffect(() => {
getMemes(currentPage).then((data) => {
setEndPage(data.pagination.totalPages);
setMemes(data.data);
console.log(data);
console.log(memes);
console.log(endPage);
});
}, []);
but if I pass memes as the second parameter:
function ImageContainer() {
const [memes, setMemes] = useState([]);
const [currentIndex, setIndex] = useState(0);
const [currentPage, setPage] = useState(1);
const [endPage, setEndPage] = useState(0);
useEffect(() => {
getMemes(currentPage).then((data) => {
setEndPage(data.pagination.totalPages);
setMemes(data.data);
console.log(data);
console.log(memes);
console.log(endPage);
});
}, [memes]);
Then the console.log shows that both of the states have been updated, but the code keeps looping infinitely.
Thanks!
Upvotes: 0
Views: 357
Reputation: 66
It get stacked in infinite loop because the closure you passed to the function then set the state of memes, that trigger the useEffect hook, because it's listening the state of the property memes. You can pass currentPage in the array. Try using a loading state.
Upvotes: 0
Reputation: 39320
You needlessly create an infinite loop by adding memes to the effect dependency, log it in the component function instead:
useEffect(() => {
getMemes(currentPage).then((data) => {
setEndPage(data.pagination.totalPages);
setMemes(data.data);
console.log('api data:',data);
});
}, []);
console.log('memes:',memes);
console.log('end page:',endPage);
Upvotes: 0
Reputation: 647
Your state will get updated but the issue here is that you are checking for state updates by calling console.log(memes)
directly after setMemes(data.data)
, but the state of a component is updated asynchronously which means setMemes
is an asynchronous function.
If you want to do something with memes
(except updating it) after it has been updated use another useEffect
hook and define memes
as its dependency.
The infinite loop is happening because you are defining memes
as dependency of the useEffect
and also updating memes
inside the same effect. Therefore this useEffect
is constantly triggering itself.
Upvotes: 1