Skip to content

Commit 2afae08

Browse files
committed
Merge pull request reduxjs#258 from ellbee/stores-doc
Update store.md to use combineReducers explicit call
2 parents cdaa3e8 + 2bb3769 commit 2afae08

File tree

1 file changed

+68
-28
lines changed

1 file changed

+68
-28
lines changed

docs/store.md

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,72 @@
33
The store has the following responsibilities:
44

55
* Holds application state
6-
* Allows access to state via the `getState` method
7-
* Allows state to be updated via the `dispatch` method
8-
* Registers listeners via the `subscribe` method
6+
* Allows access to state via `getState`
7+
* Allows state to be updated via `dispatch`
8+
* Registers listeners via `subscribe`
99

1010
####Initialization
1111

12-
The simplest way to initialize the store is to call `createStore` with an object of reducer functions. The following example sets up the store for an application that has both a `counter` reducer and a `todos` reducer.
12+
To intialize a store you simply call `createStore` with a reducer:
1313

1414
```js
1515
import { createStore } from 'redux';
16-
import { Provider } from 'react-redux';
17-
import counter from 'reducers/counter';
18-
import todos from 'reducers/todos';
16+
import counterReducer from './reducers/counter';
1917

20-
const store = createStore({counter, todos});
18+
const store = createStore(counterReducer);
2119
```
2220

23-
A recommended pattern is to create the object of reducer functions from a definition file.
21+
`createStore` intializes the store with a single reducer, but in the following example we would like to use functionality from both the `counter` and `todos` reducers. To do this we need to somehow combine `counter` and `todos` into a single reducer. Here is one approach:
22+
23+
```js
24+
import { createStore } from 'redux';
25+
import counterReducer from './reducers/counter';
26+
import todosReducer from './reducers/todos';
27+
28+
// set up the initial combined state
29+
const initialState = {
30+
counterState: undefined,
31+
todoState: undefined
32+
};
33+
34+
function masterReducer(state = initialState, action) {
35+
// call each reducer separately
36+
const counterState = counterReducer(state.counterState, action);
37+
const todoState = todosReducer(state.todoState, action);
38+
39+
// combine updated state created by each reducer into the new combined state
40+
return { counterState, todoState };
41+
}
42+
43+
const store = createStore(masterReducer);
44+
```
45+
46+
Combining reducers is very common so there is a helper function named `combineReducers` to assist. `combineReducers` takes an object of reducers and combines them into a single reducer. Here is the previous example using `combineReducers`:
47+
48+
```js
49+
import { createStore, combineReducers } from 'redux';
50+
import counterReducer from './reducers/counter';
51+
import todosReducer from './reducers/todos';
52+
53+
const reducers = {
54+
counter: counterReducer,
55+
todos: todosReducer
56+
}
57+
58+
const masterReducer = combineReducers(reducers);
59+
const store = createStore(masterReducer);
60+
```
61+
62+
Note that the key of each reducer in the reducer object passed to `combineReducers` becomes a top-level key on the state object returned by the combined reducer. In the previous example, the state object returned by `masterReducer` looks like this:
63+
64+
```js
65+
const state = {
66+
counter: counterState,
67+
todos: todosState
68+
};
69+
```
70+
71+
A recommended pattern is to use `import *` to import an object of reducers from a definition file:
2472

2573
```js
2674
// reducers/index.js
@@ -29,29 +77,29 @@ export { default as todos } from './todos'
2977
```
3078

3179
```js
32-
import { createStore } from 'redux';
33-
import { Provider } from 'react-redux';
80+
import { createStore, combineReducers } from 'redux';
3481
import * as reducers from './reducers/index';
3582

36-
const store = createStore(reducers);
83+
const reducer = combineReducers(reducers);
84+
const store = createStore(reducer);
3785
```
3886

3987
You may optionally specify the initial state as the second argument to `createStore`. This is useful for hydrating the state of the client to match the state of a Redux application running on the server.
4088

4189
```js
4290
// server
43-
const store = createStore(reducers);
91+
const store = createStore(reducer);
4492
store.dispatch(MyActionCreators.doSomething()); // fire action creators to fill the state
4593
const state = store.getState(); // somehow pass this state to the client
4694

4795
// client
4896
const initialState = window.STATE_FROM_SERVER;
49-
const store = createStore(reducers, initialState);
97+
const store = createStore(reducer, initialState);
5098
```
5199

52100
####Usage
53101

54-
Store state is accessed using the `getState` method. Note that when you initialize the store by passing `createStore` an object of reducer functions, the name of each reducer becomes a top-level key on the state object.
102+
Store state is accessed using the `getState` method.
55103

56104
```js
57105
store.getState();
@@ -65,7 +113,7 @@ store.getState();
65113
// }
66114
```
67115

68-
Store state is updated by calling the `dispatch` method with an action understood by one or more reducers.
116+
Store state is updated by calling the `dispatch` method with an action understood by the reducer.
69117

70118
```js
71119
store.dispatch({
@@ -95,23 +143,15 @@ let unsubscribe = store.subscribe(() => console.log('state change!'));
95143
```
96144

97145
####Advanced Intitialization
98-
`createStore` can be called with a single reducing function instead of an object of reducing functions. The `combineReducers` function can be used to compose multiple reducers. TODO: Real world use case?
99-
100-
```js
101-
import { createStore, combineReducers } from 'redux';
102-
import * as reducers from './reducers/index';
103-
104-
const combinedReducerFn = combineReducers(counter, todos);
105-
const store = createStore(combinedReducerFn);
106-
```
107146

108147
[Middleware](middleware.md) can be set up using `applyMiddleware`.
109148

110149
```js
111-
import { createStore, applyMiddleware } from 'redux'
150+
import { createStore, applyMiddleware, combineReducers } from 'redux'
112151
import { logger, promise } from './middleware'
113152
import * as reducers from './reducers/index';
114153

115-
const createWithMiddleware = applyMiddleware(logger, promise)(createStore);
116-
const store = createWithMiddleware(reducers);
154+
const reducer = combineReducers(reducers);
155+
const createStoreWithMiddleware = applyMiddleware(logger, promise)(createStore);
156+
const store = createStoreWithMiddleware(reducer);
117157
```

0 commit comments

Comments
 (0)