4

All:

When I read the source of Redux, in its createStore:

function createStore(reducer, initialState, enhancer) {
    ......
    var currentState = initialState;
    ......
    dispatch({ type: ActionTypes.INIT });
    ......
}

When create a new store, it sets currentState to initialState, and call reducer in init dispatch to update the default state value. I wonder: generally the currentStatew will be given a value from reducer, then what is the purpose of that initialState?

Thanks

Kuan
  • 11,149
  • 23
  • 93
  • 201
  • 3
    Now that the entire application state is in a single tree, you can serialize that tree (to json) and save it for later. Then, you can populate the entire app with state you saved. Here `initialState` allows us to inject the state of the app. This is one of the major features of organizing state in the way redux does. – Davin Tryon Mar 10 '16 at 21:58
  • @DavinTryon Thanks, I guess I did not quite catch u. Say when we inject saved state to createStore(reducer, savedState), the initial dispatch `dispatch({ type: ActionTypes.INIT });` still will be called which return the value defined in reducer, how that savedState get used? – Kuan Mar 10 '16 at 22:10

1 Answers1

10

Normally, just specify the initial state as reducer default argument, and let each reducer manage it for themselves.

However in some cases you want to “hydrate” the state with existing data. For example, you might have saved the whole state tree in a localStorage and want to load it from there on startup, or maybe you are rendering on the server, and want to load the initial state you saved on the server from the HTML.

In this case, the initialState to createStore() is useful because it lets you optionally hydrate some parts of the tree where you have pre-populated data. In this case, it would “win” to the reducer default state which is usually the behavior you would want. The parts of the state tree that exist in initialState would be used as is, and the missing parts would be retrieved from the reducers. This makes it possible to “restore” some parts of the state, but always re-initialize the others.

Hopefully this answer should provide a more in-depth explanation of this technique.

Community
  • 1
  • 1
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
  • Thanks, when I read that code again, I finally realize what confused me is the initState need to has same structure of the restoredState, otherwise it will be override by reducer default return. BTW, I am right now reading your article about presentatioanl/container component. Like it so much! – Kuan Mar 11 '16 at 21:59
  • Hi, Dan, one question about react-redux is: in that todo list example: when we build the container componnet like: `const mapStateToProps = (state) => { return { todos: getVisibleTodos(state.todos, state.visibilityFilter) } }` the state has to be the whole state tree and in getVisibleTodos(or whatever) we have to know the exact structure of the state tree in order to access the part for todos, right? It can not be like in building combine reducer, just part of state pass, right? – Kuan Mar 12 '16 at 19:22
  • You get the full state in `mapStateToProps` but it is up to you what to do with it. For example, you can write helper functions we call “selectors” that extract a part of the state, and even compose them. I suggest you to check out a library called Reselect that lets you create composable and efficient selectors. – Dan Abramov Mar 13 '16 at 12:07
  • Thanks. Another question related to the container component is: how to decide the right moment/place to use container component. Does it mean we always use a container component as long as we need to pass data( which is not need by parent component) from parent to children components. – Kuan Mar 21 '16 at 18:01
  • Please create a separate question, as it doesn’t appear related. Cheers! – Dan Abramov Mar 22 '16 at 17:13
  • Hi, Dan, I have one question dedicated to container component, inside that component, we need to know exactly the whole structure in order to access according data for passing to presentational component, does this mean this pattern will have a heavy coupling with the state data? – Kuan Apr 01 '16 at 17:23
  • To avoid excessive coupling, it’s best to use composable selectors to gradually “refine” the data you want: http://redux.js.org/docs/recipes/ComputingDerivedData.html. But indeed at the end a container component selects particular part of the state. – Dan Abramov Apr 01 '16 at 17:28
  • 1
    Thanks, as talking about container component, say I have a data visualization chart which consists of a lot of different presentational components( such as the lines, axis, title, legend, option widgets, header menu, etc), I am kinda wondering which way u recommend: should I **wrap each of them** with a container component(which seems add a lot of work) or just use the presentational components, and wrap the final component(the most out side) with **single** container component( which seems a careful design of attribution passing architecture required) ? – Kuan Apr 01 '16 at 23:22
  • 1
    I’d probably start by wrapping them with a single container and see how it goes. – Dan Abramov Apr 03 '16 at 00:10
  • Thanks, i will start with that. – Kuan Apr 03 '16 at 01:02