Makes the Redux store available to the connect()
calls in the component hierarchy below. Normally, you can’t use connect()
without wrapping a parent or ancestor component in <Provider>
.
If you really need to, you can manually pass store
as a prop to every connect()
ed component, but we only recommend to do this for stubbing store
in unit tests, or in non-fully-React codebases. Normally, you should just use <Provider>
.
store
(Redux Store): The single Redux store in your application.children
(ReactElement) The root of your component hierarchy.
ReactDOM.render(
<Provider store={store}>
<MyRootComponent />
</Provider>,
rootEl
)
ReactDOM.render(
<Provider store={store}>
<Router history={history}>
<Route path="/" component={App}>
<Route path="foo" component={Foo}/>
<Route path="bar" component={Bar}/>
</Route>
</Router>
</Provider>,
document.getElementById('root')
)
Connects a React component to a Redux store. connect
is a facade around connectAdvanced
, providing a convenient API for the most common use cases.
It does not modify the component class passed to it; instead, it returns a new, connected component class for you to use.
-
[
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 ofmapStateToProps
must be a plain object*, which will be merged into the component’s props. If you don't want to subscribe to store updates, passnull
orundefined
in place ofmapStateToProps
. IfownProps
is specified as a second argument, its value will be the props passed to your component, andmapStateToProps
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).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 asmapStateToProps()
for a particular component instance. This allows you to do per-instance memoization. You can refer to #279 and the tests it adds for more details. Most apps never need this.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 to efficiently compose selectors and compute derived data. -
[
mapDispatchToProps(dispatch, [ownProps]): dispatchProps
] (Object or Function): If an object is passed, each function inside it is assumed to be a Redux action creator. An object with the same function names, but with every action creator wrapped into adispatch
call so they may be invoked directly, will be merged into the component’s props. If a function is passed, it will be givendispatch
. If you don't want to subscribe to store updates, passnull
orundefined
in place ofmapStateToProps
. It’s up to you to return an object that somehow usesdispatch
to bind action creators in your own way. (Tip: you may use thebindActionCreators()
helper from Redux.) If you omit it, the default implementation just injectsdispatch
into your component’s props. IfownProps
is specified as a second argument, its value will be the props passed to your component, andmapDispatchToProps
will be re-invoked whenever the component receives new props.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 asmapDispatchToProps()
for a particular component instance. This allows you to do per-instance memoization. You can refer to #279 and the tests it adds for more details. Most apps never need this. -
[
mergeProps(stateProps, dispatchProps, ownProps): props
] (Function): If specified, it is passed the result ofmapStateToProps()
,mapDispatchToProps()
, and the parentprops
. 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. -
[
options
] (Object) If specified, further customizes the behavior of the connector. In addition to the options passable toconnectAdvanced()
(see those below),connect()
accepts these additional options:- [
pure
] (Boolean): If true,connect()
will avoid re-renders and calls tomapStateToProps
,mapDispatchToProps
, andmergeProps
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
- [
areStatesEqual
] (Function): When pure, compares incoming store state to its previous value. Default value:strictEqual (===)
- [
areOwnPropsEqual
] (Function): When pure, compares incoming props to its previous value. Default value:shallowEqual
- [
areStatePropsEqual
] (Function): When pure, compares the result ofmapStateToProps
to its previous value. Default value:shallowEqual
- [
areMergedPropsEqual
] (Function): When pure, compares the result ofmergeProps
to its previous value. Default value:shallowEqual
- [
Note:
ownProps
is not passed tomapStateToProps
andmapDispatchToProps
if formal definition of the function contains one mandatory parameter (function has length 1). For example, function defined like below won't receiveownProps
as the second argument.
function mapStateToProps(state) {
console.log(state); // state
console.log(arguments[1]); // undefined
}
const mapStateToProps = (state, ownProps = {}) => {
console.log(state); // state
console.log(ownProps); // undefined
}
Functions with no mandatory parameters or two parameters will receive ownProps
.
const mapStateToProps = (state, ownProps) => {
console.log(state); // state
console.log(ownProps); // ownProps
}
function mapStateToProps() {
console.log(arguments[0]); // state
console.log(arguments[1]); // ownProps
}
const mapStateToProps = (...args) => {
console.log(args[0]); // state
console.log(args[1]); // ownProps
}
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:
-
You may wish to override
areStatesEqual
if yourmapStateToProps
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. -
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 yourmapStateToProps
function.) -
You may wish to override
areOwnPropsEqual
as a way to whitelist incoming props. You'd also have to implementmapStateToProps
,mapDispatchToProps
andmergeProps
to also whitelist props. (It may be simpler to achieve this other ways, for example by using recompose's mapProps.) -
You may wish to override
areStatePropsEqual
to usestrictEqual
if yourmapStateToProps
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 timemapStateToProps
is called. -
You may wish to override
areMergedPropsEqual
to implement adeepEqual
if your selectors produce complex props. ex: nested objects, new arrays, etc. (The deep equal check should be faster than just re-rendering.)
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.
export default connect()(TodoApp)
import * as actionCreators from './actionCreators'
export default connect(null, actionCreators)(TodoApp)
Don’t do this! It kills any performance optimizations because
TodoApp
will rerender after every action.
It’s better to have more granularconnect()
on several components in your view hierarchy that each only
listen to a relevant slice of the state.
export default connect(state => state)(TodoApp)
function mapStateToProps(state) {
return { todos: state.todos }
}
export default connect(mapStateToProps)(TodoApp)
import * as actionCreators from './actionCreators'
function mapStateToProps(state) {
return { todos: state.todos }
}
export default connect(mapStateToProps, actionCreators)(TodoApp)
import * as actionCreators from './actionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return { actions: bindActionCreators(actionCreators, dispatch) }
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
import { addTodo } from './actionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({ addTodo }, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return {
todoActions: bindActionCreators(todoActionCreators, dispatch),
counterActions: bindActionCreators(counterActionCreators, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(Object.assign({}, todoActionCreators, counterActionCreators), dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
import * as todoActionCreators from './todoActionCreators'
import * as counterActionCreators from './counterActionCreators'
import { bindActionCreators } from 'redux'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(Object.assign({}, todoActionCreators, counterActionCreators), dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(TodoApp)
import * as actionCreators from './actionCreators'
function mapStateToProps(state, ownProps) {
return { todos: state.todos[ownProps.userId] }
}
export default connect(mapStateToProps)(TodoApp)
import * as actionCreators from './actionCreators'
function mapStateToProps(state) {
return { todos: state.todos }
}
function mergeProps(stateProps, dispatchProps, ownProps) {
return Object.assign({}, ownProps, {
todos: stateProps.todos[ownProps.userId],
addTodo: (text) => dispatchProps.addTodo(ownProps.userId, text)
})
}
export default connect(mapStateToProps, actionCreators, mergeProps)(TodoApp)
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.
It does not modify the component class passed to it; instead, it returns a new, connected component class for you to use.
-
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 ofselector
is expected to be a plain object, which is passed as the props to the wrapped component. If a consecutive call toselector
returns the same object (===
) as its previous call, the component will not be re-rendered. It's the responsibility ofselector
to return that previous object when appropriate. -
[
connectOptions
] (Object) If specified, further customizes the behavior of the connector.-
[
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+')'
-
[
methodName
] (String): shown in error messages. Usually overridden by wrapper functions. Default value:'connectAdvanced'
-
[
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
-
[
shouldHandleStateChanges
] (Boolean): controls whether the connector component subscribes to redux store state changes. If set to false, it will only re-render oncomponentWillReceiveProps
. Default value:true
-
[
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'
-
[
withRef
] (Boolean): If true, stores a ref to the wrapped component instance and makes it available viagetWrappedInstance()
method. Default value:false
-
Addionally, any extra options passed via
connectOptions
will be passed through to yourselectorFactory
in thefactoryOptions
argument.
-
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.
WrappedComponent
(Component): The original component class passed toconnectAdvanced(...)(Component)
.
All the original static methods of the component are hoisted.
Returns the wrapped component instance. Only available if you pass { withRef: true }
as part of the options
argument.
-
Since
connectAdvanced
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)
. -
connectAdvanced
does not modify the passed React component. It returns a new, connected component, that you should use instead.
import * as actionCreators from './actionCreators'
import { bindActionCreators } from 'redux'
function selectorFactory(dispatch) {
let ownProps = {}
let result = {}
const actions = bindActionCreators(actionCreators, dispatch)
const addTodo = (text) => actions.addTodo(ownProps.userId, text)
return (nextState, nextOwnProps) => {
const todos = nextState.todos[nextProps.userId]
const nextResult = { ...nextOwnProps, todos, addTodo }
ownProps = nextOwnProps
if (!shallowEqual(result, nextResult)) result = nextResult
return result
}
}
export default connectAdvanced(selectorFactory)(TodoApp)