When my app crashes, I want to clear the data persisted in storage, thus when user re-open the application, which will trigger the Rehydrate, will update the redux store to be default values and the user can continue to use the app ( avoiding the error component, of course )
So I put persistor.purge() in the ErrorUtils.globalHandler of React Native, but when the Rehydrate happens, the data passed along the redux action still has the old data before crashing
I tried to use redux-reset right after the persistor.purge() and now the Rehydrates only passes the default values.
The question is that: What does the persistor.purge() then ?
After doing some tests and check, I found the following:
the purge() seems really not clearing any data, even at the storage itself.
I am using AsyncStorage and the way I check the data is following the guide here
So after a crash happens, I am sure that the purge() is called as I log something in the callback of it ( I am trying to purge 3 keys, it returns 3 nulls in callback ).
However, when I check the AsyncStorage, the content of the storage is still the same. If I try to execute AsyncStorage.clear(), then all keys are deleted and the storage is indeed empty.
Is it a problem of using the AsyncStorage ? I haven't test with other storage type and only tested in Android device
I finally found out the problem!
To make things simple, let's make some assumptions:
When an error happens, the order of call is:
Since both calls above will trigger promise / async actions, we cannot make sure who will finish first. However, most of the time, the purge will finish first, while the nav state change second.
This scenario will lead to:
That's why it creates "illusion" that the purge is not working ( for auth key ).
To handle this situation, just need to reset the redux state in the global error handler.
Sorry for the confusion in this issue, this can be closed now :)
@williamliangwl I have the same problem. I try to reset my state from a custom action, but only works for some reducers.
const appReducer = combineReducers({
plans,
contracts,
user,
appState
})
const rootReducer = (state, action) => {
console.log("STATE", state)
if (action.type === 'RESET') {
state = undefined
}
return appReducer(state, action)
}
export default rootReducer
I also tried to reset the state passing the default values, without exit
//Action
export const clearPlans = function () {
return {
type: CLEAR_PLANS,
payload: []
}
}
//Reducer
const initialState = {
plans: [],
persistExpiresAt: DATA_EXPIRES_AT,
};
const plans = (state = initialState, action) => {
switch(action.type) {
case FETCH_PLANS:
console.log(action.payload)
return {...state,
plans: action.payload
}
case CLEAR_PLANS:
console.log(action.payload)
return {...state,
plans: action.payload
}
default:
return state
}
}
How did you handle the redux state? Thank you in advance
@ronnierios to reset all my redux states, I simply use the redux-reset here.
Actually I am still new in React Native and Redux, so I don't really understand what the following code does
const rootReducer = (state, action) => {
console.log("STATE", state)
if (action.type === 'RESET') {
state = undefined
}
return appReducer(state, action)
}
However, I think if we just want to reset all redux states to its initial state, we can simply use the redux-reset.
If we only want to reset some of them, then may be it's better to implement the reset in each reducers, by "listening" to the same action.type. Another way to do this, you can also use the redux-reset, but on those reducers that don't want to be reset, just return the current state.
Ran into the same issue. The solution suggested here is to wipe your own state and have redux-persist persist the wiped state, which means this is a workaround as it doesnt require you to call persistor.purge at all.
Hi @williamliangwl ,
Using redux-reset just make your store clean in the current browser tab.
If you open another tab, all state persisted there.
Do you have any solution to purge the persistor so far.
Regards,
Hi @vinhphamthanh, to be honest I have never implemented redux in web, so I might not have good answer to your problem
But after skimming this link, it looks like you can store the redux to the localStorage which can be synced across tabs
Most helpful comment
@ronnierios to reset all my redux states, I simply use the redux-reset here.
Actually I am still new in React Native and Redux, so I don't really understand what the following code does
However, I think if we just want to reset all redux states to its initial state, we can simply use the redux-reset.
If we only want to reset some of them, then may be it's better to implement the reset in each reducers, by "listening" to the same action.type. Another way to do this, you can also use the redux-reset, but on those reducers that don't want to be reset, just return the current state.