Search code examples
javascriptreactjsreduxreact-reduxredux-toolkit

Why my storage variable doesn't load when my functional component mounts?


I want to save my store(array of todos) in localStorage when my functional component unmounts. And when my component mounts (for example when App refreshes), it should read that variable from localStorage.

But why when I refresh the app, previous data doesn't load?

This is a part of my code:

function App() {

    const storeContents = useSelector(state => state.todo);
    const dispatch = useDispatch();

    useEffect(() => {
        const todos = localStorage.getItem("dd");
        if(todos){
            dispatch({type: "todos/loadTodos", payload: JSON.parse(todos)})
        }
        return () => {
            localStorage.setItem("dd", JSON.stringify(storeContents));
        }
        // eslint-disable-next-line
    },[])
.
.

My slice:

const todoSlice = createSlice({
    name: "todos",
    initialState: [],
    reducers: {
        loadTodos(state, action){
            return action.payload;
        },
.
.

I checked this question and used JSON.stringify and JSON.parse but it doesn't work again: React Redux Toolkit: How can I can store my initialState to localStorage using createSlice?

Link to complete code: https://github.com/arman-ebrahimi/TodosApp

Link to output: https://dapper-basbousa-c1c0e6.netlify.app/


Solution

  • Issue

    The only place you update the local storage is in App in that useEffect's clean-up function. The problem is that App will never be unmounted as it's your main component, and it's not rendered conditionally. When someone closes its tab or refreshes the page, you are not in React's component lifecycle anymore.

    Solution

    What you can do that would simplify your code is to change initialState in todoSlice to:

    initialState: localStorage.getItem("dd") ? JSON.parse(localStorage.getItem("dd")) : []
    

    Change your useEffect in App.js as below to update the localStorage after each change:

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