Why is local storage deleted when I refresh the page?

Viewed 4146

I have a reducer for state management at the context API. I was saving my Todos and it's happening successfully but when ı refresh the page all todos is deleting and just stay empty array.

// The relevant part in the reducer.
case "TODO_ADD_USER":
      return {
        ...state,
        users: action.payload,
      };
// Localstorage functions.
useEffect(() => {
    saveLocalTodos();
  }, [state]);

  useEffect(() => {
    const localTodos = getLocalTodos();
    dispatch({ type: "TODO_ADD_USER", payload: localTodos });
  }, []);

  const saveLocalTodos = () => {
    if (localStorage.getItem("users") === null) {
      localStorage.setItem("users", JSON.stringify([]));
    } else {
      localStorage.setItem("users", JSON.stringify(state.users));
    }
  };

  const getLocalTodos = () => {
    let locals;
    if (localStorage.getItem("users") === null) {
      locals = [];
    } else {
      locals = JSON.parse(localStorage.getItem("users"));
    }
    return locals;
  };
Place of keeping the state.
const users = {
  users: [],
};
1 Answers

There are a couple issues with your code.

The biggest one here is that you are saving the todos before getting them. So at the start of the application, things are getting reset, which is problematic.

Up next, you have your condition for the saving a bit backwards. You want to check if state.users === null and do a special action for that, rather than if localStorage.getItem("users") === null, as that will be null by default, and have nothing to do with the value in memory.

In fact, if the localStorage value is not null, but the state.users is, then it would set "null" to localStorage, which is less than ideal.

Here's the working code:

  useEffect(() => {
    // Get the item from local storage. JSON.parse(null) returns null rather than throws
    // Get from local storage before setting it
    const localTodos = JSON.parse(localStorage.getItem("users")) || [];
    dispatch({ type: "TODO_ADD_USER", payload: localTodos });
  }, []);

  useEffect(() => {
    // The conditions for this was wrong.
    // You want to check if `state.users` has a value
    // If it does, store! If not, don't store.
    // That way you don't reset data
    // In the case that you have this app running in two windows,
    // there's more that needs to be done for that.
    if (state.users) {
      localStorage.setItem("users", JSON.stringify(state.users || []));
    }
  }, [state]);

https://codesandbox.io/s/angry-glitter-9l10t?file=/src/App.js

Related