Search code examples
javascriptreactjsreduxredux-persist

Reducers are gone after attempting to implement redux-persist


I am attempting to implement redux-persist to persist a specific reducer only, invoices, version, but in my case, my reducers are all gone.

This is the entry point:

import React, { Component } from "react";
import { Provider } from "react-redux";
import { createStore, applyMiddleware, compose } from "redux";
import { persistStore, persistCombineReducers } from "redux-persist";
import { createWhitelistFilter } from "redux-persist-transform-filter";
import { PersistGate } from 'redux-persist/es/integration/react';
import storage from "redux-persist/lib/storage";
import thunkMiddleware from "redux-thunk";
import { apiMiddleware } from "redux-api-middleware";
import reducers from "./actions/reducers";
import AppContainer from "./containers/App";
import FlashMessage from "./containers/common/FlashMessage";
import "./App.css"

const middleware = [thunkMiddleware, apiMiddleware];

const persistConfig = {
  storage,
  key: 'root',
  transforms: [
    createWhitelistFilter('invoices')
  ]
};
const store = createStore(
  persistCombineReducers(persistConfig, reducers),
  compose(
    applyMiddleware(...middleware),
  )
);

const persistor = persistStore(store);

export default class App extends Component {
  render () {
    return (
      <Provider store={store}>
        <PersistGate persistor={persistor}>
          {/*<FlashMessage/>*/} // Since there is no reducer, this fails
          <AppContainer/>
        </PersistGate>
      </Provider>
    )
  }
}

And this is the reducers file I have:

import { combineReducers } from "redux";
import { routerReducer as router } from "react-router-redux";
import app from "./app";
import invoices from "./invoices/invoices";
import recipients from "./recipients/recipients";

export const makeRootReducer = (asyncReducers) => {
  return combineReducers({
    router,
    app,
    invoices,
    recipients,
    ...asyncReducers
  })
};

export const injectReducer = (store, { key, reducer }) => {
  store.asyncReducers[key] = reducer;
  store.replaceReducer(makeRootReducer(store.asyncReducers))
};

export default makeRootReducer;

I have followed many suggestions but I must be missing something.


Solution

  • I found out why. After checking the source code, I saw the following documentation block of persistCombineReducers:

    /**
         * It provides a way of combining the reducers, replacing redux's @see combineReducers
         * @param config persistence configuration
         * @param reducers set of keyed functions mapping to the application state
         * @returns reducer
         */
        export function persistCombineReducers<S>(config: PersistConfig, reducers: ReducersMapObject): Reducer<S & PersistedState>;
    

    The key words were "replacing redux's @see combineReducers".

    Removing combineReducers from my reducers file to the following solved the issue:

    import { routerReducer as router } from "react-router-redux";
    import app from "./app";
    import invoices from "./invoices/invoices";
    import recipients from "./recipients/recipients";
    
    const reducers = {
      router,
      app,
      invoices,
      recipients,
    };
    
    export default reducers;