Use Hooks in React Redux
Tags: redux, react, javascript, hooks
Published: 2019-11-10 19:53:45

> PS - This was originally [posted in my blog](https://akhilaariyachandra.com/use-hooks-in-react-redux/). Check it out if you want learn more about React and JavaScript!
> PPS - I got to know about hooks in Redux thanks to Antoine in my previous post. {% user slashgear_ %}

In my [previous post](https://akhilaariyachandra.com/setup-redux-in-a-react-app/) I went through setting up Redux in a React app. Since then I learnt about using hooks as an alternative to the `connect()` Higher Order Component. In this post we will refactor the app we made in the [previous post](https://akhilaariyachandra.com/setup-redux-in-a-react-app/) to use the Redux Hooks.

# Getting Started

Before we start refactoring let's check out the two hooks we are going to use.

- `useSelector` - Allows us to get the state from the Redux store. This hook will be used to replace `mapStateToProps` in `connect()`.
- `useDispatch` - Allows us to dispatch out redux actions. This hook will be used to replace `mapDispatchToProps` in `connect()`.

# Refactoring the Controls Component

First lets remove the props, `connect()` Higher Order Component and `mapStateToProps` and `mapDispatchToProps`.

```jsx
const Controls = () => {
  return (
    <div>
      <button
        onClick={() => actions.setUserId(user.userId - 1)}
        disabled={user.userId <= 1 || user.isFetchingUser}
      >
        Previous
      </button>

      <button
        onClick={() => actions.setUserId(user.userId + 1)}
        disabled={user.userId >= 10 || user.isFetchingUser}
      >
        Next
      </button>
    </div>
  )
}

export default Controls
```

Then we need to import the two hooks from **react-redux**.

```javascript
import { useSelector, useDispatch } from "react-redux"
```

To get the redux state, we need to use `useSelector`. `useSelector` needs a function as an argument where the redux state is the parameter and the return object is the state we need, similar to `mapStateToProps`. So use `useSelector` to declare the user inside the component.

```javascript
const user = useSelector(state => ({ user: state.user }))
```

The above line of code can be shortened to the following.

```javascript
const user = useSelector(state => state.user)
```

To call the redux actions, we need to declare the dispatch function in the component using the `useDispatch` hook. After that we can call out redux actions inside the dispatch function like we did in the `getUser` action.

```javascript
const dispatch = useDispatch()
```

Just change all actions to run inside the `dispatch` function like this.

```javascript
dispatch(setUserId(user.userId - 1))
```

In the end the Controls component should look like this.

```jsx
import React from "react"
import { useSelector, useDispatch } from "react-redux"
import { setUserId } from "../redux/user/actions"

const Controls = () => {
  const user = useSelector(state => state.user)
  const dispatch = useDispatch()

  return (
    <div>
      <button
        onClick={() => dispatch(setUserId(user.userId - 1))}
        disabled={user.userId <= 1 || user.isFetchingUser}
      >
        Previous
      </button>

      <button
        onClick={() => dispatch(setUserId(user.userId + 1))}
        disabled={user.userId >= 10 || user.isFetchingUser}
      >
        Next
      </button>
    </div>
  )
}

export default Controls
```

# Refactoring the Display Component

We need to refactor the Display component the same way we did the Controls component.

- Remove all the `connect()` Higher Order Component related code.
- Import `useSelector` and `useDispatch`.

```javascript
import { useSelector, useDispatch } from "react-redux"
```

- Declare the user state using `useSelector`.

```javascript
const user = useSelector(state => state.user)
```

- Declare the dispatch function using `useDispatch`.

```javascript
const dispatch = useDispatch()
```

- Change all Redux action to be called inside the `dispatch` function.

```javascript
dispatch(getUser(user.userId))
```

In the end the code for the Display component should look like this.

```jsx
import React from "react"
import { useSelector, useDispatch } from "react-redux"
import { getUser } from "../redux/user/actions"

const Display = () => {
  const user = useSelector(state => state.user)
  const dispatch = useDispatch()

  React.useEffect(() => {
    dispatch(getUser(user.userId))
  }, [user.userId])

  return (
    <div>
      <table>
        <tbody>
          <tr>
            <td>ID: </td>
            <td>{user.user.id}</td>
          </tr>

          <tr>
            <td>Name: </td>
            <td>{user.user.name}</td>
          </tr>

          <tr>
            <td>Username: </td>
            <td>{user.user.username}</td>
          </tr>

          <tr>
            <td>Email: </td>
            <td>{user.user.email}</td>
          </tr>
        </tbody>
      </table>
    </div>
  )
}

export default Display
```

# Wrap Up

This is a sample of the setup we just did. If you think you missed something, feel free to check out the code.

{% codesandbox react-redux-hooks-starter-51wxq %}

If you want to learn more about the hooks in **react-redux**, please check out the official documentation [here](https://react-redux.js.org/api/hooks).

If you found this post helpful please make sure to share it! 😊