Skip to content

Accept object as valid mapStateToProps argument #645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
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: 3 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ It does not modify the component class passed to it; instead, it *returns* a new
<a id="connect-arguments"></a>
#### Arguments

* [`mapStateToProps(state, [ownProps]): stateProps`] \(*Function*): If this argument is specified, the new component will subscribe to Redux store updates. This means that any time the store is updated, `mapStateToProps` will be called. The results of `mapStateToProps` must be a plain object*, which will be merged into the component’s props. If you don't want to subscribe to store updates, pass `null` or `undefined` in place of `mapStateToProps`. If `ownProps` is specified as a second argument, its value will be the props passed to your component, and `mapStateToProps` will be additionally re-invoked whenever the component receives new props (e.g. if props received from a parent component have shallowly changed, and you use the ownProps argument, mapStateToProps is re-evaluated).
* [`mapStateToProps(state, [ownProps]): stateProps`] \(*Function* or *Object*): If this argument is specified, the new component will subscribe to Redux store updates. This means that any time the store is updated, `mapStateToProps` will be called. The results of `mapStateToProps` must be a plain object*, which will be merged into the component’s props. If you don't want to subscribe to store updates, pass `null` or `undefined` in place of `mapStateToProps`. If `ownProps` is specified as a second argument, its value will be the props passed to your component, and `mapStateToProps` will be additionally re-invoked whenever the component receives new props (e.g. if props received from a parent component have shallowly changed, and you use the ownProps argument, mapStateToProps is re-evaluated).

If an object is passed, each function inside it is assumed to be a Redux selector.

>Note: in advanced scenarios where you need more control over the rendering performance, `mapStateToProps()` can also return a function. In this case, *that* function will be used as `mapStateToProps()` for a particular component instance. This allows you to do per-instance memoization. You can refer to [#279](https://github.com/reactjs/react-redux/pull/279) and the tests it adds for more details. Most apps never need this.

Expand Down
26 changes: 26 additions & 0 deletions src/connect/mapStateToProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,31 @@ export function whenMapStateToPropsIsFunction(mapStateToProps) {
: undefined
}

function getSelectorFromObject(objectSelectors) {
return function (state) {
const result = {};
Object.keys(objectSelectors).forEach(function (key) {
result[key] = objectSelectors[key](state);
});
return result;
};
}

function isValidmapStateToPropsObj(mapStateToProps) {
return typeof mapStateToProps === 'object' && Object
.keys(mapStateToProps)
.map(function (key) { return mapStateToProps[key] })
.every(function (val) { return typeof val === 'function'; });
}

export function whenMapStateToPropsIsObject(mapStateToProps) {
return (isValidmapStateToPropsObj(mapStateToProps)) ?
wrapMapToPropsFunc(
getSelectorFromObject(mapStateToProps), 'mapStateToProps'
) :
undefined
}

export function whenMapStateToPropsIsMissing(mapStateToProps) {
return (!mapStateToProps)
? wrapMapToPropsConstant(() => ({}))
Expand All @@ -14,5 +39,6 @@ export function whenMapStateToPropsIsMissing(mapStateToProps) {

export default [
whenMapStateToPropsIsFunction,
whenMapStateToPropsIsObject,
whenMapStateToPropsIsMissing
]
Loading