Search code examples
react-nativereact-reduxredux-persist

Access the datas in redux-persist (react native)


I am a newbie in react-redux. I am trying a Todo app using redux. Here I need to store the data and show them as soon as the app opens, for which redux-persist is used. And it works fine. The one where I am stuck is in action. I have initialized id = 0 here. Hence every time app opens, it stores the data from id = 0 and then increments. How can I refer to the last id stored from persist and use it when the new data is added?

App.js

export const persistor = persistStore(store);

class App extends Component<Props> {
  render() {
    return (
      <Provider store={store}>
        <PersistGate loading={<ActivityIndicator />} persistor={persistor}>
          <ToDoApp />
        </PersistGate>
      </Provider>
    );
  }
}

store

const persistConfig = {
     key: 'root',
     storage,
     stateReconciler: autoMergeLevel2 
};

const pReducer = persistReducer(persistConfig, rootReducer);

export default (store = createStore(pReducer));

action

import { ADD_TODO, TOGGLE_TODO } from './actionTypes';

let nextId = 0; // how to initialize nextId as the last id from persisted data?
export const addToDoo = text => ({
  type: ADD_TODO,
  id: nextId++,
  text
});

export const toggleTodo = id => ({
  type: TOGGLE_TODO,
  id
});

Solution

  • I have not used redux-persist so far, I'm using this technique but that is off-topic, your problem is only related to redux.

    It's not the job of an action creator to assign an id to a new todo, it's the reducer's job. Your action could look like:

    const addTodo = text => ({
      type: ADD_TODO,
      text,
    })
    

    That's in the reducer that must reside nextId. At startup (or page reload), it will be 0 or the value stored in localStorage. There it will increment every time an ADD_TODO action comes up:

    const initialState = {
      nextId: 0,
    }
    
    const reducer = (state = initialState, action) => {
      switch (action.type) {
        case 'ADD_TODO':
          //...
        case 'TOGGLE_TODO':
          //...
        default:
          return state
      }
    }
    

    I see redux-persist does all the magic of serializing the state to storage (localStorage for browser and AsyncStorage for React-Native) and retrieving it at startup. For reference, that is what I would do for a pure React App (the old way with localStorage):

    • In the root index.js, after the createStore, I to get the value from storage: const nextIdFromLS = storage.getItem("nextId")
    • if this value exists, I fire an action to set this nextId value store.dispatch(setNextId(nextIdFromLS))
    • the action SET_NEXT_ID makes the reducer update the state with the nextId from localStorage
    • next time a todo is added, inside the case "ADD_TODO":, I would store the new todo as expected but I would also run localStorage.setItem("nextId", this.state.nextId++) so that we have the value stored and we can refresh the page