Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@
"webpack": "^1.9.6",
"webpack-dev-server": "^1.8.2"
},
"dependencies": {
"invariant": "^2.0.0",
"warning": "^2.0.0"
},
"npmName": "redux",
"npmFileMap": [
{
Expand Down
22 changes: 9 additions & 13 deletions src/createStore.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import invariant from 'invariant';
import isPlainObject from './utils/isPlainObject';

/**
Expand Down Expand Up @@ -32,10 +31,9 @@ export var ActionTypes = {
* and subscribe to changes.
*/
export default function createStore(reducer, initialState) {
invariant(
typeof reducer === 'function',
'Expected the reducer to be a function.'
);
if (typeof reducer !== 'function') {
throw new Error('Expected the reducer to be a function.');
}

var currentReducer = reducer;
var currentState = initialState;
Expand Down Expand Up @@ -92,15 +90,13 @@ export default function createStore(reducer, initialState) {
* return something else (for example, a Promise you can await).
*/
function dispatch(action) {
invariant(
isPlainObject(action),
'Actions must be plain objects. Use custom middleware for async actions.'
);
if (!isPlainObject(action)) {
throw new Error('Actions must be plain objects. Use custom middleware for async actions.');
}

invariant(
isDispatching === false,
'Reducers may not dispatch actions.'
);
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.');
}

try {
isDispatching = true;
Expand Down
13 changes: 6 additions & 7 deletions src/utils/bindActionCreators.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import invariant from 'invariant';
import mapValues from '../utils/mapValues';

function bindActionCreator(actionCreator, dispatch) {
Expand Down Expand Up @@ -31,12 +30,12 @@ export default function bindActionCreators(actionCreators, dispatch) {
return bindActionCreator(actionCreators, dispatch);
}

invariant(
typeof actionCreators === 'object' && actionCreators != null,
'bindActionCreators expected an object or a function, instead received %s. ' +
'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?',
typeof actionCreators
);
if (typeof actionCreators !== 'object' || actionCreators == null) {
throw new Error(
`bindActionCreators expected an object or a function, instead received ${typeof actionCreators}. ` +
`Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`
);
}

return mapValues(actionCreators, actionCreator =>
bindActionCreator(actionCreator, dispatch)
Expand Down
62 changes: 30 additions & 32 deletions src/utils/combineReducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { ActionTypes } from '../createStore';
import isPlainObject from '../utils/isPlainObject';
import mapValues from '../utils/mapValues';
import pick from '../utils/pick';
import invariant from 'invariant';
import warning from 'warning';

function getErrorMessage(key, action) {
var actionType = action && action.type;
Expand All @@ -19,17 +17,15 @@ function verifyStateShape(initialState, currentState) {
var reducerKeys = Object.keys(currentState);

if (reducerKeys.length === 0) {
warning(
false,
console.error(
'Store does not have a valid reducer. Make sure the argument passed ' +
'to combineReducers is an object whose values are reducers.'
);
return;
}

if (!isPlainObject(initialState)) {
warning(
false,
console.error(
'initialState has unexpected type of "' +
({}).toString.call(initialState).match(/\s([a-z|A-Z]+)/)[1] +
'". Expected initialState to be an object with the following ' +
Expand All @@ -42,12 +38,13 @@ function verifyStateShape(initialState, currentState) {
key => reducerKeys.indexOf(key) < 0
);

warning(
unexpectedKeys.length === 0,
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` +
`"${unexpectedKeys.join('", "')}" in initialState will be ignored. ` +
`Expected to find one of the known reducer keys instead: "${reducerKeys.join('", "')}"`
);
if (unexpectedKeys.length > 0) {
console.error(
`Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` +
`"${unexpectedKeys.join('", "')}" in initialState will be ignored. ` +
`Expected to find one of the known reducer keys instead: "${reducerKeys.join('", "')}"`
);
}
}

/**
Expand All @@ -72,24 +69,26 @@ export default function combineReducers(reducers) {

Object.keys(finalReducers).forEach(key => {
var reducer = finalReducers[key];
invariant(
typeof reducer(undefined, { type: ActionTypes.INIT }) !== 'undefined',
`Reducer "${key}" returned undefined during initialization. ` +
`If the state passed to the reducer is undefined, you must ` +
`explicitly return the initial state. The initial state may ` +
`not be undefined.`
);
if (typeof reducer(undefined, { type: ActionTypes.INIT }) === 'undefined') {
throw new Error(
`Reducer "${key}" returned undefined during initialization. ` +
`If the state passed to the reducer is undefined, you must ` +
`explicitly return the initial state. The initial state may ` +
`not be undefined.`
);
}

var type = Math.random().toString(36).substring(7).split('').join('.');
invariant(
typeof reducer(undefined, { type }) !== 'undefined',
`Reducer "${key}" returned undefined when probed with a random type. ` +
`Don't try to handle ${ActionTypes.INIT} or other actions in "redux/*" ` +
`namespace. They are considered private. Instead, you must return the ` +
`current state for any unknown actions, unless it is undefined, ` +
`in which case you must return the initial state, regardless of the ` +
`action type. The initial state may not be undefined.`
);
if (typeof reducer(undefined, { type }) === 'undefined') {
throw new Error(
`Reducer "${key}" returned undefined when probed with a random type. ` +
`Don't try to handle ${ActionTypes.INIT} or other actions in "redux/*" ` +
`namespace. They are considered private. Instead, you must return the ` +
`current state for any unknown actions, unless it is undefined, ` +
`in which case you must return the initial state, regardless of the ` +
`action type. The initial state may not be undefined.`
);
}
});

var defaultState = mapValues(finalReducers, () => undefined);
Expand All @@ -98,10 +97,9 @@ export default function combineReducers(reducers) {
return function combination(state = defaultState, action) {
var finalState = mapValues(finalReducers, (reducer, key) => {
var newState = reducer(state[key], action);
invariant(
typeof newState !== 'undefined',
getErrorMessage(key, action)
);
if (typeof newState === 'undefined') {
throw new Error(getErrorMessage(key, action));
}
return newState;
});

Expand Down
6 changes: 3 additions & 3 deletions test/utils/bindActionCreators.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('bindActionCreators', () => {
]);
});

it('should throw an invariant violation for an undefined actionCreator', () => {
it('should throw for an undefined actionCreator', () => {
expect(() => {
bindActionCreators(undefined, store.dispatch);
}).toThrow(
Expand All @@ -47,7 +47,7 @@ describe('bindActionCreators', () => {
);
});

it('should throw an invariant violation for a null actionCreator', () => {
it('should throw for a null actionCreator', () => {
expect(() => {
bindActionCreators(null, store.dispatch);
}).toThrow(
Expand All @@ -56,7 +56,7 @@ describe('bindActionCreators', () => {
);
});

it('should throw an invariant violation for a primitive actionCreator', () => {
it('should throw for a primitive actionCreator', () => {
expect(() => {
bindActionCreators('string', store.dispatch);
}).toThrow(
Expand Down