How to set up redux-persist with middlewares properly?

525 Views Asked by At

I am new to react and redux. I am trying to apply redux-persist to my web but I got these two errors. Can't found what really make the errors. Need some help to fix this. Any help is highly appreciated!

1) Warning: Failed prop type: Invalid prop `store` of type `function` supplied to `Provider`, expected `object`.

2) Uncaught TypeError: store.getState is not a function

In my Store.js,

import { composeWithDevTools } from 'redux-devtools-extension';
import { createStore, applyMiddleware } from 'redux';
import { persistStore } from 'redux-persist';
import { persistedReducer } from './root-reducer';
import thunk from 'redux-thunk';
import logger from 'redux-logger';


const middlewares = [thunk, logger];

export default () => {
    let store = createStore(persistedReducer, composeWithDevTools(
        applyMiddleware(...middlewares),
    ));
    let persistor = persistStore(store)
    return { store, persistor }
}

In my root-reducer.js

import { combineReducers } from 'redux';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';

import userReducer from './User/User.reducer.jsx';

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

const rootReducer = combineReducers({
    user: userReducer,
});

export const persistedReducer = persistReducer(persistConfig, rootReducer);

In my Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

import { Provider } from 'react-redux';
import store from './redux/store';
import { PersistGate } from 'redux-persist/integration/react';
import persistor from './redux/store';

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <BrowserRouter>
        <App />
      </BrowserRouter>
   </PersistGate>
  </Provider>
  ,
  document.getElementById('root')
);
2

There are 2 best solutions below

1
On

In your store.js you exporting function, so you should call that funcation in Index.js, or export object from store.js (by calling the function inside).

So it either:

Store.js:

...
export default (() => {
    let store = createStore(persistedReducer, composeWithDevTools(
        applyMiddleware(...middlewares),
    ));
    let persistor = persistStore(store)
    return { store, persistor }
})();

Or Index.js:

<Provider store={store()}>

In case if you use Index.js option then probably you should import store as getStore, will make more sense.

0
On

I figure it out finally and revise a bit.

In my store.js,

import { composeWithDevTools } from 'redux-devtools-extension';

import { createStore, applyMiddleware, compose } from 'redux';
import { persistStore } from 'redux-persist';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';

import thunk from 'redux-thunk';
import logger from 'redux-logger';

import rootReducer from './root-reducer';

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

const middlewares = [thunk, logger];

const enhancer = compose(
    composeWithDevTools(
        applyMiddleware(...middlewares),
    )
);

const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer,
    enhancer
);
const persistor = persistStore(store);
export { persistor, store };

In my root-reducer.js,

import { combineReducers } from 'redux';
import userReducer from './User/User.reducer.jsx';

const rootReducer = combineReducers({
    user: userReducer,
});

export default rootReducer;

In my Index.js,

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { persistor, store } from './redux/storeUpdated';

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
        <BrowserRouter>
          <App />
        </BrowserRouter>
    </PersistGate>
  </Provider>
  ,
  document.getElementById('root')
);