redux persist not storing store in the async storage

1.9k Views Asked by At

Note- If you want to summarize my question, then I would say that I have 5 reducers. Only 2 of them are being persisted while 3 are not.

My redux-persist version is 6.0.0. Now I come to my problem. My react-native app is fetching data from json-server and storing it in redux-store. redux-store in turn stores it in AsyncStorage as I have printed the content of storage in my code. No problem till now.

But now I turn off my json-server and exit my app on my android device to test redux-persist( I don't recompile it, I just exit it). As I open it again, redux, instead of looking in AsyncStorage, it again tries to contact json-server to fetch the data( rather it should look into the asyncstorage). Now since the server is not running, the app cannot fetch data and writes an error message into the state( as I have configured it like that way). So, AsyncStorage again gets emptied and the application renders nothing. Now I present you the code of configureStore.js:


import {createStore, applyMiddleware} from 'redux';
import { dishes } from './dishes';
import { comments } from './comments';
import { promotions } from './promotions';
import { leaders } from './leaders';
import { favorite } from './favorite.js';
import thunk from 'redux-thunk';
import { logger } from "redux-logger";
import { persistStore, persistCombineReducers } from 'redux-persist';
import AsyncStorage from '@react-native-community/async-storage';

const config = {
    key: 'root',
    storage: AsyncStorage,
    debug: true
  }

export const ConfigureStore = () => {
    const store = createStore(
        persistCombineReducers(config,{
            dishes,
            comments,
            promotions,
            leaders,
            favorite
        }),
        applyMiddleware(thunk, logger)
    );

    const persistor = persistStore(store)
    return {persistor, store};
}

Below is App.js:


import React from 'react';
import Main from './components/MainComponent';
import { Provider } from 'react-redux';
import { ConfigureStore } from './redux/configureStore';
import { PersistGate } from 'redux-persist/es/integration/react'
import  Loading  from './components/LoadingComponent';

const { persistor, store } = ConfigureStore();
//const store=ConfigureStore();


class App extends React.Component{
  
  render(){
    return (
      <Provider store={store}>
        <PersistGate 
          loading={<Loading />}
          persistor={persistor}>
          <Main /></PersistGate>
      </Provider>
  );
}
};

export default App;

One other strange thing that I must tell you is that out of 5 reducers, only comments and favorites are the two reducers whose data is being persisted even after app restart and I also have not made it any different from other 3.

Below is comments.js reducer:

import * as ActionTypes from './ActionTypes';

export const comments = (state = { errMess: null, comments:[]}, action) => {
  switch (action.type) {
    case ActionTypes.ADD_COMMENTS:
      return {...state, errMess: null, comments: action.payload};

    case ActionTypes.COMMENTS_FAILED:
      return {...state, errMess: action.payload};

    case ActionTypes.ADD_COMMENT:
      {action.payload.id=state.comments.length;console.log("hello from reducer",action.payload);return {...state,comments: [...state.comments,action.payload]}}

    default:
      return state;
  }
};

Below is dishes.js:

import * as ActionTypes from './ActionTypes';


export const dishes = (state = { isLoading: true,
                                 errMess: null,
                                 dishes:[]}, action) => {
    switch (action.type) {
        
        case ActionTypes.ADD_DISHES:
            return {...state, isLoading: false, errMess: null, dishes: action.payload};

        case ActionTypes.DISHES_LOADING:
            return {...state, isLoading: true, errMess: null, dishes: []}

        case ActionTypes.DISHES_FAILED:
            return {...state, isLoading: false, errMess: action.payload};

        default:
          return state;
      }
};
2

There are 2 best solutions below

0
On
  • List item

After scratching my head for nearly a day, only one switch case in all reducers is causing problem. That case is LOADING case. I made my dishes.js reducer like this:

import * as ActionTypes from './ActionTypes';


export const dishes = (state = { isLoading: true,
                                 errMess: null,
                                 dishes:[]}, action) => {
    switch (action.type) {
        
        case ActionTypes.ADD_DISHES:
            return {...state, isLoading: false, errMess: null, dishes: action.payload};

        
        case ActionTypes.DISHES_FAILED:
            return {...state, isLoading: false, errMess: action.payload};

        default:
          return state;
      }
};

I changed other reducers in the same way and everything started working like a charm!!

13
On

I suggest using a whitelist and blacklist.

const persistConfig = {
  key: 'root',
  storage: storage,
  blacklist: ['navigation'] // navigation will not be persisted
};
 
// WHITELIST
const persistConfig = {
  key: 'root',
  storage: storage,
  whitelist: ['navigation'] // only navigation will be persisted
};

Try This Way :

const persistConfig = {
    key: 'root',
    storage: AsyncStorage,
    whitelist: ["dishes, comments, promotions, leader, favorite"]
  }

const rootReducer = combineReducers({
    dishes: dishes,
    comments: comments,
    promotions: promotions,
    leaders: leaders,
    favorite: favorite
});

const persistReducer = persistReducer(persistConfig, rootReducer);

const store = createStore(persistReducer,  applyMiddleware(thunk));

let persistor = persistStore(store);

export {store, persistor};