I am trying to add redux-persist with next.js using next-redux-wrapper, but storage is not updating, state is lost during page refresh,
Here is my store.ts file:-
import { createStore, applyMiddleware } from 'redux';
import { createWrapper } from 'next-redux-wrapper';
import storage from 'redux-persist/lib/storage';
import rootReducer from './rootReducer';
import { createLogger } from 'redux-logger'
import { persistStore, persistReducer } from 'redux-persist';
import { composeWithDevTools } from 'redux-devtools-extension';
const logger = createLogger();
// BINDING MIDDLEWARE
const bindMiddleware = (middleware) => {
if (process.env.NODE_ENV !== 'production') {
return composeWithDevTools(applyMiddleware(...middleware));
}
return applyMiddleware(...middleware);
};
const makeStore: any = ({ isServer }) => {
if (isServer) {
//If it's on server side, create a store
return createStore(rootReducer, bindMiddleware([logger]));
} else {
//If it's on client side, create a store which will persist
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store: any = createStore(
persistedReducer,
bindMiddleware([logger])
);
store.__persistor = persistStore(store);
return store;
}
};
export const wrapper = createWrapper(makeStore);
Here is my reducer.ts file:-
import {
LOGOUT,
LOGIN_ERROR,
LOGIN_SUCCESS,
} from "./actionTypes";
const initialState = {
userInfo: null,
accessToken: null,
loginError: false,
loading: true,
isLoggedIn: false
};
const authReducer = (state: any = initialState, action: any) => {
switch (action.type) {
case LOGIN_SUCCESS:
state = {
...state,
userInfo: action.payload.userInfo,
accessToken: action.payload.accessToken,
loading: false,
isLoggedIn: true
}
break;
case LOGIN_ERROR:
state = {
...state
}
break;
case LOGOUT:
state = {
...state,
userInfo: null,
accessToken: null,
loginError: false,
loading: false,
isLoggedIn: false
}
console.log(state);
break;
default:
state = {
...state,
};
break;
}
return state;
};
export default authReducer;
And my _app.tsx file:-
import type { AppProps } from "next/app";
import "../styles/reset.scss";
import Layout from "@/components/layout";
import { wrapper } from "../src/redux/store"
import { useStore } from "react-redux"
import { PersistGate } from "redux-persist/integration/react";
import { ApolloProvider } from "@apollo/client";
import { useApollo } from "../src/graphql/apollo/apollo";
import Loader from '@/components/Loader'
function MyApp({ Component, pageProps }: AppProps) {
const apolloClient = useApollo(pageProps.initialApolloState);
const store: any = useStore();
return (
<ApolloProvider client={apolloClient}>
<PersistGate persistor={store.__persistor} loading={<div>Loading</div>}>
<Layout>
<Loader />
<Component {...pageProps} />
</Layout>
</PersistGate>
</ApolloProvider>
);
}
export default wrapper.withRedux(MyApp);
Is there need to hand persist/REHYDRATE action in reducer file?, I am checking the persist/REHYDRATE action but payload is undefined on that action.
I found the solution, Here is my store.ts file
import { createStore, applyMiddleware } from 'redux';
import { createWrapper } from 'next-redux-wrapper';
import storage from 'redux-persist/lib/storage';
import rootReducer from './rootReducer';
import rootSaga from './rootSaga'
import { createLogger } from 'redux-logger'
import { persistStore, persistReducer } from 'redux-persist';
import { composeWithDevTools } from 'redux-devtools-extension';
import createSagaMiddleware from "redux-saga";
const logger = createLogger();
const sagaMiddleware = createSagaMiddleware();
// BINDING MIDDLEWARE
const bindMiddleware = (middleware) => {
if (process.env.NODE_ENV !== 'production') {
return composeWithDevTools(applyMiddleware(...middleware));
}
return applyMiddleware(...middleware);
};
const makeStore: any = ({ isServer }) => {
if (isServer) {
//If it's on server side, create a store
return createStore(rootReducer, bindMiddleware([logger]));
// return createStore(rootReducer, bindMiddleware([]));
} else {
//If it's on client side, create a store which will persist
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store: any = createStore(
persistedReducer,
bindMiddleware([logger, sagaMiddleware])
// bindMiddleware([sagaMiddleware])
);
store.__persistor = persistStore(store);
sagaMiddleware.run(rootSaga);
return store;
}
};
export const wrapper = createWrapper(makeStore);
and here is my _app.tsx file:-
import type { AppProps } from "next/app";
import "../styles/reset.scss";
import Layout from "@/components/layout";
import { wrapper } from "@/redux/store";
import { useStore } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { ApolloProvider } from "@apollo/client";
import { useApollo } from "@/graphql/apollo/apollo";
import Head from "next/head";
import SimpleReactLightbox from "simple-react-lightbox";
function MyApp({ Component, pageProps }: AppProps) {
const apolloClient = useApollo(pageProps.initialApolloState);
const store: any = useStore();
return (
<ApolloProvider client={apolloClient}>
<PersistGate persistor={store.__persistor} loading={null}>
<SimpleReactLightbox>
<Layout>
<Head>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0"
/>
</Head>
<Component {...pageProps} />
</Layout>
</SimpleReactLightbox>
</PersistGate>
</ApolloProvider>
);
}
export default wrapper.withRedux(MyApp);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.