From a0630c89b9fcdfbb53d8d8b2946f9034dd024971 Mon Sep 17 00:00:00 2001 From: Gregory Date: Mon, 13 Apr 2020 17:05:22 +0300 Subject: [PATCH] feature: add object shorthand for mapStateToProps in connect using reselect library --- .gitignore | 2 ++ docs/api/connect.md | 20 +++++++++++++++++++- docs/introduction/quick-start.md | 2 ++ package.json | 3 ++- src/connect/mapStateToProps.js | 17 ++++++++++++++++- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index c5c530d5e..08292f7d7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ website/build/ website/yarn.lock website/node_modules website/i18n/* + +.DS_Store \ No newline at end of file diff --git a/docs/api/connect.md b/docs/api/connect.md index f980adda7..aba925e96 100644 --- a/docs/api/connect.md +++ b/docs/api/connect.md @@ -27,7 +27,7 @@ The returns of `mapStateToProps` and `mapDispatchToProps` are referred to intern `connect` accepts four different parameters, all optional. By convention, they are called: -1. `mapStateToProps?: Function` +1. `mapStateToProps?: Function | Object` 2. `mapDispatchToProps?: Function | Object` 3. `mergeProps?: Function` 4. `options?: Object` @@ -73,6 +73,24 @@ For more details on recommended usage of `mapStateToProps`, please refer to [our > You may define `mapStateToProps` and `mapDispatchToProps` as a factory function, i.e., you return a function instead of an object. In this case your returned function will be treated as the real `mapStateToProps` or `mapDispatchToProps`, and be called in subsequent calls. You may see notes on [Factory Functions](#factory-functions) or our guide on performance optimizations. +#### Object Shorthand Form + +`mapStateToProps` may be an object where each field is an [selector](https://redux.js.org/recipes/computing-derived-data#selectorsindexjs). + +```js +import { getTodos } from './selectors' + +const mapStateToProps = { + todos: getTodos, +} + +export default connect( + mapStateToProps, +)(TodoApp) +``` + +In this case, React-Redux binds the `state` and `ownProps` of your store to each of the selector using `createStructuredSelector` from [reselect](https://github.com/reduxjs/reselect). + ### `mapDispatchToProps?: Object | (dispatch, ownProps?) => Object` Conventionally called `mapDispatchToProps`, this second parameter to `connect()` may either be an object, a function, or not supplied. diff --git a/docs/introduction/quick-start.md b/docs/introduction/quick-start.md index 90a92ed74..55b2b91ba 100644 --- a/docs/introduction/quick-start.md +++ b/docs/introduction/quick-start.md @@ -35,6 +35,8 @@ yarn add react-redux You'll also need to [install Redux](https://redux.js.org/introduction/installation) and [set up a Redux store](https://redux.js.org/recipes/configuring-your-store/) in your app. +Also need to [install Reselect](https://github.com/reduxjs/reselect#installation) to use object shorthand for `mapStateToProps` in `connect`. + ## `Provider` React Redux provides ``, which makes the Redux store available to the rest of your app: diff --git a/package.json b/package.json index 5531f832e..6ff62ec87 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ }, "peerDependencies": { "react": "^16.8.3", - "redux": "^2.0.0 || ^3.0.0 || ^4.0.0-0" + "redux": "^2.0.0 || ^3.0.0 || ^4.0.0-0", + "reselect": "^4.0.0" }, "peerDependenciesMeta": { "react-dom": { diff --git a/src/connect/mapStateToProps.js b/src/connect/mapStateToProps.js index 6bfc0b368..35d402861 100644 --- a/src/connect/mapStateToProps.js +++ b/src/connect/mapStateToProps.js @@ -1,3 +1,5 @@ +import { createStructuredSelector } from 'reselect' + import { wrapMapToPropsConstant, wrapMapToPropsFunc } from './wrapMapToProps' export function whenMapStateToPropsIsFunction(mapStateToProps) { @@ -10,4 +12,17 @@ export function whenMapStateToPropsIsMissing(mapStateToProps) { return !mapStateToProps ? wrapMapToPropsConstant(() => ({})) : undefined } -export default [whenMapStateToPropsIsFunction, whenMapStateToPropsIsMissing] +export function whenMapStateToPropsIsObject(mapStateToProps) { + return mapStateToProps && typeof mapStateToProps === 'object' + ? wrapMapToPropsFunc( + createStructuredSelector(mapStateToProps), + 'mapStateToProps' + ) + : undefined +} + +export default [ + whenMapStateToPropsIsFunction, + whenMapStateToPropsIsMissing, + whenMapStateToPropsIsObject +]