Home > front end >  It is ok to use useRef(), localStorage and useState() in order to keep state data after refreshing t
It is ok to use useRef(), localStorage and useState() in order to keep state data after refreshing t

Time:10-29

What I want to achieve, is to keep changes in the state between refresh. Now I think about this solution below, (using localStorage with useRef()) but I'm suspicious about it, it seems like it isn't technically correct, what do you think about that? It is useRef() supposed to be used for cases like this one, or maybe there are other more convenient solutions? It is supposed to not use any database. Is a little project, a movie app, not a prod or stuff like that, the 5mb from localStorage are pretty much enough.

State (fetched from the API)

 const [popularMovies, setPopularMovies] = useState(false);

Fetch Data for state

  function getPopularMoviesData() {
    const url =
      "https://api.themoviedb.org/3/movie/popular?api_key=60186105dc57d2473a4b079bdee2fa31&language=en-US&page=1";

    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setPopularMovies(data);
      })
      .catch((err) => console.error(err));
  }

  useEffect(() => {
    getPopularMoviesData();
  }, []);

useRef()

  const prevPopularMovies = useRef();

keep our previous data after each re-render

  useEffect(() => {
    prevPopularMovies.current = popularMovies;
    setPopularMovies(prevPopularMovies.current);
  });

localStorage for keeping data on refresh

useEffect(() => {
    const popularMoviesData = localStorage.getItem("popularMovies");

    if (popularMoviesData !== null) {
      setPopularMovies(JSON.parse(popularMoviesData));
    }
  }, []);

  useEffect(() => {
    localStorage.setItem("popularMovies", JSON.stringify(popularMovies));
  }, [popularMovies]);

CodePudding user response:

If the question is really just about persisting state through page reloads then all you really need is a state initializer function to initialize the state from localStorage, and the useEffect hook to save state updates to localStorage.

The useState hook will keep the popularMovies state value from render cycle to render cycle. There's nothing to worry about here as this is the default React state behavior, the state lives as long as the component is mounted.

Example:

const initializeState = () => {
  return JSON.parse(localStorage.getItem("popularMovies")) || [];
};

...

const [popularMovies, setPopularMovies] = useState(initializeState);

useEffect(() => {
  localStorage.setItem("popularMovies", JSON.stringify(popularMovies));
}, [popularMovies]);

CodePudding user response:

You can certainly do this as a way to cache state between reloads but ultimately this data can get lost if local storage is cleared on exit or for other reasons and so it is never a guarantee. One robust solution that attempts to solve this is immortal db. This package will sync state between localstorage, cookies and indexdb in attempt to have the data persist.

  • Related