Using the connect () function from the react-redux package
- Transfer
The article, the translation of which we publish today, will discuss how to create container components in React applications that are related to the state of Redux. This material is based on the description of the state control mechanism in React using the react-redux package . It is assumed that you already have a basic understanding of the architecture and library APIs that we will talk about. If not, refer to the React and Redux documentation .

React provides the developer with two basic mechanisms for transferring data to components. These are properties (props) and state (state). Properties are read-only and allow parent components to pass attributes to child components. A state is a local entity encapsulated inside a component, which can change at any time during the component's life cycle.
Since state is an extremely useful mechanism used to create powerful dynamic React applications, it is necessary to properly manage it. Currently there are several libraries that provide a well-structured architecture for managing the state of applications. Among them - Flux , Redux , MobX .
Redux is a library designed to create containers used to store the state of an application. It offers the developer clear state management tools that behave predictably. This library is suitable for applications written in pure JavaScript, and for projects that have been developed using some frameworks. Redux is small, but it also allows you to write robust applications that work in different environments.
Here's how to create Redux repositories:
The react-redux package provides React bindings for a Redux state container, making it extremely easy to connect a React application to a Redux repository. This allows you to separate the components of a React application based on their connection to the repository. Namely, we are talking about the following types of components:
Details about this approach to the division of responsibility of the components can be found here . In this material, we will mainly talk about container components connected to the state of Redux using react-redux.
The react-redux package has a very simple interface. In particular, the most interesting in this interface comes down to the following:
Install react-redux to use this package in the project as follows:
Based on the assumption that you have already configured the Redux repository for your React application, here is an example of connecting the application to the Redux repository:
Now you can create container components that are connected to the Redux repository. This is done within the hierarchy
As already mentioned, the react-redux API is
If you, in the React component, need to get data from the repository, or you need to dispatch actions, or you need to do both, you can convert a regular component into a container component by wrapping it into a higher-order component returned by a function
You can create the container component yourself and manually sign the component on the Redux repository using the command
In the following example, we are trying to manually create a container component and connect it to the Redux repository, subscribing to it. Here we strive to implement the same functionality, which is shown in the previous example.
The function
If your React application uses multiple Redux repositories, it
The function
Since the function returns a higher-order component, it must be called again, passing the base React component in order to convert it to a container component:
Here is the function signature
An argument
The function is
If a
If it
An argument
Now consider the various uses
If you do not use your own implementation
If an
The following example shows an example of constructing an argument
When using a
If this function returns another function, then the returned function is used in the role
Helper function
The following example illustrates the use, in a role
If an
This function returns a simple object with properties that will be passed to the wrapped component. This is useful for conditional mapping of the state of the Redux repository state or property-based action generators.
If
An optional object passed to the function
Here is the documentation page, after reviewing which, you can find out which parameters you can use with
Before converting a regular React component to a container component using
Suppose that we have a container component
In order for this component to be used in the application, it will be necessary to describe the Redux repository to which this component must be connected. Otherwise, an error will occur. This can be done in two ways, which we will now consider.
The first way to equip a component with Redux storage is to pass a reference to such storage as a value of a
If you want to set up a Redux repository for an application only once, then you will be interested in the method that we will now consider. It is usually suitable for applications that use only one Redux repository.
The react-redux package provides a developer with components
As already mentioned, the functions
However, there is one problem. If the number of required parameters of the declared function is less than 2, then
Consider several options for working with
In this situation, it is
Consider the following example:
Here there is only one option
There is only one mandatory parameter here,
It is all very simple. Namely, in such a situation, a transfer is
Having mastered this material, you learned about when and how to use the API
Dear readers! Do you use the react-redux package in your projects?


About state management in JavaScript applications
React provides the developer with two basic mechanisms for transferring data to components. These are properties (props) and state (state). Properties are read-only and allow parent components to pass attributes to child components. A state is a local entity encapsulated inside a component, which can change at any time during the component's life cycle.
Since state is an extremely useful mechanism used to create powerful dynamic React applications, it is necessary to properly manage it. Currently there are several libraries that provide a well-structured architecture for managing the state of applications. Among them - Flux , Redux , MobX .
Redux is a library designed to create containers used to store the state of an application. It offers the developer clear state management tools that behave predictably. This library is suitable for applications written in pure JavaScript, and for projects that have been developed using some frameworks. Redux is small, but it also allows you to write robust applications that work in different environments.
Here's how to create Redux repositories:
import { createStore } from 'redux';
const initialState = {
auth: { loggedIn: false }
}
const store = createStore((state = initialState, action) => {
switch (action.type) {
case "LOG_IN":
return { ...state, auth: { loggedIn: true } };
break;
case "LOG_OUT":
return { ...state, auth: { loggedIn: false } };
break;
default:
return state;
break;
}
})
React-redux package
The react-redux package provides React bindings for a Redux state container, making it extremely easy to connect a React application to a Redux repository. This allows you to separate the components of a React application based on their connection to the repository. Namely, we are talking about the following types of components:
- Presentation components. They are responsible only for the appearance of the application and are not aware of the state of Redux. They receive data through properties and can call callbacks, which are also passed to them through properties.
- Components containers. They are responsible for the operation of the internal mechanisms of the application and interact with the state of Redux. They are often created using react-redux, they can dispatch Redux actions. In addition, they subscribe to state changes.
Details about this approach to the division of responsibility of the components can be found here . In this material, we will mainly talk about container components connected to the state of Redux using react-redux.
The react-redux package has a very simple interface. In particular, the most interesting in this interface comes down to the following:
<Provider store>
- allows you to create a wrapper for a React application and make Redux state accessible to all container components in its hierarchy.connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
- allows you to create higher order components. This is needed to create container components based on React base components.
Install react-redux to use this package in the project as follows:
npm install react-redux --save
Based on the assumption that you have already configured the Redux repository for your React application, here is an example of connecting the application to the Redux repository:
import React from'react';
import ReactDOM from'react-dom';
import { Provider } from'react-redux';
import createStore from'./createReduxStore';
const store = createStore();
const rootElement = document.getElementById('root');
ReactDOM.render((
<Providerstore={store}>
<AppRootComponent />
</Provider>
), rootElement);
Now you can create container components that are connected to the Redux repository. This is done within the hierarchy
AppRootComponent
using the API connect()
.When do you need to use connect ()?
▍Creation of container components
As already mentioned, the react-redux API is
connect()
used to create container components that are connected to the Redux repository. The storage to which the connection is made is obtained from the uppermost ancestor of the component using the React context mechanism. You connect()
do not need the function if you create only the presentation components. If you, in the React component, need to get data from the repository, or you need to dispatch actions, or you need to do both, you can convert a regular component into a container component by wrapping it into a higher-order component returned by a function
connect()
from react-redux . Here's what it looks like:import React from'react';
import { connect } from'react-redux';
import Profile from'./components/Profile';
function ProfileContainer(props) {
return (
props.loggedIn
? <Profile profile={props.profile} />
: <div>Please logintoview profile.</div>
)
}
const mapStateToProps = function(state) {
return {
profile: state.user.profile,
loggedIn: state.auth.loggedIn
}
}
export defaultconnect(mapStateToProps)(ProfileContainer);
▍ Eliminating the need to manually subscribe to the Redux repository
You can create the container component yourself and manually sign the component on the Redux repository using the command
store.subscribe()
. However, using the function connect()
means applying some improvements and performance optimizations that you may not be able to use when using other mechanisms. In the following example, we are trying to manually create a container component and connect it to the Redux repository, subscribing to it. Here we strive to implement the same functionality, which is shown in the previous example.
import React, { Component } from 'react';
import store from './reduxStore';
import Profile from './components/Profile';
classProfileContainerextendsComponent{
state = this.getCurrentStateFromStore()
getCurrentStateFromStore() {
return {
profile: store.getState().user.profile,
loggedIn: store.getState().auth.loggedIn
}
}
updateStateFromStore = () => {
const currentState = this.getCurrentStateFromStore();
if (this.state !== currentState) {
this.setState(currentState);
}
}
componentDidMount() {
this.unsubscribeStore = store.subscribe(this.updateStateFromStore);
}
componentWillUnmount() {
this.unsubscribeStore();
}
render() {
const { loggedIn, profile } = this.state;
return (
loggedIn
? <Profile profile={profile} />
: <div>Please login to view profile.</div>
)
}
}
export default ProfileContainer;
The function
connect()
, in addition, gives the developer additional flexibility, allowing you to customize container components to obtain dynamic properties based on the properties originally transferred to them. This is very useful for getting samples from a state based on properties, or for binding action generators to a specific variable from properties. If your React application uses multiple Redux repositories, it
connect()
allows you to easily specify the specific repository to which the container component should be connected.Connect () anatomy
The function
connect()
provided by the react-redux package can take up to four arguments, each of which is optional. After calling the function connect()
, a higher-order component is returned, which can be used to wrap any React component. Since the function returns a higher-order component, it must be called again, passing the base React component in order to convert it to a container component:
const ContainerComponent = connect()(BaseComponent);
Here is the function signature
connect()
:connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
MapArgument mapStateToProps
An argument
mapStateToProps
is a function that returns either a regular object or another function. Passing this argument connect()
causes the container component to subscribe to the Redux repository updates. This means that the function mapStateToProps
will be called every time the state of the storage changes. If you are tracking status updates are not interested, pass connect()
the value of this argument undefined
or null
. The function is
mapStateToProps
declared with two parameters, the second of which is optional. The first parameter represents the current state of the Redux repository. The second parameter, if passed, is the object of the properties passed to the component:const mapStateToProps = function(state) {
return {
profile: state.user.profile,
loggedIn: state.auth.loggedIn
}
}
exportdefault connect(mapStateToProps)(ProfileComponent);
If a
mapStateToProps
normal object is returned from , the returned object is stateProps
combined with the properties of the component. You can access these properties in a component like this:functionProfileComponent(props) {
return (
props.loggedIn
? <Profileprofile={props.profile} />
: <div>Please login to view profile.</div>
)
}
If it
mapStateToProps
returns a function, then this function is used as mapStateToProps
for each component instance. This can be useful for improving rendering performance and for memoization.MapArgument mapDispatchToProps
An argument
mapDispatchToProps
can be either an object or a function that returns either a regular object or another function. In order to better illustrate the work mapDispatchToProps
, we need action generators. Suppose we have the following generators:exportconst writeComment = (comment) => ({
comment,
type: 'WRITE_COMMENT'
});
exportconst updateComment = (id, comment) => ({
id,
comment,
type: 'UPDATE_COMMENT'
});
exportconst deleteComment = (id) => ({
id,
type: 'DELETE_COMMENT'
});
Now consider the various uses
mapDispatchToProps
.Standard default implementation
If you do not use your own implementation
mapDispatchToProps
, represented by an object or a function, the standard implementation will be used, using which the storage method is implemented dispatch()
as a property for the component. You can use this property in the component as follows:import React from'react';
import { connect } from'react-redux';
import { updateComment, deleteComment } from'./actions';
functionComment(props) {
const { id, content } = props.comment;
// Вызов действий через props.dispatch()
const editComment = () => props.dispatch(updateComment(id, content));
const removeComment = () => props.dispatch(deleteComment(id));
return (
<div>
<p>{ content }</p>
<buttontype="button"onClick={editComment}>Edit Comment</button>
<buttontype="button"onClick={removeComment}>Remove Comment</button>
</div>
)
}
exportdefault connect()(Comment);
Object transfer
If an
mapDispatchToProps
object is used as an argument , then each function in the object will be interpreted as a Redux action generator and wrapped in a call to the storage method dispatch()
, which will allow it to be called directly. The resulting object with the action generators dispatchProps
will be combined with the properties of the component. The following example shows an example of constructing an argument
mapDispatchToProps
that represents an object with action generators, and how generators can be used as properties of the React component:import React from'react';
import { connect } from'react-redux';
import { updateComment, deleteComment } from'./actions';
functionComment(props) {
const { id, content } = props.comment;
// Действия, представленные свойствами компонента, вызываются напрямую
const editComment = () => props.updatePostComment(id, content);
const removeComment = () => props.deletePostComment(id);
return (
<div>
<p>{ content }</p>
<buttontype="button"onClick={editComment}>Edit Comment</button>
<buttontype="button"onClick={removeComment}>Remove Comment</button>
</div>
)
}
// Объект с генераторами действийconst mapDispatchToProps = {
updatePostComment: updateComment,
deletePostComment: deleteComment
}
exportdefault connect(null, mapDispatchToProps)(Comment);
Transfer function
When using a
mapDispatchToProps
function as an argument, the programmer must independently take care of returning the object dispatchProps
that binds the action generators using the storage method dispatch()
. This function accepts, as the first parameter, a storage method dispatch()
. As in the case of c mapStateToProps
, the function can also take an optional second parameter ownProps
that describes the mapping with the original properties passed to the component. If this function returns another function, then the returned function is used in the role
mapDispatchToProps
, which can be useful for the purposes of improving rendering performance and memoization. Helper function
bindActionCreators()
Redux can be used inside this function to bind action generators to a storage method dispatch()
. The following example illustrates the use, in a role
mapDispatchToProps
, of a function. It also demonstrates bindActionCreators()
how to work with an auxiliary function used to bind action generators to work with comments to props.actions
the React component:import React from'react';
import { connect } from'react-redux';
import { bindActionCreators } from'redux';
import * as commentActions from'./actions';
functionComment(props) {
const { id, content } = props.comment;
const { updateComment, deleteComment } = props.actions;
// Вызов действий из props.actions
const editComment = () => updateComment(id, content);
const removeComment = () => deleteComment(id);
return (
<div>
<p>{ content }</p>
<buttontype="button"onClick={editComment}>Edit Comment</button>
<buttontype="button"onClick={removeComment}>Remove Comment</button>
</div>
)
}
const mapDispatchToProps = (dispatch) => {
return {
actions: bindActionCreators(commentActions, dispatch)
}
}
exportdefault connect(null, mapDispatchToProps)(Comment);
▍Argument mergeProps
If an
connect()
argument is passed to the function mergeProps
, it is a function that takes the following three parameters:stateProps
- the property object returned from the callmapStateToProps()
.dispatchProps
- property object with action generators frommapDispatchToProps()
.ownProps
- the initial properties obtained by the component.
This function returns a simple object with properties that will be passed to the wrapped component. This is useful for conditional mapping of the state of the Redux repository state or property-based action generators.
If
connect()
this function is not passed, then its standard implementation is used:const mergeProps = (stateProps, dispatchProps, ownProps) => {
returnObject.assign({}, ownProps, stateProps, dispatchProps)
}
▍Argument representing an object with parameters
An optional object passed to the function
connect()
as the fourth argument contains parameters intended to change the behavior of this function. So, connect()
is a special implementation of the function connectAdvanced()
, it takes most of the parameters available connectAdvanced()
, as well as some additional parameters. Here is the documentation page, after reviewing which, you can find out which parameters you can use with
connect()
, and how they modify the behavior of this function.Using the connect () Function
▍Create a repository
Before converting a regular React component to a container component using
connect()
, you need to create a Redux repository to which this component will be connected. Suppose that we have a container component
NewComment
that is used to add new comments to a publication, and, in addition, displays a button to send a comment. The code describing this component might look like this:importReact from 'react';
import { connect } from 'react-redux';
classNewCommentextendsReact.Component{
input = null
writeComment = evt => {
evt.preventDefault();
const comment = this.input.value;
comment && this.props.dispatch({ type: 'WRITE_COMMENT', comment });
}
render() {
const { id, content } = this.props.comment;
return (
<div>
<input type="text" ref={e => this.input = e} placeholder="Write a comment" />
<button type="button" onClick={this.writeComment}>SubmitComment</button>
</div>
)
}
}
export default connect()(NewComment);
In order for this component to be used in the application, it will be necessary to describe the Redux repository to which this component must be connected. Otherwise, an error will occur. This can be done in two ways, which we will now consider.
Setting the store property in a container component
The first way to equip a component with Redux storage is to pass a reference to such storage as a value of a
store
component property :import React from'react';
import store from'./reduxStore';
import NewComment from'./components/NewComment';
functionCommentsApp(props) {
return<NewCommentstore={store} />
}
Setting the store property in the <Provider> component
If you want to set up a Redux repository for an application only once, then you will be interested in the method that we will now consider. It is usually suitable for applications that use only one Redux repository.
The react-redux package provides a developer with components
<Provider>
that can be used to wrap the root component of an application. It takes property store
. It is assumed that it is a link to the Redux repository, which is planned to be used in the application. The property is store
passed, in accordance with the application hierarchy, to container components using the React context mechanism:import React from'react';
import ReactDOM from'react-dom';
import store from'./reduxStore';
import { Provider } from'react-redux';
import NewComment from'./components/NewComment';
functionCommentsApp(props) {
return<NewComment />
}
ReactDOM.render((
<Providerstore={store}>
<CommentsApp />
</Provider>
), document.getElementById('root'))
▍Organize access to ownProps
As already mentioned, the functions
mapStateToProps
and mapDispatchToProps
, passed connect()
, can be declared with the second parameter ownProps
, which is the properties of the component. However, there is one problem. If the number of required parameters of the declared function is less than 2, then
ownProps
it will not be transmitted. But if the function is declared with the absence of the required parameters or, at least, with 2 parameters, it ownProps
will be transferred. Consider several options for working with
ownProps
.Function declaration without parameters
const mapStateToProps = function() {
console.log(arguments[0]); // state
console.log(arguments[1]); // ownProps
};
In this situation, it is
ownProps
passed because the function is declared without the required parameters. As a result, the following code written using the new syntax of the remaining ES6 parameters will work:const mapStateToProps = function(...args){
console.log(args[0]); // state
console.log(args[1]); // ownProps
};
Function declaration with one parameter
Consider the following example:
const mapStateToProps = function(state) {
console.log(state); // state
console.log(arguments[1]); // undefined
};
Here there is only one option
state
. As a result, arguments[1]
takes the value undefined
due to the fact that it is ownProps
not transmitted.Function declaration with a default parameter
const mapStateToProps = function(state, ownProps = {}) {
console.log(state); // state
console.log(ownProps); // {}
};
There is only one mandatory parameter here,
state
since the second parameter ownProps
,, is optional due to the fact that it has a default value. As a result, since there is only one mandatory parameter, it is ownProps
not passed, and mapping is performed with the default value that was assigned to it, that is, with an empty object.Function declaration with two parameters
const mapStateToProps = function(state, ownProps) {
console.log(state); // state
console.log(ownProps); // ownProps
};
It is all very simple. Namely, in such a situation, a transfer is
ownProps
made because the function is declared with two mandatory parameters.Results
Having mastered this material, you learned about when and how to use the API
connect()
provided by the react-redux package and designed to create container components that are connected to the Redux state. Here we have described in some detail about the device function connect()
and about working with it, however, if you want to learn more about this mechanism, in particular - to familiarize yourself with the options for using it - take a look at this section of the react-redux documentation. Dear readers! Do you use the react-redux package in your projects?
