How can I persist redux state tree on refresh?
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.
--
Edit
It's been some time since I've revisited this question, but seeing that the other (albeit more upvoted answer) encourages rolling your own solution, I figured I'd answer this again.
As of this edit, both libraries have been updated within the last six months. My team has been using redux-persist in production for a few years now and have had no issues.
While it might seem like a simple problem, you'll quickly find that rolling your own solution will not only cause a maintenance burden, but result in bugs and performance issues. The first examples that come to mind are:
JSON.stringify
andJSON.parse
can not only hurt performance when not needed but throw errors that when unhandled in a critical piece of code like your redux store can crash your application.- (Partially mentioned in the answer below): Figuring out when and how to save and restore your app state is not a simple problem. Do it too often and you'll hurt performance. Not enough, or if the wrong parts of state are persisted, you may find yourself with more bugs. The libraries mentioned above are battle-tested in their approach and provide some pretty fool-proof ways of customizing their behavior.
- Part of the beauty of redux (especially in the React ecosystem) is its ability to be placed in multiple environments. As of this edit, redux-persist has 15 different storage implementations, including the awesome localForage library for web, as well as support for React Native, Electron, and Node.
To sum it up, for 3kB minified + gzipped (at the time of this edit) this is not a problem I would ask my team to solve itself.
React Redux state is lost at page refresh
You can easily persist it in the localstorage. Check the example below.
const loadState = () => {
try {
const serializedState = localStorage.getItem('state');
if(serializedState === null) {
return undefined;
}
return JSON.parse(serializedState);
} catch (e) {
return undefined;
}
};
const saveState = (state) => {
try {
const serializedState = JSON.stringify(state);
localStorage.setItem('state', serializedState);
} catch (e) {
// Ignore write errors;
}
};
const peristedState = loadState();
store.subscribe(() => {
saveState(store.getState());
});
const store = createStore(
persistedState,
// Others reducers...
);
render(
<Provider store={store}>
<App/>
</Provider>,
document.getElementById('root');
);
Serialization is an expensive operation. You should use a throttle function (like the one implemented by lodash
) to limit the number of saves.
Eg:
import throttle from 'lodash/throttle';
store.subscribe(throttle(() => {
saveState(store.getState());
}, 1000));
Related Topics
For Loop With Two Array in JavaScript
Why Flatlist Is Not Updating Dynamically in React Native
Why Is the Onclick Event Triggered Twice
Preventing Viewport Resize of Web Page When Android Soft Keyboard Is Active
How to Close Sweet Alert on Ajax Request Completion
React Typescript Is Not Assignable to Parameter of Type
Merge Array of Objects by Same Key-Value
React Enable Button After All Form Fields Are Not Empty
Angular2: Show Placeholder Image If Img Src Is Not Valid
How to Refresh the Data in a Jqgrid
Want to Show/Hide Div Based on Dropdown Box Selection
How to Make Autoplay of the Swiper Slider Start Only After the Slider Enters Viewport
Reactjs - Multiple If Conditions Inside Map Function
How to Refresh Specific Div Using Javascript/Jquery With the Variables on It
Disable Prev Control on First Slide and Disable Next Control on Last Slide
Get Part of the Url Pathname Via JavaScript Regex
Make Angular.Foreach Wait for Promise After Going to Next Object