Where to write to localStorage in a Redux app?

In a word: middleware.

Check out redux-persist. Or write your own.

[UPDATE 18 Dec 2016] Edited to remove mention of two similar projects now inactive or deprecated.


To fill in the blanks of Dan Abramov's answer you could use store.subscribe() like this:

store.subscribe(()=>{
  localStorage.setItem('reduxState', JSON.stringify(store.getState()))
})

Before creating the store, check localStorage and parse any JSON under your key like this:

const persistedState = localStorage.getItem('reduxState') 
                       ? JSON.parse(localStorage.getItem('reduxState'))
                       : {}

You then pass this persistedState constant to your createStore method like this:

const store = createStore(
  reducer, 
  persistedState,
  /* any middleware... */
)

Reducer is never an appropriate place to do this because reducers should be pure and have no side effects.

I would recommend just doing it in a subscriber:

store.subscribe(() => {
  // persist your state
})

Before creating the store, read those persisted parts:

const persistedState = // ...
const store = createStore(reducer, persistedState)

If you use combineReducers() you’ll notice that reducers that haven’t received the state will “boot up” as normal using their default state argument value. This can be pretty handy.

It is advisable that you debounce your subscriber so you don’t write to localStorage too fast, or you’ll have performance problems.

Finally, you can create a middleware that encapsulates that as an alternative, but I’d start with a subscriber because it’s a simpler solution and does the job well.