I'm having trouble accessing saved data after app starts with redux-persist.
The reducer initializes with data defined in my initial state. By the time the previous session's state loads with AsyncStorage, the component is already displayed with the default data.
I know that the data is saved and fetched successfully. If I leave the screen to a different one and come back to it, I can see that the data is displayed correctly. Debugging the state and props also shows that this is a async timing issue.
How can I delay the loading of the redux containers to after the store rehydrates. Alternatively, can I force update the conatainer (and its children) to update when the store finishes loading?
Here is what I've tried. to configure my store:
export default function configureStore(initialState) {
const middlewares = [thunk];
if (process.env.NODE_ENV === `development`) {
const createLogger = require(`redux-logger`);
const logger = createLogger();
middlewares.push(logger);
}
let store = compose(
applyMiddleware(...middlewares),
autoRehydrate() )(createStore)(reducers);
persistStore(store, {blacklist: ['routing'], storage: AsyncStorage}, () => {
store.dispatch(storeRehydrateComplete())
})
return store
}
Hoping that this will update all other components (since all reducers in redux are called in an action), I've tried creating an action that triggers when the store finishes loading:
import { REHYDRATE_STORE } from './types'
export function storeRehydrateComplete(){
return {
type: REHYDRATE_STORE,
}
}
And it's reducer: import { REHYDRATE_STORE } from '../actions/types' const initialState = { storeIsReady: false }
export default function reducer(state = initialState, action){
switch (action.type) {
case REHYDRATE_STORE:
return {...state, storeIsReady:true}
break;
default:
return state
break;
}
}
But although the storeIsReady state changes to true when rehydration is complete, I'm still couldn't figure out how to force update the container component.
The state that we use inside redux as a store can only be modified with the help of the actions. But, this state must be specified somewhere first to use it. We prefer to declare our initial state at the reducer files. Then we use that reducer in the store and provide that store use inside the whole application.
With the Redux Persist library, developers can save the Redux store in persistent storage, for example, the local storage. Therefore, even after refreshing the browser, the site state will still be preserved.
You can set it at the reducers . Reducers can also set initialState by looking at the incoming state argument (which would be undefined if createStore is not called with initialState ) and returning the values they would like to use as default.
I solved it by following this recipe: delay-render-until-rehydration-complete
Basically the solution is as follows:
In the component that wraps <Provider>
, create a local state flag that tracks whether the store has rehydrated yet or not. Using the callback of persistStore() to update this flag.
In the render function of this wrapper, if the flag is true, render <Provider>
, otherwise, render some temporary view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With