Can't add new initial state
In development mode, if I want to add new state under whitelist. The new state I added doesn't appear. I need to clear the storage of my app in able to see the new state that I added. Is that normal or I got some mistake?
Example, I wanna add new initial state under user store
{
checkout: {
loading: false,
error: null
}
}
then even if I reload my app it doesn't appear when I call and when I check the checkout.
const checkout = useSelector((state) => state.user.checkout) undefined
So to make it appear on state.
1.) is I will remove the user store at whitelist then reload the app, then return it back to whitelist
2.) clear storage of the app
Here's how I config my store
import AsyncStorage from '@react-native-async-storage/async-storage'
import { combineReducers } from 'redux'
import {
persistReducer,
persistStore,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist'
import { configureStore } from '@reduxjs/toolkit'
import startup from './Startup'
import user from './User'
import theme from './Theme'
import utils from './Utils'
const reducers = combineReducers({
startup,
user,
theme,
utils,
})
const persistConfig = {
key: 'root',
storage: AsyncStorage,
whitelist: ['theme', 'user'],
}
const persistedReducer = persistReducer(persistConfig, reducers)
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) => {
const middlewares = getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
})
if (__DEV__ && !process.env.JEST_WORKER_ID) {
const createDebugger = require('redux-flipper').default
middlewares.push(createDebugger())
}
return middlewares
},
})
const persistor = persistStore(store)
export { store, persistor }
@rosnaib11 did you find any solution?
@manjuy124 No. What I did just separate my unnecessary states to other non-persisted modules. And add only those required state to whitelist such as token, userinfo.
having the same issue. this is kind of a problem in my opinion. what if i want to add new persisted states to my app i can't ask everybody who uses my app to clear their localstorage.
You can use Migrations for your use case - https://github.com/rt2zz/redux-persist/blob/master/docs/migrations.md
@parth-koshta i have used as provided in the link but still my new states are not being shown
@sameer0075 Did you update the version key in persistConfig to your latest migration key?
Thanks @parth-koshta for pointing us towards the migration example.
@rosnaib11 / @sameer0075 what worked for me was:
- I added the initialState
hanFontSize: 24in my slice - I did not manage to get it to work without
stateReconciler: autoMergeLevel2- maybe I was manually overwriting the state with a wrong format, but this works well for me. - https://github.com/rt2zz/redux-persist#state-reconciler a more conservative reconciler might work for you
After making changes to your migration code, bump the version by one.
import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2';
const migrations: any = {
0: (state: RootState) => {
// migration clear out device settings
return {
...state,
// settings: undefined
}
},
1: (state: RootState) => {
// migration to keep only device state
return {
settings: {
hanFontSize: 24
}
}
}
}
const persistConfig = {
key: "root",
version: 5,
storage: AsyncStorage,
blacklist: ['quiz'],
stateReconciler: autoMergeLevel2,
migrate: createMigrate(migrations, { debug: true }),
};
You can use migration, as described in this post
Or you can use transform
const persistConfig = {
key: 'your_key',
version: 1,
storage: AsyncStorage,
whitelist: ['your_reducer_1', 'your_reducer_2'],
transforms: [
createTransform(
// transform state on its way to being serialized and persisted.
(inboundState: RootState, key) => {
return inboundState;
},
// transform state being rehydrated
(outboundState: RootState, key) => {
switch (key) {
case 'your_reducer_1':
return { ...reducer1InitialState, ...outboundState };
case 'your_reducer_2':
return { ...reducer1InitialState, ...outboundState };
default:
return outboundState;
}
},
// define which reducers this transform gets called for.
{ whitelist: ['your_reducer_1', 'your_reducer_2'] },
),
],
};