Home > Software engineering >  why my state in redux resets after page refresh
why my state in redux resets after page refresh

Time:07-13

created a state using redux-toolkit but right after i refresh page or go to another one the state resets. i've been broking my head for 4 hours, can't stand it anymore. there is code on github gists

Also here it is:

index.ts file: configuration of redux store

import { configureStore } from "@reduxjs/toolkit";
import authStateSlice from "redux/authStateSlice";
import deviceTypeReducer from "redux/deviceTypeSlice";
import userDataSlice from "redux/userDataSlice";

const store = configureStore({
  reducer: {
    isMobile: deviceTypeReducer,
    isLogin: authStateSlice,
    userData: userDataSlice,
  },
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

export default store;

signin.tsx: there i fetch data from a server and put it in my redux state:

import React, { useEffect, useState } from "react";
import { useAppSelector } from "lib";
import { useAppDispatch } from "../../lib/useAppDispatch";
import { userActionState } from "redux/userDataSlice";

export const SignIn: React.FC = () => {
  const { isUser } = useAppSelector((state) => state.userData);
  console.log("IS USER: ", isUser);
  const dispatch = useAppDispatch();

  const loginHandler = async () => {
    try {
      const response = await fetch(
        "...link to api",
        {
          method: "POST",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ email, password }),
        }
      );
      if (!response.ok) {
        const err = await response.json();
        throw new Error(err)
      }
      const data = await response.json();

      dispatch(userActionState({ isUser: true }));
    } catch (error) {
        throw new Error(err)
    }
  };

  return (
    <div>
      ...
    </div>
  );
};

userDataSlice.tsx: my user's data slice:

import { createSlice } from "@reduxjs/toolkit";
import { ResponseLoginDataType } from "@types";

const initialState: {
  isUser: boolean | undefined;
} = {
  isUser: undefined,
};

const userDataSlice = createSlice({
  name: "isUser",
  initialState,
  reducers: {
    userActionState(
      state,
      action: {
        payload: {
          isUser: boolean | undefined;
        };
      }
    ) {
      state.isUser = action.payload.isUser;
    },
  },
});

export default userDataSlice.reducer;
export const { userActionState } = userDataSlice.actions;

userInfo.tsx: there i tried to get that state, but it gives my default one:

import React, { useEffect, useState } from "react";
import { useAppSelector } from "lib";

export const UserInfo: React.FC<UserInfo> = ({
  name,
  nickname,
  picture,
  activity,
  active,
}) => {
  const { isUser } = useAppSelector((state) => state.userData);
  console.log("USER:: ", isUser);

  return (
    <>
     .....
    </>
  );
};

CodePudding user response:

Your Redux state doesn't persist to any non-volatile storage, such as local storage or cookies. redux-persist could be an option for you to keep your application's state.

This blog post might help: https://blog.logrocket.com/persist-state-redux-persist-redux-toolkit-react/

CodePudding user response:

When you refresh or leave page, you are restarting the redux store so it will always go back to the default. If you want to persist the store you will need to use a tool like redux-persist. Here is how you could setup your store with redux-persist.

One thing that is annoying is making sure your redux store persists nested objects, secondly since you are in typescript don't try to persist the root reducer.

import storage from "redux-persist/lib/storage";
import autoMergeLevel2 from "redux-persist/lib/stateReconciler/autoMergeLevel2";
import persistReducer from "redux-persist/es/persistReducer";
import persistStore from "redux-persist/es/persistStore";

const persistConfigOne = {
  key: "ex1",
  storage,
  stateReconciler: autoMergeLevel1, // Shallow level persisted objects
};
const persistConfigTwo = {
  key: "ex2",
  storage,
  stateReconciler: autoMergeLevel2, // This will persist deeper nested objects if needed.
};

//Can't get state typings if persisting root reducer. Persisted by reducer works.
const reducers = combineReducers({
  ex1: persistReducer<Ex1State, any>(persistConfigOne, ex1Reducer),
  ex2: persistReducer<Ex2State, any>(persistConfigTwo, ex2Reducer),
});

export const store = configureStore({
  reducer: reducers,
  devTools: process.env.NODE_ENV !== "production", // May want to add this for Redux Dev Tools
  middleware: [thunk], // Probably will need to use thunk at some point
});
  • Related