I'm trying to access the latest state in other setState function, cant figure out the correct way of doing it for a functional component
without accessing the latest state setMoviesList
set state as undefined and causes issues
state
const [movies, setMoviesList] = useState();
const [currentGenre, setcurrentGenre] = useState();
const [page, setPage] = useState(1);
const [genreList, setGenreList] = useState();
const [nextPage, setNextPage] = useState(false);
const [previousMovieList, setPreviousMovieList] = useState();
useEffect(() => {
async function getMovies(currentGenre, page) {
if (currentGenre) {
const data = await rawAxios.get(
`https://api.themoviedb.org/3/discover/movie?api_key=f4872214e631fc876cb43e6e30b7e731&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}&with_genres=${currentGenre}`
);
setPreviousMovieList((previousMovieList) => {
if (!previousMovieList) return [data.data];
else {
if (nextPage) {
console.log(previousMovieList);
setNextPage(false);
return [...previousMovieList, data.data];
}
}
});
setMoviesList(previousMovieList.results);
} else {
const data = await rawAxios.get(
`https://api.themoviedb.org/3/discover/movie?api_key=f4872214e631fc876cb43e6e30b7e731&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}`
);
if (!previousMovieList) {
console.log('!previousMovieList', previousMovieList);
console.log('!data', data.data);
setPreviousMovieList(previousMovieList)
} else {
if (nextPage) {
console.log('else', previousMovieList);
setNextPage(false);
setPreviousMovieList([...previousMovieList, data.data])
// return [...previousMovieList, data.data];
}
}
setMoviesList(previousMovieList.results);
}
}
getMovies(currentGenre, page);
}, [currentGenre, page, setMoviesList, nextPage]);
want to access latest previousMovieList
here
setMoviesList(previousMovieList.results);
CodePudding user response:
You need to include previousMovieList
in your useEffect
dependency array as follows:
useEffect(()=>
{...},
[currentGenre, page, setMoviesList, nextPage, previousMovieList]
);
Without including it, you will have a stale closure and latest value will not be reflected in your function. This is causing the initial previousMovieList
value of undefined
to never update within your useEffect logic.
If you dont want it in your useEffect
deps, you can use a ref:
const previousMovieList = useRef();
//then in your useEffect
setMoviesList(previousMovieList.current.results)
//and to set it
previousMovieList.current = ... // whatever you want to store
Or you can do something like this:
setPreviousMovieList((previousMovieList) => {
if (!previousMovieList) return [data.data];
else {
if (nextPage) {
console.log(previousMovieList);
setNextPage(false);
return [...previousMovieList, data.data];
}
}
setMoviesList(previousMovieList.results);
});
Basically move setMoviesList
to within the setPreviousMovieList function where you do have access to previousMovieList
.
Kind of hard to tell what you're trying to do, but generally when you want to store the previous value of state, you would use the ref
approach. Like usePrevious for example
CodePudding user response:
you can use optional chaining to access the data coming from the api
enter code here
const [movies, setMoviesList] = useState();
const [currentGenre, setcurrentGenre] = useState();
const [page, setPage] = useState(1);
const [genreList, setGenreList] = useState();
const [nextPage, setNextPage] = useState(false);
const [previousMovieList, setPreviousMovieList] = useState();
useEffect(() => {
async function getMovies(currentGenre, page) {
if (currentGenre) {
const data = await rawAxios.get(
`https://api.themoviedb.org/3/discover/movie?api_key=f4872214e631fc876cb43e6e30b7e731&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}&with_genres=${currentGenre}`
);
setPreviousMovieList((previousMovieList) => {
if (!previousMovieList) return [data?.data];
else {
if (nextPage) {
console.log(previousMovieList);
setNextPage(false);
return [...previousMovieList, data?.data];
}
}
});
setMoviesList(previousMovieList?.results);
} else {
const data = await rawAxios.get(
`https://api.themoviedb.org/3/discover/movie?api_key=f4872214e631fc876cb43e6e30b7e731&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=${page}`
);
if (!previousMovieList) {
console.log('!previousMovieList', previousMovieList);
console.log('!data', data?.data);
setPreviousMovieList(previousMovieList)
} else {
if (nextPage) {
console.log('else', previousMovieList);
setNextPage(false);
setPreviousMovieList([...previousMovieList, data?.data])
// return [...previousMovieList, data?.data];
}
}
setMoviesList(previousMovieList.results);
}
}
getMovies(currentGenre, page);
}, [currentGenre, page, setMoviesList, nextPage]);