Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to persist redux state data in Next.js?

I've recently set up the redux with my Next.js project, now i'm dealing with persisting redux data, so that on every page refresh, i can have the persist state. So i've added redux-persist for handling this scenario as it's the best solution with react-redux, but I don't know why it's not working here in next.js with next-redux-wrapper or withRedux library too. So kindly help me with this issue, is there anything like redux-persist existed ?(I don't want cookie's solution though), if yes, then kindly suggest me the references with examples, it will be really helpful. Thanks in advance...

I was actually trying to persist the redux state after every page refreshes, so i have used redux-persist with next-redux-wrapper too, but i'm getting errors

/store.js

    import { createStore, applyMiddleware } from 'redux'
    import { composeWithDevTools } from 'redux-devtools-extension'
    import thunkMiddleware from 'redux-thunk'
    import { persistReducer } from 'redux-persist';
    import storage from 'redux-persist/lib/storage';

    const persistConfig = {
      timeout: 0,
      key: 'root',
      storage,
    };
    const persistedReducer = persistReducer(persistConfig, reducer);

    export default () => {
      return createStore(persistedReducer,
        composeWithDevTools(
          applyMiddleware(
            thunkMiddleware
          )
        ));
    };

/_app.js

    import App, { Container } from 'next/app'
    import React from 'react'
    import { Provider } from 'react-redux'
    import withRedux from 'next-redux-wrapper';
    import { PersistGate } from 'redux-persist/integration/react';
    import { persistStore } from 'redux-persist';
    import store from '../store';

    class MyApp extends App {
      static async getInitialProps ({Component, ctx}) {
        return {
          pageProps: (Component.getInitialProps ? await Component.getInitialProps(ctx) : {})
        };
      }

      render () {
        const { Component, pageProps, reduxStore } = this.props;
        const persistor = persistStore(store);
        return (
          <Container>
            <Provider store={store}>
            <PersistGate loading={null} persistor={persistor}>
                <Component {...pageProps} />
              </PersistGate>
            </Provider>
          </Container>
        )
      }
    }

I expect it will persist the state, but I'm getting error like this : "redux-persist failed to create sync storage. falling back to memory storage.TypeError: baseReducer is not a function"

like image 280
user8084720 Avatar asked Jan 04 '19 09:01

user8084720


People also ask

Can you use Redux with next JS?

Can I use Next. js with Redux? Yes! Here's an example with Redux and an example with thunk.


2 Answers

Create a your own storage.js file. Put the file in the main project folder. Use this code...

import createWebStorage from "redux-persist/lib/storage/createWebStorage";

const createNoopStorage = () => {
  return {
    getItem(_key) {
      return Promise.resolve(null);
    },
    setItem(_key, value) {
      return Promise.resolve(value);
    },
    removeItem(_key) {
      return Promise.resolve();
    },
  };
};

const storage = typeof window !== "undefined" ? createWebStorage("local") : createNoopStorage();

export default storage;

Go to the store.js file created in the Nextjs example. Replace the import storage from 'redux-persist/lib/storage' with import storage from './storage' to import the file you created instead.

like image 175
Aaron Tomlinson Avatar answered Nov 09 '22 10:11

Aaron Tomlinson


I can't see your reducer here, but I'm guessing you are not handling rehydrate case. In order to persist state on page refresh your reducer should handle REHYDRATE case. This is an example from my code:

const Account = (state= INIT_STATE, action) => {
    switch (action.type) {
    /// other cases here....
    case REHYDRATE:
        const rehydrated = (action && action.payload && action.payload.Account) || {}
        return { ...state, ...rehydrated }
    default: return { ...state };
like image 41
zoran jeremic Avatar answered Nov 09 '22 11:11

zoran jeremic