Skip to content

Commit d7ede94

Browse files
committed
Merge branch 'master' into migrate-real-world-example-to-redux-react-router
2 parents 76ddafc + 39072e3 commit d7ede94

25 files changed

+134
-516
lines changed

CHANGELOG.md

Lines changed: 3 additions & 438 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ Join the **#redux** channel of the [Reactiflux](http://reactiflux.com) Slack com
150150

151151
Special thanks to [Jamie Paton](http://jdpaton.github.io) for handing over the `redux` NPM package name.
152152

153+
### Change Log
154+
155+
This project adheres to [Semantic Versioning](http://semver.org/).
156+
Every release, along with the migration instructions, is documented on the Github [Releases](https://github.com/rackt/redux/releases) page.
157+
153158
### Patrons
154159

155160
The work on Redux was [funded by the community](https://www.patreon.com/reactdx).

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@
3636
* [applyMiddleware](/docs/api/applyMiddleware.md)
3737
* [bindActionCreators](/docs/api/bindActionCreators.md)
3838
* [compose](/docs/api/compose.md)
39+
* [Change Log](/CHANGELOG.md)
3940
* [Patrons](/PATRONS.md)

docs/advanced/AsyncActions.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,9 @@ Remember that reducers are just functions, so you can use functional composition
293293

294294
## Async Action Creators
295295

296-
Finally, how do we use the synchronous action creators we [defined earlier](#synchronous-action-creators) together with network requests? The standard way to do it with Redux is to use the [Redux Thunk middleware](https://github.com/gaearon/redux-thunk). It comes in a separate package called `redux-thunk`. We’ll explain how middleware works in general [later](Middleware.md); for now, there is just one important thing you need to know: by using this specific middleware, an action creator can return a function instead an action object. This way, the function creator becomes a [thunk](https://en.wikipedia.org/wiki/Thunk).
296+
Finally, how do we use the synchronous action creators we [defined earlier](#synchronous-action-creators) together with network requests? The standard way to do it with Redux is to use the [Redux Thunk middleware](https://github.com/gaearon/redux-thunk). It comes in a separate package called `redux-thunk`. We’ll explain how middleware works in general [later](Middleware.md); for now, there is just one important thing you need to know: by using this specific middleware, an action creator can return a function instead an action object. This way, the action creator becomes a [thunk](https://en.wikipedia.org/wiki/Thunk).
297297

298-
When a function creator returns a function, that function will get executed by the Redux Thunk middleware. This function doesn’t need to be pure; it is thus allowed to have side effects, including executing asynchronous API calls. The function can also dispatch actions—like those synchronous actions we defined earlier.
298+
When an action creator returns a function, that function will get executed by the Redux Thunk middleware. This function doesn’t need to be pure; it is thus allowed to have side effects, including executing asynchronous API calls. The function can also dispatch actions—like those synchronous actions we defined earlier.
299299

300300
We can still define these special thunk action creators inside our `actions.js` file:
301301

@@ -355,7 +355,7 @@ export function fetchPosts(reddit) {
355355
dispatch(receivePosts(reddit, json))
356356
);
357357

358-
// Note: in a real world app, you also want to
358+
// In a real world app, you also want to
359359
// catch any error in the network call.
360360
};
361361
}
@@ -390,15 +390,11 @@ import { createStore, applyMiddleware } from 'redux';
390390
import { selectReddit, fetchPosts } from './actions';
391391
import rootReducer from './reducers';
392392

393-
const logger = createLogger({
394-
level: 'info',
395-
collapsed: true,
396-
predicate (getState, action) => action.type
397-
});
393+
const loggerMiddleware = createLogger();
398394

399395
const createStoreWithMiddleware = applyMiddleware(
400396
thunkMiddleware, // lets us dispatch() functions
401-
logger // neat middleware that logs actions
397+
loggerMiddleware // neat middleware that logs actions
402398
)(createStore);
403399

404400
const store = createStoreWithMiddleware(rootReducer);

docs/advanced/ExampleRedditAPI.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,11 @@ export default rootReducer;
164164
```js
165165
import { createStore, applyMiddleware } from 'redux';
166166
import thunkMiddleware from 'redux-thunk';
167-
import loggerMiddleware from 'redux-logger';
167+
import createLogger from 'redux-logger';
168168
import rootReducer from './reducers';
169169

170+
const loggerMiddleware = createLogger();
171+
170172
const createStoreWithMiddleware = applyMiddleware(
171173
thunkMiddleware,
172174
loggerMiddleware

docs/basics/Reducers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Note that:
101101

102102
>##### Note on `Object.assign`
103103
104-
>[`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) is a part of ES6, but is not implemented by most browsers yet. You’ll need to either use a polyfill, a [Babel plugin](https://github.com/babel-plugins/babel-plugin-object-assign), or a helper from another library like [`_.assign()`](https://lodash.com/docs#assign).
104+
>[`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) is a part of ES6, but is not implemented by most browsers yet. You’ll need to either use a polyfill, a [Babel plugin](https://www.npmjs.com/package/babel-plugin-object-assign), or a helper from another library like [`_.assign()`](https://lodash.com/docs#assign).
105105
106106
>##### Note on `switch` and Boilerplate
107107

docs/introduction/Examples.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ open http://localhost:3000/
8080

8181
It covers:
8282

83-
* [Universal rendering](/docs/recipes/ServerRendering.md) with Redux and React
83+
* [Universal rendering](../recipes/ServerRendering.md) with Redux and React
8484
* Prefetching state based on input and via asynchronous fetches.
8585
* Passing state from the server to the client
8686

docs/recipes/WritingTests.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,15 @@ import expect from 'expect';
330330
import * as types from '../../constants/ActionTypes';
331331
import singleDispatch from '../../middleware/singleDispatch';
332332

333-
const fakeStore = fakeData => ({
333+
const createFakeStore = fakeData => ({
334334
getState() {
335335
return fakeData;
336336
}
337337
});
338338

339339
const dispatchWithStoreOf = (storeData, action) => {
340340
let dispatched = null;
341-
const dispatch = singleDispatch(fakeStore(storeData))(actionAttempt => dispatched = actionAttempt);
341+
const dispatch = singleDispatch(createFakeStore(storeData))(actionAttempt => dispatched = actionAttempt);
342342
dispatch(action);
343343
return dispatched;
344344
};

examples/async/.babelrc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
{
2-
"stage": 2
2+
"stage": 2,
3+
"plugins" : [
4+
"react-transform"
5+
],
6+
"extra" : {
7+
"react-transform": [{
8+
"target" : "react-transform-webpack-hmr",
9+
"imports" : ["react"],
10+
"locals" : ["module"]
11+
}]
12+
}
313
}

examples/async/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@
3636
"devDependencies": {
3737
"babel-core": "^5.6.18",
3838
"babel-loader": "^5.1.4",
39+
"babel-plugin-react-transform": "^1.0.3",
3940
"expect": "^1.6.0",
4041
"jsdom": "^5.6.1",
4142
"mocha": "^2.2.5",
4243
"mocha-jsdom": "^1.0.0",
4344
"node-libs-browser": "^0.5.2",
44-
"react-hot-loader": "^1.3.0",
45+
"react-transform-webpack-hmr": "^0.1.4",
4546
"webpack": "^1.9.11",
4647
"webpack-dev-server": "^1.9.0"
4748
}

examples/async/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = {
1919
module: {
2020
loaders: [{
2121
test: /\.js$/,
22-
loaders: ['react-hot', 'babel'],
22+
loaders: ['babel'],
2323
exclude: /node_modules/,
2424
include: __dirname
2525
}]

examples/counter/.babelrc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
{
2-
"stage": 2
2+
"stage": 2,
3+
"plugins" : [
4+
"react-transform"
5+
],
6+
"extra" : {
7+
"react-transform": [{
8+
"target" : "react-transform-webpack-hmr",
9+
"imports" : ["react"],
10+
"locals" : ["module"]
11+
}]
12+
}
313
}

examples/counter/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@
2525
"devDependencies": {
2626
"babel-core": "^5.6.18",
2727
"babel-loader": "^5.1.4",
28+
"babel-plugin-react-transform": "^1.0.3",
2829
"expect": "^1.6.0",
2930
"jsdom": "^5.6.1",
3031
"mocha": "^2.2.5",
3132
"mocha-jsdom": "^1.0.0",
3233
"node-libs-browser": "^0.5.2",
33-
"react-hot-loader": "^1.3.0",
34+
"react-transform-webpack-hmr": "^0.1.4",
3435
"webpack": "^1.9.11",
3536
"webpack-dev-server": "^1.9.0"
3637
}

examples/counter/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = {
1919
module: {
2020
loaders: [{
2121
test: /\.js$/,
22-
loaders: ['react-hot', 'babel'],
22+
loaders: ['babel'],
2323
exclude: /node_modules/,
2424
include: __dirname
2525
}]

examples/real-world/.babelrc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
{
2-
"stage": 2
2+
"stage": 2,
3+
"plugins" : [
4+
"react-transform"
5+
],
6+
"extra" : {
7+
"react-transform": [{
8+
"target" : "react-transform-webpack-hmr",
9+
"imports" : ["react"],
10+
"locals" : ["module"]
11+
}]
12+
}
313
}

examples/real-world/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
"devDependencies": {
3333
"babel-core": "^5.6.18",
3434
"babel-loader": "^5.1.4",
35-
"react-hot-loader": "^1.3.0",
3635
"redux-devtools": "^2.1.2",
36+
"babel-plugin-react-transform": "^1.0.3",
37+
"react-transform-webpack-hmr": "^0.1.4",
3738
"webpack": "^1.9.11",
3839
"webpack-dev-server": "^1.9.0"
3940
}

examples/real-world/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = {
1919
module: {
2020
loaders: [{
2121
test: /\.js$/,
22-
loaders: ['react-hot', 'babel'],
22+
loaders: ['babel'],
2323
exclude: /node_modules/,
2424
include: __dirname
2525
}]

examples/todomvc/.babelrc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
{
2-
"stage": 2
2+
"stage": 2,
3+
"plugins" : [
4+
"react-transform"
5+
],
6+
"extra" : {
7+
"react-transform": [{
8+
"target" : "react-transform-webpack-hmr",
9+
"imports" : ["react"],
10+
"locals" : ["module"]
11+
}]
12+
}
313
}

examples/todomvc/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@
2525
"devDependencies": {
2626
"babel-core": "^5.6.18",
2727
"babel-loader": "^5.1.4",
28+
"babel-plugin-react-transform": "^1.0.3",
2829
"expect": "^1.8.0",
2930
"jsdom": "^5.6.1",
3031
"mocha": "^2.2.5",
3132
"mocha-jsdom": "^1.0.0",
3233
"node-libs-browser": "^0.5.2",
3334
"raw-loader": "^0.5.1",
34-
"react-hot-loader": "^1.3.0",
35+
"react-transform-webpack-hmr": "^0.1.4",
3536
"style-loader": "^0.12.3",
3637
"todomvc-app-css": "^2.0.1",
3738
"webpack": "^1.9.11",

examples/todomvc/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module.exports = {
1919
module: {
2020
loaders: [{
2121
test: /\.js$/,
22-
loaders: ['react-hot', 'babel'],
22+
loaders: ['babel'],
2323
exclude: /node_modules/,
2424
include: __dirname
2525
}, {

examples/universal/.babelrc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
{
2-
"stage": 2
2+
"stage": 2,
3+
"plugins" : [
4+
"react-transform"
5+
],
6+
"extra" : {
7+
"react-transform": [{
8+
"target" : "react-transform-webpack-hmr",
9+
"imports" : ["react"],
10+
"locals" : ["module"]
11+
}]
12+
}
313
}

examples/universal/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@
2929
"devDependencies": {
3030
"babel-core": "^5.8.22",
3131
"babel-loader": "^5.3.2",
32+
"babel-plugin-react-transform": "^1.0.3",
3233
"babel-runtime": "^5.8.20",
33-
"react-hot-loader": "^1.3.0",
34+
"react-transform-webpack-hmr": "^0.1.4",
3435
"webpack": "^1.11.0",
3536
"webpack-dev-server": "^1.10.1"
3637
}

examples/universal/webpack.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ module.exports = {
2222
module: {
2323
loaders: [{
2424
test: /\.js$/,
25-
loaders: ['react-hot', 'babel?optional=runtime'],
25+
loaders: ['babel?optional=runtime'],
2626
exclude: /node_modules/,
2727
include: __dirname
2828
}]

src/utils/combineReducers.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ function getErrorMessage(key, action) {
1515
);
1616
}
1717

18-
function verifyStateShape(initialState, currentState) {
19-
var reducerKeys = Object.keys(currentState);
18+
function verifyStateShape(inputState, outputState, action) {
19+
var reducerKeys = Object.keys(outputState);
20+
var argumentName = action && action.type === ActionTypes.INIT ?
21+
'initialState argument passed to createStore' :
22+
'previous state received by the reducer';
2023

2124
if (reducerKeys.length === 0) {
2225
console.error(
@@ -26,25 +29,26 @@ function verifyStateShape(initialState, currentState) {
2629
return;
2730
}
2831

29-
if (!isPlainObject(initialState)) {
32+
if (!isPlainObject(inputState)) {
3033
console.error(
31-
'initialState has unexpected type of "' +
32-
({}).toString.call(initialState).match(/\s([a-z|A-Z]+)/)[1] +
33-
'". Expected initialState to be an object with the following ' +
34+
`The ${argumentName} has unexpected type of "` +
35+
({}).toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] +
36+
`". Expected argument to be an object with the following ` +
3437
`keys: "${reducerKeys.join('", "')}"`
3538
);
3639
return;
3740
}
3841

39-
var unexpectedKeys = Object.keys(initialState).filter(
42+
var unexpectedKeys = Object.keys(inputState).filter(
4043
key => reducerKeys.indexOf(key) < 0
4144
);
4245

4346
if (unexpectedKeys.length > 0) {
4447
console.error(
4548
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` +
46-
`"${unexpectedKeys.join('", "')}" in initialState will be ignored. ` +
47-
`Expected to find one of the known reducer keys instead: "${reducerKeys.join('", "')}"`
49+
`"${unexpectedKeys.join('", "')}" found in ${argumentName}. ` +
50+
`Expected to find one of the known reducer keys instead: ` +
51+
`"${reducerKeys.join('", "')}". Unexpected keys will be ignored.`
4852
);
4953
}
5054
}
@@ -94,7 +98,6 @@ export default function combineReducers(reducers) {
9498
});
9599

96100
var defaultState = mapValues(finalReducers, () => undefined);
97-
var stateShapeVerified;
98101

99102
return function combination(state = defaultState, action) {
100103
var finalState = mapValues(finalReducers, (reducer, key) => {
@@ -106,10 +109,7 @@ export default function combineReducers(reducers) {
106109
});
107110

108111
if (process.env.NODE_ENV !== 'production') {
109-
if (!stateShapeVerified) {
110-
verifyStateShape(state, finalState);
111-
stateShapeVerified = true;
112-
}
112+
verifyStateShape(state, finalState, action);
113113
}
114114

115115
return finalState;

0 commit comments

Comments
 (0)