2

So I was using redux-persist in my react-native app to persist the state and everything is working fine.

For the reducer, I was using switch-case to check for different action-types, and for the default, I was returning the state.

initialState = {
  first: null,
  second: null,
};

export default myReducer = (state = initialState, action) => {
  switch (action.type) {
    case ...:
            ... // Handling some cases which work fine
    default:
      return state;
  }
};

This thing is working fine but if I replace state with {...state} in the default block, it doesn't persist the state.

Now how much I had understood is state = {...state} so why is this not working.

Here is the persistConfig;

import AsyncStorage from "@react-native-async-storage/async-storage";
const persistConfig = {
  key: "root",
  storage: AsyncStorage,
};
diedu
  • 19,277
  • 4
  • 32
  • 49
Irfan wani
  • 4,084
  • 2
  • 19
  • 34
  • I haven't work on the persistence redux but in my understanding spreading the state object will create a new object and the redux compares the two objects and find something changed , so it keeps the new one. – Monty Tomar May 29 '21 at 05:03
  • So after keeping the new one why the data is getting deleted as the new one will include everything from the old state as i am just copying that. Please correct me if i am wrong. – Irfan wani May 29 '21 at 06:00
  • Maybe, there's something with your persistence config (the `persistConfig` object in lib's readme). Could you share it? – Parzh from Ukraine Sep 22 '21 at 09:27
  • What does the state become? undefined? – Adam Katz Sep 22 '21 at 20:39
  • @AdamKatz It is changed back to initialState – Irfan wani Sep 23 '21 at 01:28
  • @Irfanwani Far as my understanding If it run to default case I will return an identical state. I suspect It not run into default case – nart Sep 23 '21 at 03:12
  • Can you please explain the possible cases?? – Irfan wani Sep 23 '21 at 03:22
  • i just want to say, i didnt actually believe this so I tried replicating it in my project and I have the same result! this has nothing to do with anything external to what is in the question, very strange behaviour. – Adam Katz Sep 23 '21 at 12:22

1 Answers1

2

I'm not sure this is acceptable as an answer but maybe it will shed enough light to be useful. I did a bit of digging and this is what I Found.

  1. Its not just {..state} that changes the variable, any cloning does, for example Object.assign({}, state) also breaks the persisted state.
  2. Redux persist calls the reducer quite a few times on close and on open, most of these calls state is undefined and therefore defaults to initial state (you can see this by adding console.log(state) console.log(action) in the defaults
  3. My guess is that redux persist looks out for any changes between reassignment between the given state to the reducer and the output state of the reducer and if there is a reassignment it persists that value. If this is correct then when the state gets set to initial state on close of app it wont be logged by the persistor because there is no reassignment (if you return state) but it will get logged when you clone the state in your default {...state}
Adam Katz
  • 6,999
  • 11
  • 42
  • 74
  • 1
    I think this the right answer. How much i understood it is when i spread the state, as it creates a new object, on app reload, the redux checks for the default and as that is a new object, it updates the state but the state which we spreaded is not the persisted state but the initialState. But when we don't spread the state and simply return state, it doesnot mutate the state and simply returns it which is actually the persisted state. Still a little hard to understand. – Irfan wani Sep 24 '21 at 03:21