For example...
export const user = (state = {
id: localStorage.getItem('id'),
name: localStorage.getItem('name'),
loggedInAt: null
}, action) => {
case types.LOGIN:
localStorage.setItem('name', action.payload.user.name);
localStorage.setItem('id', action.payload.user.id);
return { ...state, ...action.payload.user }
default:
return { ...state, loggedInAt: Date.now() }
}
That's a scaled down version of what I'm doing, default returns the state from localStorage as expected. However the state of my application is actually blank once I refresh the page.
Redux createStore
2nd param is intended for store initialization:
createStore(reducer, [initialState], [enhancer])
So you can do something like this:
const initialState = {
id: localStorage.getItem('id'),
name: localStorage.getItem('name'),
loggedInAt: null
};
const store = createStore(mainReducer, initialState);
Since reducers should be pure functions (i.e. no side effects) and localStorage.setItem
is a side effect, you should avoid saving to localStorage in a reducer.
Instead you can:
store.subscribe(() => {
const { id, name } = store.getState();
localStorage.setItem('name', name);
localStorage.setItem('id', id);
});
This will happen whenever the state changes, so it might affect performance.
Another option is to save the state only when the page is closed (refresh counts) using onBeforeUnload
:
window.onbeforeunload = () => {
const { id, name } = store.getState();
localStorage.setItem('name', name);
localStorage.setItem('id', id);
};