ReactJS all hooks series: UseReducer in action.
Tags: javascript, webdev, react, redux
Published: 2022-01-21 14:31:11

To be honest, I am tired of counter-app examples.

I had to step on and write this article to demonstrate to react beginners a real use case of `useReducer()` because I am sure you are tired of the counter app examples too. No?

In this article, we'll discuss what  is `useReducer()`, its syntax, and implement it to create an effect of a well-known website (spoiler, it's Pinterest).

Prerequisite? Basic ReactJS and to know what is "state". Are you familiar with Redux or not? It doesn't matter. Optionally, it's good to know the reduce() method. Here's a small [post that explains it in a nutshell.](https://dev.to/amiinequ/javascripts-reduce-method-in-a-nutshell-gik)

So this article is for beginners who are into React hooks.

Before we proceed I would like to state that I am jobless for the moment and I am looking for a remote frontend job position. How can you help? Refer my [portfolio](https://amhoume.com) to someone who's looking for a frontend developer, less than that, you can share my article.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/E2CMs3zElINbc4pNC7/giphy.gif">



Thank you and let's go.

#What is useReducer() hook?



It's all about state management. `useReducer()` is an alternative to `useState()`. We use it to handle complex state logic because it gives us the ability to handle complex state logic that involves sub-values or when the next state depends on the previous one.


Here's the syntax:

```
import { useReducer } from 'react';

const initialState = SomeValue;

const reducer = (state, action) => {
    switch(action)
      case 'toClick':
         return newState
    default:
      throw new Error("Unexpected action");
}

function ComponentA() {

      const [actualState, dispatch] = useReducer(reducer, initialState);

      return (
           <button onClick={() => dispatch('toClick')}>
                Click me
           </button>
           );
}
```

We import `useReducer`, then we have the `initialState` which is the default value of the state.

Also, the reducer function takes two arguments: The state and an action and contains a switch statement. 

In case the action is 'toClick' we will do something to the state and return it. But where? Now comes the hook itself.

`const [actualState, dispatch] = useReducer(reducer, initialState);`

`useReducer()` returns an array of two values:
 * the state ( where we save our calculated value from the switch statement).
 * A dispatch() method. 

The `useReducer()` hook itself takes two arguments: the reducer function and the initial state of which we defined before.

The `useReducer()` takes the `initailState` and passes it to the reducer function through the state argument and whatever it returns, it saves it inside the `actualState`.

In programming, everything is confusing until explained with a real example.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hxla5f51pqthce0tkycq.png)


#A Real use case.



So I decided to work on a Pinterest clone. It turns out that the home page has this effect where four buttons represents four themes.


<img width="100%" style="width:100%" src="https://media.giphy.com/media/6cVo7eXTaaVC0SE8Dg/giphy.gif">


So I have four buttons and each click changes the state of four elements:

* the color for the buttons.
* The theme title.
* The background pictures.
* The color arrow down button

Let's go.

The default text is "Weeknight dinner" so I created a theme named `dinner` with the color of `darkYello`, so my initial state is going to be an object with three states: The color, the text, and the theme.



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2rzuhzk8ae7psuof5l0a.png)


Next is the dispatcher:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1uymf2fax6gd4uhr3wb9.png)

It acts like the usual `setState` but instead, it sets an action. 

Here, we have four buttons, each one has a dispatch function with an `action` as an object which contains the action's type.

Now the reducer function:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qr46cf9x0mb3hlragmwd.png)

It takes two arguments: the state and the action.

We defined a switch statement because we have multiple actions. So, in case the user clicked on the button with the dispatcher `green`,  the case `green` will be triggered and change the state of Color, text, and theme.

Now the `useReducer()` hook.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y9s6ulan9yxrhjf0npg2.png)

It takes the reducer function defined earlier and the initial state and returns an array. The returned array contains an object of the states: text, theme, and color, not to forget the dispatch method.

Here's how I am implementing it in the JSX.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fnj1ozwm3mgocqzg3k5m.png)

PS: I am using TailwindCSS.

If the state is `darkYello`, then the background is `bg-darkYello`, if it's blue or green then the background is going to be gray.

And for the title.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0bn56tjgyjmt4716afnu.png)

I am just placing the state text and if's null it will display "Weeknight dinner" as a default value.


#A wrap up!
 
<img width="100%" style="width:100%" src="https://media.giphy.com/media/2aI0NbmSnKo9R4NgFE/giphy.gif">



The user will click on a button and the dispatch function will be triggered with an action, The reducer function will take that action plus the current state (if it's the first time, then it will take the initial state) and compare the action's type with all the cases, if one is found it will do the logic and assign the result to the states defined in the `useReducer()` hook, if no, it will return a state or throw an exception.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/lmvMgBJU9oRZxmTljV/giphy.gif">

Is that it? 

Well! yes, but actually no. 

It's time for you to practice. If you have a dummy react project that uses `useState`, try it to replace it with useReducer.

The goal was to make you understand the `useReducer()` hook without using the counter app example.


I hope that you enjoyed the article and if so, please don't forget to share it. Also, feel free to add a comment if you see that I forgot to mention something important. 

Thank you.