Skip to content

Commit ff71f53

Browse files
jimbollatimdorr
authored andcommitted
Update API docs for v5 (reduxjs#480)
* updates docs for changes in v5 (WORK IN PROGRESS) * update docs for changes in v5 * removes unused code from example * adds a tags to api.md for direct linking
1 parent eff0ddf commit ff71f53

File tree

1 file changed

+108
-24
lines changed

1 file changed

+108
-24
lines changed

docs/api.md

Lines changed: 108 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## API
22

3+
<a id="provider"></a>
34
### `<Provider store>`
45

56
Makes the Redux store available to the `connect()` calls in the component hierarchy below. Normally, you can’t use `connect()` without wrapping the root component in `<Provider>`.
@@ -40,28 +41,38 @@ ReactDOM.render(
4041
)
4142
```
4243

44+
45+
<a id="connect"></a>
4346
### `connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])`
4447

45-
Connects a React component to a Redux store.
48+
Connects a React component to a Redux store. `connect` is a facade around `connectAdvanced`, providing a convenient API for the most common use cases.
4649

47-
It does not modify the component class passed to it.
48-
Instead, it *returns* a new, connected component class, for you to use.
50+
It does not modify the component class passed to it; instead, it *returns* a new, connected component class for you to use.
4951

52+
<a id="connect-arguments"></a>
5053
#### Arguments
5154

5255
* [`mapStateToProps(state, [ownProps]): stateProps`] \(*Function*): If specified, the component will subscribe to Redux store updates. Any time it updates, `mapStateToProps` will be called. Its result must be a plain object*, and it will be merged into the component’s props. If you omit it, the component will not be subscribed to the Redux store. 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).
5356

5457
>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.
5558
59+
>The `mapStateToProps` function takes a single argument of the entire Redux store’s state and returns an object to be passed as props. It is often called a **selector**. Use [reselect](https://github.com/reactjs/reselect) to efficiently compose selectors and [compute derived data](http://redux.js.org/docs/recipes/ComputingDerivedData.html).
60+
5661
* [`mapDispatchToProps(dispatch, [ownProps]): dispatchProps`] \(*Object* or *Function*): If an object is passed, each function inside it will be assumed to be a Redux action creator. An object with the same function names, but with every action creator wrapped into a `dispatch` call so they may be invoked directly, will be merged into the component’s props. If a function is passed, it will be given `dispatch`. It’s up to you to return an object that somehow uses `dispatch` to bind action creators in your own way. (Tip: you may use the [`bindActionCreators()`](http://reactjs.github.io/redux/docs/api/bindActionCreators.html) helper from Redux.) If you omit it, the default implementation just injects `dispatch` into your component’s props. If `ownProps` is specified as a second argument, its value will be the props passed to your component, and `mapDispatchToProps` will be re-invoked whenever the component receives new props.
5762

5863
>Note: in advanced scenarios where you need more control over the rendering performance, `mapDispatchToProps()` can also return a function. In this case, *that* function will be used as `mapDispatchToProps()` 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.
5964
6065
* [`mergeProps(stateProps, dispatchProps, ownProps): props`] \(*Function*): If specified, it is passed the result of `mapStateToProps()`, `mapDispatchToProps()`, and the parent `props`. The plain object you return from it will be passed as props to the wrapped component. You may specify this function to select a slice of the state based on props, or to bind action creators to a particular variable from props. If you omit it, `Object.assign({}, ownProps, stateProps, dispatchProps)` is used by default.
6166

62-
* [`options`] *(Object)* If specified, further customizes the behavior of the connector.
63-
* [`pure = true`] *(Boolean)*: If true, implements `shouldComponentUpdate` and shallowly compares the result of `mergeProps`, preventing unnecessary updates, assuming that the component is a “pure” component and does not rely on any input or state other than its props and the selected Redux store’s state. *Defaults to `true`.*
64-
* [`withRef = false`] *(Boolean)*: If true, stores a ref to the wrapped component instance and makes it available via `getWrappedInstance()` method. *Defaults to `false`.*
67+
* [`options`] *(Object)* If specified, further customizes the behavior of the connector. In addition to the options passable to `connectAdvanced()` (see those below), `connect()` accepts these additional options:
68+
* [`pure`] *(Boolean)*: If true, `connect()` will avoid re-renders and calls to `mapStateToProps`, `mapDispatchToProps`, and `mergeProps` if the relevant state/props objects remain equal based on their respective equality checks. Assumes that the wrapped component is a “pure” component and does not rely on any input or state other than its props and the selected Redux store’s state. Default value: `true`
69+
* [`areStatesEqual`] *(Function)*: When pure, compares incoming store state to its previous value. Default value: `strictEqual (===)`
70+
* [`areOwnPropsEqual`] *(Function)*: When pure, compares incoming props to its previous value. Default value: `shallowEqual`
71+
* [`areStatePropsEqual`] *(Function)*: When pure, compares the result of `mapStateToProps` to its previous value. Default value: `shallowEqual`
72+
* [`areMergedPropsEqual`] *(Function)*: When pure, compares the result of `mergeProps` to its previous value. Default value: `shallowEqual`
73+
74+
<a id="connect-arguments-arity"></a>
75+
##### The arity of mapStateToProps and mapDispatchToProps determines whether they receive ownProps
6576

6677
> Note: `ownProps` **is not passed** to `mapStateToProps` and `mapDispatchToProps` if formal definition of the function contains one mandatory parameter (function has length 1). For example, function defined like below won't receive `ownProps` as the second argument.
6778
```javascript
@@ -96,33 +107,26 @@ const mapStateToProps = (...args) => {
96107
}
97108
```
98109

110+
<a id="connect-optimizing"></a>
111+
##### Optimizing connect when options.pure is true
99112

100-
#### Returns
101-
102-
A React component class that injects state and action creators into your component according to the specified options.
103-
104-
##### Static Properties
105-
106-
* `WrappedComponent` *(Component)*: The original component class passed to `connect()`.
107-
108-
##### Static Methods
109-
110-
All the original static methods of the component are hoisted.
113+
When `options.pure` is true, `connect` performs several equality checks that are used to avoid unncessary calls to `mapStateToProps`, `mapDispatchToProps`, `mergeProps`, and ultimately to `render`. These include `areStatesEqual`, `areOwnPropsEqual`, `areStatePropsEqual`, and `areMergedPropsEqual`. While the defaults are probably appropriate 99% of the time, you may wish to override them with custom implementations for performance or other reasons. Here are several examples:
111114

112-
##### Instance Methods
115+
* You may wish to override `areStatesEqual` if your `mapStateToProps` function is computationally expensive and is also only concerned with a small slice of your state. For example: `areStatesEqual: (prev, next) => prev.entities.todos === next.entities.todos`; this would effectively ignore state changes for everything but that slice of state.
113116

114-
###### `getWrappedInstance(): ReactComponent`
117+
* You may wish to override `areStatesEqual` to always return false (`areStatesEqual: () => false`) if you have impure reducers that mutate your store state. (This would likely impact the other equality checks is well, depending on your `mapStateToProps` function.)
115118

116-
Returns the wrapped component instance. Only available if you pass `{ withRef: true }` as part of the `connect()`’s fourth `options` argument.
119+
* You may wish to override `areOwnPropsEqual` as a way to whitelist incoming props. You'd also have to implement `mapStateToProps`, `mapDispatchToProps` and `mergeProps` to also whitelist props. (It may be simpler to achieve this other ways, for example by using [recompose's mapProps](https://github.com/acdlite/recompose/blob/master/docs/API.md#mapprops).)
117120

118-
#### Remarks
121+
* You may wish to override `areStatePropsEqual` to use `strictEqual` if your `mapStateToProps` uses a memoized selector that will only return a new object if a relevant prop has changed. This would be a very slight performance improvement, since would avoid extra equality checks on individual props each time `mapStateToProps` is called.
119122

120-
* It needs to be invoked two times. The first time with its arguments described above, and a second time, with the component: `connect(mapStateToProps, mapDispatchToProps, mergeProps)(MyComponent)`.
123+
* You may wish to override `areMergedPropsEqual` to implement a `deepEqual` if your selectors produce complex props. ex: nested objects, new arrays, etc. (The deep equal check should be faster than just re-rendering.)
121124

122-
* It does not modify the passed React component. It returns a new, connected component, that you should use instead.
125+
#### Returns
123126

124-
* The `mapStateToProps` function takes a single argument of the entire Redux store’s state and returns an object to be passed as props. It is often called a **selector**. Use [reselect](https://github.com/reactjs/reselect) to efficiently compose selectors and [compute derived data](http://redux.js.org/docs/recipes/ComputingDerivedData.html).
127+
A higher-order React component class that passes state and action creators into your component derived from the supplied arguments. This is created by `connectAdvanced`, and details of this higher-order component are covered there.
125128

129+
<a id="connect-examples"></a>
126130
#### Examples
127131

128132
##### Inject just `dispatch` and don't listen to store
@@ -294,3 +298,83 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
294298

295299
export default connect(mapStateToProps, actionCreators, mergeProps)(TodoApp)
296300
```
301+
302+
<a id="connectAdvanced"></a>
303+
### `connectAdvanced(selectorFactory, [connectOptions])`
304+
305+
Connects a React component to a Redux store. It is the base for `connect()` but is less opinionated about how to combine `state`, `props`, and `dispatch` into your final props. It makes no assumptions about defaults or memoization of results, leaving those responsibilities to the caller.
306+
307+
It does not modify the component class passed to it; instead, it *returns* a new, connected component class for you to use.
308+
309+
<a id="connectAdvanced-arguments"></a>
310+
#### Arguments
311+
312+
* `selectorFactory(dispatch, factoryOptions): selector(state, ownProps): props` \(*Function*): Intializes a selector function (during each instance's constructor). That selector function is called any time the connector component needs to compute new props, as a result of a store state change or receiving new props. The result of `selector` is expected to be a plain object, which is passed as the props to the wrapped component. If a consecutive call to `selector` returns the same object (`===`) as its previous call, the component will not be re-rendered. It's the responsibility of `selector` to return that previous object when appropriate.
313+
314+
* [`connectOptions`] *(Object)* If specified, further customizes the behavior of the connector.
315+
316+
* [`getDisplayName`] *(Function)*: computes the connector component's displayName property relative to that of the wrapped component. Usually overridden by wrapper functions. Default value: `name => 'ConnectAdvanced('+name+')'`
317+
318+
* [`methodName`] *(String)*: shown in error messages. Usually overridden by wrapper functions. Default value: `'connectAdvanced'`
319+
320+
* [`renderCountProp`] *(String)*: if defined, a property named this value will be added to the props passed to the wrapped component. Its value will be the number of times the component has been rendered, which can be useful for tracking down unnecessary re-renders. Default value: `undefined`
321+
322+
* [`shouldHandleStateChanges`] *(Boolean)*: controls whether the connector component subscribes to redux store state changes. If set to false, it will only re-render on `componentWillReceiveProps`. Default value: `true`
323+
324+
* [`storeKey`] *(String)*: the key of props/context to get the store. You probably only need this if you are in the inadvisable position of having multiple stores. Default value: `'store'`
325+
326+
* [`withRef`] *(Boolean)*: If true, stores a ref to the wrapped component instance and makes it available via `getWrappedInstance()` method. Default value: `false`
327+
328+
* Addionally, any extra options passed via `connectOptions` will be passed through to your `selectorFactory` in the `factoryOptions` argument.
329+
330+
<a id="connectAdvanced-returns"></a>
331+
#### Returns
332+
333+
A higher-order React component class that builds props from the store state and passes them to the wrapped component. A higher-order component is a function which accepts a component argument and returns a new component.
334+
335+
##### Static Properties
336+
337+
* `WrappedComponent` *(Component)*: The original component class passed to `connectAdvanced(...)(Component)`.
338+
339+
##### Static Methods
340+
341+
All the original static methods of the component are hoisted.
342+
343+
##### Instance Methods
344+
345+
###### `getWrappedInstance(): ReactComponent`
346+
347+
Returns the wrapped component instance. Only available if you pass `{ withRef: true }` as part of the `options` argument.
348+
349+
#### Remarks
350+
351+
* Since it returns a higher-order component, it needs to be invoked two times. The first time with its arguments as described above, and a second time, with the component: `connectAdvanced(selectorFactory)(MyComponent)`.
352+
353+
* It does not modify the passed React component. It returns a new, connected component, that you should use instead.
354+
355+
<a id="connectAdvanced-examples"></a>
356+
#### Examples
357+
358+
##### Inject `todos` of a specific user depending on props, and inject `props.userId` into the action
359+
```js
360+
import * as actionCreators from './actionCreators'
361+
import { bindActionCreators } from 'redux'
362+
363+
function selectorFactory(dispatch) {
364+
let state = {}
365+
let ownProps = {}
366+
let result = {}
367+
const actions = bindActionCreators(actionCreators, dispatch)
368+
const addTodo = (text) => actions.addTodo(ownProps.userId, text)
369+
return (nextState, nextOwnProps) => {
370+
const todos = nextState.todos[nextProps.userId]
371+
const nextResult = { ...nextOwnProps, todos, addTodo }
372+
state = nextState
373+
ownProps = nextOwnProps
374+
if (!shallowEqual(result, nextResult)) result = nextResult
375+
return result
376+
}
377+
}
378+
export default connectAdvanced(selectorFactory)(TodoApp)
379+
```
380+

0 commit comments

Comments
 (0)