ReactLogo

Getting Started with Redux: Connecting Redux with React

This is the third part of the series on Getting Started with Redux and in this tutorial, we’re going to learn how to connect a Redux store with React.  Redux is an independent library that works with all the popular front-end libraries & frameworks. And it works flawlessly with React because of its functional approach.

You don’t need to have followed the previous parts of this series for this tutorial to make sense. If you’re here to learn about using React with Redux, you can take the Quick Recap below and then check out the code from the previous part and start from there. 

Quick Recap

In the first post, we learned about the Redux workflow and answered the question, Why Redux?. We created a very basic demo application and showed you how the various components of Redux—actions, reducers, and the store— are connected.

In the previous post, we started building a contact list application that lets you add contacts and then displays them as a list. A Redux store was created for our contact list and we added a few reducers and actions. We attempted to dispatch actions and retrieve the new state using store methods like store.dispatch() and store.getState().

By the end of this article, you’ll learn

  1. the difference between container components and presentational components
  2. about the react-redux library
  3. how to bind react and redux using connect()
  4. how to dispatch actions using mapDispatchToProps
  5. how to retrieve state using mapStateToProps

The code for the tutorial is available on GitHub at the react-redux-demo repo. Grab the code from the v2 branch and use that as a starting point for this tutorial. If you’re curious to know how the application looks by the end of this tutorial, try the v3 branch. Let’s get started.

Designing a Component Hierarchy: Smart vs. Dumb Component

This is a concept that you’ve probably heard of before. But let’s have a quick look at the difference between smart and dumb components. Recall that we had created two separate directories for components, one named containers/, and the other components/. The benefit of this approach is that the behavior logic is separated from the view.

The presentational components are said to be dumb because they are concerned about how things look. They are decoupled from the business logic of the application and receive data and callbacks from a parent component exclusively via props. They don’t care if your application is connected to a Redux store if the data is coming from the local state of the parent component. 

The container components, on the other hand, deal with the behavioral part and should contain very limited DOM markup and style. They pass the data that needs to be rendered to the dumb components as props. 

I’ve covered the topic in-depth in another tutorial, Stateful vs. Stateless Components in React.

  • React
    Stateful vs. Stateless Functional Components in React
    Manjunath M

Moving on, let’s see how we’re going to organize our components.

Designing component Hierarchy

Presentational Components

Here are the presentational components that we’ll be using in this tutorial. 

components/AddContactForm.jsx

This is an HTML form for adding a new contact. The component receives onInputChange and onFormSubmit callback as props. The onInputChange event is triggered when the input value changes and onFormSubmit when the form is being submitted.

components/ContactList.jsx

This component receives an array of contact objects as props and hence the name ContactList. We use the Array.map() method to extract individual contact details and then pass on that data to .

components/ContactCard.jsx

This component receives a contact object and displays the contact’s name and image. For practical applications, it might make sense to host JavaScript images in the cloud.

Container Components

We’re also going to construct barebones container components.

containers/Contacts.jsx

The returnContactList() function retrieves the array of contact objects and passes it to the ContactList component. Since returnContactList() retrieves the data from the store, we’ll leave that logic blank for the moment.

containers/AddContacts.jsx

We’ve created three barebones handler method that corresponds to the three actions. They all dispatch actions to update the state. In the render method, we’ve left out the logic for showing/hiding the form because we need to fetch the state. 

Now let’s see how to bind react and redux together

The react-redux Library

React bindings are not available in Redux by default. You will need to install an extra library called react-redux first. 

The library exports just two APIs that you need to remember, a component and a higher-order function known as connect()

The Provider Component

Libraries like Redux need to make the store data accessible to the whole React component tree starting from the root component. The Provider pattern allows the library to pass the data from top to the bottom. The code below demonstrates how Provider magically adds the state to all the components in the component tree. 

Demo Code

The entire app needs to have access to the store. So, we wrap the provider around the app component and then add the data that we need to the tree’s context. The descendants of the component then have access to the data. 

The connect() Method 

Now that we’ve provided the store to our application, we need to connect the React to the store. The only way that you can communicate with the store is by dispatching actions and by retrieving the state. We’ve previously used store.dispatch() to dispatch actions and store.getState() to retrieve the latest snapshot of the state. The connect()lets you do exactly this, but with the help of two methods known as mapDispatchToProps and mapStateToProps. I have demonstrated this concept in the example below:

Demo Code

mapStateToProps and mapDispatchToProps both return an object and the key of this object becomes a prop of the connected component. For instance, state.contacts.newContact is mapped to props.newContact. The action creator addContact() is mapped to props.addContact.  

But for this to work, you need the last line in the code snippet above. 

Instead of exporting the AddContact component directly, we’re exporting a connected component. The connect provides addContact and newContact as props to the component. 

How to Connect React and Redux?

Next, we’re going to cover the steps that you need to follow to connect React and Redux.

Install the react-redux Library

Install the react-redux library if you haven’t already. You can use NPM or Yarn to install it. 

Provide the Store to your App Component

Create the store first. Then, make the store object accessible to your component tree by passing it as a prop to .

index.js

Connect React Containers to Redux

The connect function is used to bind React container to Redux. What that means is that you can use the connect feature to:

  1. subscribe to the store and map its state to your props
  2. dispatch actions and map the dispatch callbacks into your props

Once you’ve connected your application to Redux, you can use this.props to access the current state and also to dispatch actions. I am going to demonstrate the process on theAddContact component. AddContact needs to dispatch three actions and get the state of two properties from the store. Let’s have a look at the code.

First, import connect into AddContact.jsx.

Second, create two methods mapStateToProps and mapDispatchToProps.

mapStateToProps receives the state of the store as an argument. It returns an object that describes how the state of the store is mapped into your props. mapDispatchToProps returns a similar object that describes how the dispatch actions are mapped to your props. 

Finally, we use connect to bind the AddContact component to the two functions as follows:

Update the Container Components to Use the Props

The component’s props are now equipped to read state from the store and dispatch actions. The logic for handeInputChange, handleSubmit and showAddContactBox should be updated as follows:

We’ve defined the handler methods. But there is still one part missing—the conditional statement inside the render function.

If isHidden is false, the form is rendered. Otherwise,a button gets rendered. 

Displaying The Contacts

We’ve completed the most challenging part. Now, all that’s left is to display these contacts as a list. The Contacts container is the best place for that logic. 

We’ve gone through the same procedure that we followed above to connect the Contacts component with the Redux store. The mapStateToProps function maps the store object to the contactList props. We then use connect to bind the props value to the Contact component. The second argument to the connect is null because we don’t have any actions to be dispatched. That completes the integration of our app with the state of the Redux store. 

What Next?

In the next post, we’ll take a deeper look at middlewares and start dispatching actions that involve fetching data from the server. Share your thoughts in the comments!

Powered by WPeMatico

Leave a Comment

Scroll to Top