Saving Redux State to Local Storage
In this video we are going to look at problem that is inherent in any Redux project, which is that by default, your application's state
will not persist past a browser refresh.
To remedy this, we will save our application's local representation of state
to localStorage
.
By using localStorage
, our locally saved state
will survive even if the browser window is closed. If you'd rather only keep data alive as long as the browser window is kept open then sessionStorage
may be the way to go. The API is identical.
This is a tip I learned from this excellent video from Dan Abramov.
With the way in which this works, you could adapt the following two functions to any sort of storage you like. For every similar problem I've ever had, localStorage
has been perfectly fine.
localStorage
acts a key / value store. This means we need a key, and a value to write. And a key to read.
You won't need to do any import
statements to make this work.
Let's see the code:
// /src/connectivity/localStorage.js
export const loadState = () => {
try {
const serializedState = localStorage.getItem('state');
if (serializedState === null) {
return undefined;
}
return JSON.parse(serializedState);
} catch (err) {
return undefined;
}
};
export const saveState = (state) => {
try {
const serializedState = JSON.stringify(state);
localStorage.setItem('state', serializedState);
} catch (err) {
// die
}
};
As our state
is a plain old JavaScript object, we can serialize (JSON.stringify
) and deserialize it (JSON.parse
) as required.
By subscribing the saveState
functionality to our Redux store, we can ensure this function will be called any time our state
is updated. It's a lovely, clean separation of concerns.
/src/store/configureStore.js
store.subscribe(() => {
saveState({
auth: store.getState().auth
});
}));
However, as our application's state
may be changing frequently, we likely don't need to write every single change to localStorage
, which would be costly.
By wrapping the function in lodash's throttle we can ensure this method will be called at most, once per second (1000
ms) in our example:
/src/store/configureStore.js
import _ from 'lodash';
// * snip *
store.subscribe(_.throttle(() => {
saveState({
auth: store.getState().auth
});
}, 1000));
Nice.