I have a multi-step form application, and I'm struggling with getting my head around how I can save my redux state and replay it after a refresh for example? Going back/forward in the app works as expected, but after a browser refresh, my previous state is empty. Ideally I'd like to be able to save prior state in session storage relating to a path, so that I can replay later, but I'm not seeing how I can do that easily. Has anyone done anything like this and can provide some pointers? Thanks.
To maintain state after a page refresh in React, we can save the state in session storage. const Comp = () => { const [count, setCount] = useState(1); useEffect(() => { setCount(JSON. parse(window. sessionStorage.
When we refresh page in a web-app, the state always resets back to the initial values which in not a good thing when you try to build some large web-app like e-commerce. We can manually do the state persistent using the native JavaScript localStorage.
If you would like to persist your redux state across a browser refresh, it's best to do this using redux middleware. Check out the redux-persist and redux-storage middleware. They both try to accomplish the same task of storing your redux state so that it may be saved and loaded at will.
It looks like you're trying to use a single-page app framework within a multiple-page context. To make the two play nicer together, you could look into making your own middleware that synchronizes state to and from localStorage
to create an app that appears to not have lost any state after a refresh/page navigation.
localStorageLoad
) and end (localStorageDump
) of the createStoreWithMiddleware
function creation (right before redux-logger
):// store/configureStore.js
const createStoreWithMiddleware = applyMiddleware(
localStorageLoad, thunk, promise, localStorageDump, logger
)(createStore);
// index.js
const store = configureStore();
store.dispatch({ type: 'INIT' });
ReactDOM.render(<App />, document.getElementById('root'));
The localStorageLoad
would handle the INIT
action and dispatch some sort of SET_STATE
action, which would contain a payload with the state that was previously saved in localStorage
.
// middleware/localStorageLoad.js
export default store => next => action => {
const { type } = action;
if (type === 'INIT') {
try {
const storedState = JSON.parse(
localStorage.getItem('YOUR_APP_NAME')
);
if (storedState) {
store.dispatch({
type: 'RESET_STATE',
payload: storedState
});
}
return;
} catch (e) {
// Unable to load or parse stored state, proceed as usual
}
}
next(action);
}
Then, add a reducer which replaces the state with that payload, effectively rebooting the app as it was previously.
localStorageDump
middleware that comes at the end of the chain that saves each reduced state object into localStorage
. Something like this:// middleware/localStorageDump.js
export default store => next => action => {
const state = store.getState();
localStorage.setItem('YOUR_APP_NAME', JSON.stringify(state));
next(action);
}
Just an idea, haven't actually tried it. Hope that helps get you started towards a solution.
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