Skip to content

Instantly share code, notes, and snippets.

@vre2h
Last active November 12, 2020 18:19
Show Gist options
  • Save vre2h/d620ad389580e788b7482245fa62b06c to your computer and use it in GitHub Desktop.
Save vre2h/d620ad389580e788b7482245fa62b06c to your computer and use it in GitHub Desktop.
How to configure Store and use localStorage with react and redux.
import { createStore } from 'redux'
import throttle from 'lodash/throttle'
import rootReducer from './reducer';
import { loadState, saveState } from './localStorage'
const configureStore = () => {
const persistedState = loadState();
const store = createStore(rootReducer, persistedState);
store.subscribe(throttle(() => {
saveState({
todos: store.getState().todos
})
}, 1000))
return store
}
export default configureStore
import React from 'react'
import { render } from 'react-dom'
import Root from './components/Root'
import configureStore from './configureStore'
const store = configureStore();
render(
<Root store={store} />,
document.getElementById('root')
);
export const loadState = stateName => {
try {
const serializedState = localStorage.getItem(stateName);
if (serializedState === null) {
return undefined;
}
return JSON.parse(serializedState);
} catch (err) {
return undefined;
}
};
export const saveState = (state, stateName) => {
try {
const serializedState = JSON.stringify(state);
localStorage.setItem(stateName, serializedState);
} catch (err) {
throw new Error("Can't save changes in local storage");
}
};
  1. You must understand that if save state to the localStorage is an expensive so if your storage changing often you should think about performance. So I recommend to use lodash's throttle which won't allow launch your function if it's called more often than number in ms that you've given as second argument.

You should install lodash via ``yarn:

  yarn add lodash
  • Or npm
  npm i --save lodash
  1. Note that you should wrap your calls to localStorage in try/catch because if user's browser doesn't allow caching in localStorage it will give an error and in this case you should return current state.

  2. We add Root component because it helps to keep clean index.js and later if we need to add other wrapping components like Router, it will be easy to do.

import React from 'react';
import { Provider } from 'react-redux';
import { PropTypes } from 'prop-types';
import App from './App';
const Root = ({ store }) => (
<Provider store={store}>
<App />
</Provider>
);
Root.propTypes = {
store: PropTypes.object.isRequired,
};
export default Root;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment