Redux with React’s Functional Components

How to use Redux’s useSelector and useDispatch hooks

Sean LaFlam
Geek Culture

--

Before reading this you should familiarize yourself with what Redux is and how to use it in React class components.

Setup

Start by creating a new react app. I’ll be using a package called Redux Toolkit to get the shell of the app set up quickly. If you’d like to do the same run:

npx create-react-app my-app --template redux

This creates your React app to use the official template for working with Redux. Then inside your app run:

npm install @reduxjs/toolkit react-redux
npm install redux

At src/app/store.js create the following:

Then, head to index.js and wrap your App component like so:

Now you are all setup.

Counter Component

For this example, we will be creating a simple counter.

When using a Class component, you would see something like this:

This is the standard Redux setup, where we use mapStateToProps to get access to properties on the Redux store available to our component as props, and then dispatch actions to our reducer (also available as props) in order to update those properties.

When using Hooks however we need to do things a little differently.

useSelector

The useSelector hook is how we are going to mimic the mapStateToProps function in our component.

Start by importing useSelector from ‘react-redux’.

import { useSelector} from 'react-redux'

Very similar to the useState hook, you will declare a variable at the top of your component and set it equal to the return value of the useSelector function. The useSelector function takes another function as its parameter. This function will be passed the entire state object as its parameter.

const count = useSelector((state) => state.counter)

So basically, you’re writing a function that has state as its argument and then returns some property off of that state object (in this case the value of the counter). Then, you pass that function to useSelector which is what gives the function access to the state object. Then, you are assigning the return value of your function inside of your function to the variable you declared (in this case count).

Confusing enough for you?

Essentially this:

const mapStateToProps = (state, props) = {  counter: state.counter,  user: state.user}

And this:

const count = useSelector((state) => state.counter)const user = useSelector((state) => state.user)

Are doing the exact same thing with slightly different syntax.

useDispatch

In my opinion, useDispatch is actually much simpler. It reminds me a lot of useHistory.

First, we need to import it:

import { useSelector, useHistory} from 'react-redux'

Then, all you need to do is put this at the top of your component:

const dispatch = useDispatch()

Now, you have a function called dispatch that will send whatever you pass it to the reducer. It’s actually a lot more simple to use than mapDispatchToProps. Just like before we want to import our actions from redux/actions

import { incrementCounter, decrementCounter } from '../redux/actions/counterActions.js'

But instead of doing the whole complicated process of adding these functions to another function, and then mapping that outer function to our props, we can just do this:

onClick={() => dispatch(decrementCounter())}

No props necessary, and we define the function right in our JSX in one line of code!

The final component will look like this:

Notice that we no longer need the connect function at the bottom of our component export to get Redux to work properly.

And there’s a quick intro to using Redux with Hooks!

More content at plainenglish.io

--

--