4

I am trying to persist my state using redux-persist API. I have my state structure as below.

var initState = {
  searchInp: "",
  allProducts: {},
  isProductDtlsLoading: true
};

Where allProducts is a nested objects array with each object structure as below :

allProducts : {
004: {
   defaultOffer: null
   mrp: 550
   productData: [{…}]
   productName: "Hair Dryer"
   productQty: 0
   sellingPrice: 450
   prodCode: "004"
   }
}

Now when I try to persist the data, I can see that Chrome Developer Tools in Application tab, the value for searchInp persists fine and is not lost due to page refresh. Value for allProducts is updated fine in the persisted store but then when refreshed the value gets lost and let's say productQty defaults to 0. How can I persist nested object properties like productQty in this case?

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import * as serviceWorker from "./serviceWorker";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import rootReducer from "./Store/Reducers/reducer";
import thunk from "redux-thunk";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/es/storage/session";
import { PersistGate } from "redux-persist/lib/integration/react";
import hardSet from "redux-persist/lib/stateReconciler/hardSet";

const persistConfig = {
  key: "root",
  storage: storage,
  stateReconciler: hardSet
};

var pReducer = persistReducer(persistConfig, rootReducer);

var store = createStore(pReducer, applyMiddleware(thunk));
var persistor = persistStore(store);

var app = (
  <Provider store={store}>
    <PersistGate persistor={persistor} loading={null}>
      <App />
    </PersistGate>
  </Provider>
);

ReactDOM.render(app, document.getElementById("root"));
Shantanu Tomar
  • 1,572
  • 7
  • 38
  • 64
  • I have pretty complex state in my app and this way works for me fine: https://stackoverflow.com/a/37690899/7317796 –  Nov 13 '18 at 08:05

2 Answers2

3

I recently released an open-source package called Redux Deep Persist, which can be very helpful in creating Redux Persist config for nested state no matter how deep it is. It can help you in this specific situation.

Here is what your config would look like:

import { getPersistConfig } from 'redux-deep-persist';
import storage from "redux-persist/es/storage/session";

const config = getPersistConfig({
    key: 'root',
    storage,
    whitelist: [
        'allProducts.004.productQty', 
        'allProducts.004.productData.0', // even specific indexes of arrays can be saved
    ],
    rootReducer, // your root reducer must be also passed here
    ... // any other props from the original redux-persist config omitting the stateReconciler
})

You can read more in the official documentation of redux-deep-persist https://github.com/PiotrKujawa/redux-deep-persist/blob/master/README.md

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
0

Most probably you're mutating your state instead of replacing with new one. redux-persist relies on the fact that the state is immutable and it should persist the changes correctly unless they have been mutated, see some discussion here https://github.com/rt2zz/redux-persist/issues/623. So make sure your correctly updating your state and with nested objects it can be tricky, here is some info on that Cleaner/shorter way to update nested state in Redux?

ddavydov
  • 66
  • 3