rt2zz/redux-persist

Persist not working after page reload or refresh

kcibdev opened this issue · 4 comments

I was using react-toolkit but then decided to use redux-persist in order to persist my user reducer (ie my user data, like the access token and info), but when i added the redux persist and followed an online guide. t wasn't working as intended. even after reloading the page, the data still gets wiped out, Please how do i fix this issue?

I am using

"@reduxjs/toolkit": "^1.9.5",
"react-redux": "^8.1.1",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.4.2",

Am using next js, react js and typescript

My store.js

import { combineReducers, configureStore, Store } from "@reduxjs/toolkit";
import thunk from "redux-thunk";
import { createWrapper, HYDRATE } from "next-redux-wrapper";
import {
  persistStore,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from "redux-persist";

import authReducer from "./slices/authSlice";
import teamReducer from "./slices/teamSlice";
import testimonialReducer from "./slices/testimonialSlice";
import currencyReducer from "./slices/currencySlice";
import subscriptionReducer from "./slices/subscriptionSlice";
import exchangeReducer from "./slices/exchangeSlice";
import referralReducer from "./slices/referralSlice";
import notificationReducer from "./slices/notificationSlice";
import tradeReducer from "./slices/tradeSlice";
import userReducer from "./slices/userSlice";

import storage from "redux-persist/lib/storage"; // defaults to localStorage for web
import { persistReducer } from "redux-persist";

const combineReducer = combineReducers({
  auth: authReducer,
  team: teamReducer,
  testimonial: testimonialReducer,
  currency: currencyReducer,
  subscription: subscriptionReducer,
  exchange: exchangeReducer,
  user: userReducer,
  referral: referralReducer,
  notification: notificationReducer,
  trade: tradeReducer,
});

const persistConfig = {
  key: "root",
  storage,
  whitelist: ["user"],
};

const persistedUserReducer = persistReducer(persistConfig, combineReducer);

const makeStore = () =>
  configureStore({
    reducer: persistedUserReducer,
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware({
        serializableCheck: {
          ignoredActions: [
            FLUSH,
            REHYDRATE,
            PAUSE,
            PERSIST,
            PURGE,
            REGISTER,
            HYDRATE,
          ],
        },
      }).concat(thunk),
  });

const store = makeStore();

export const persistor = persistStore(store);

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

export const wrapper = createWrapper<Store>(makeStore, { debug: true });

my root app component _app.js

import type { AppProps } from "next/app";
import { Provider } from "react-redux";
import { persistor, wrapper } from "../redux/store";
import { AuthProvider } from "../context/AuthProvider";
import { PersistGate } from "redux-persist/integration/react";

export default function App({ Component, pageProps }: AppProps) {
  const { store, props } = wrapper.useWrappedStore(pageProps)
  return (
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <AuthProvider>
          <Layout isAuthenticated={false}>
            <Component {...props.pageProps} />
           </Layout>
        </AuthProvider>
      </PersistGate>
    </Provider>
  );
}

my userSlice.js

import { createSlice } from "@reduxjs/toolkit";
import type { PayloadAction } from "@reduxjs/toolkit";
import { User } from "../../types/user";

// Interface representing the state structure of the User slice
interface UserState {
  user: User; // Data representing the user's profile
  balance: string; // User's balance as a string (could be a number, but maintained as a string for precision)
  token: string; // user access token
  isLoading?: boolean; // A flag to indicate if user-related actions are in progress
}

// Initial state for the User slice
const initialState: UserState = {
  user: {}, // Initially, there is no user data, so an empty object is used
  balance: "", // Initial balance is set to ""
  token: "", // Initial token is set to ""
  isLoading: false, // Initially, there are no loading actions, so isLoading is set to false
};

// Create the User slice using createSlice from Redux Toolkit
export const userSlice = createSlice({
  name: "user", // Name of the slice, used as the prefix for action types
  initialState, // Initial state for the slice
  reducers: {
    setUser: (state, action: PayloadAction<User>) => {
      // Reducer to update the user data when the "setUser" action is dispatched
      state.user = action.payload;
    },
    setBalance: (state, action) => {
      // Reducer to update the user's balance when the "setBalance" action is dispatched
      state.balance = action.payload;
    },
  },
  extraReducers(builder) {},
});

// Export actions from the User slice
export const { setUser, setBalance } = userSlice.actions;

// Export the reducer function for the User slice to use in the Redux store
export default userSlice.reducer;

And then this is how i set my user


const dispatch = useDispatch<AppDispatch>()

 dispatch(setUser({
          ...userData,
          access_token: data.access_token
        }))

Please can someone tell me what's wrong or what am doing wrong
Thanks

I'm facing the same issue at the moment. Pretty much same stack and versions

I copied/pasted my redux implementation from a RN 0.72 project to a new RN 0.73 project and it's not working for me neither although it's working correctly on my RN 0.72 project.

im using a redux toolkit config store too.. not working for me too.. is there a bug in this new config store?

it worked after i removed whitelist, i did combined all reducers with persist ones