Home > front end >  how do I access lates state in `setMoviesList()`
how do I access lates state in `setMoviesList()`

Time:10-24

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 setMoviesListset 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]);
  • Related