Understanding the useReducer hook in React
Tags: react, javascript, codenewbie, webdev
Published: 2021-07-10 06:17:16

##What is useReducer?
useReducer is one of the additional hooks that shipped with React 16.8 . It is an alternative to `useState` hook and helps in managing complex state logic that involves multiple sub-values or when the next state depends on the previous one. When combined with `useContext` and other hooks, it can be a good alternative to redux.
Also, `useReducer` also lets you optimize performance for components that trigger deep updates because you can pass dispatch down instead of callbacks.

##How to use useReducer hook? 
Just like any other hook in React, you first need to import it from react.
``` javascript
  import {useReducer} from 'react';
```
Now, just like the `useState` hook, `useReducer` hook also returns two things in an Array : the current state value and a `dispatch` function to which you can pass an action and invoke later.
``` javascript
const [state, dispatch] = useReducer(reducer, initialState)
``` 
We use Array destructuring to get the state and dispatch.
The `useReducer` takes two parameters. The first one is the reducer function and second is the initialState. 

## Reducer Function : 
A "reducer" is generally a function that accepts two parameters and returns a single value.
A simple example would be the reducer function that we pass to the `reduce()` method in JavaScript.
```javascript
let array = [1, 2, 3];
let reducer = (total, number) => {
  return total + number;
}
let sum = array.reduce(reducer, 0);
console.log(sum) // 6
```

The Reducer function that we pass to `useReducer` is also similar.


```javascript
const initialState = { count: 0 }
 // The reducer function

function countReducer(state, action) {
  switch (action.type) {
    case 'INCREMENT':
      return { count: state.count + 1 }
    case 'DECREMENT':
      return { count: state.count - 1 }
    case 'RESET':
      return {count: state.count = 0}
    default:
     return { count: state.count  }
  }
}
```
The reducer function above takes two parameters, first is the current state and second is the action which tells us the operation to be performed. 
Here, we have used a `Switch` Statement and based on the value of `action.type` we perform the corresponding operation on the state.

##Dispatching the action
Now, in order to call the Reducer function to perform an operation on the state we use the `dispatch` function.
```javascript
export function Counter() {
  const [state, dispatch] = useReducer(countReducer, initialState)

  return (
    <div>
      Count: {state.count}
       <button onClick={() => dispatch({ type: 'INCREMENT'})}>+</button>
       <button onClick={() => dispatch({ type: 'DECREMENT'})}>-</button>
       <button onClick={() => dispatch({ type: 'RESET'})}>Reset</button>
    </div>
  );
};
```
When we call the `dispatch` function, the current state is automatically passed as the first argument. Therefore, we only pass the action object, which has the type of action we want to perform on the state.

##Conclusion:
The above example is a basic implementation of useReducer. However, it can be used to perform complex state logic. In that case, both our state and action objects will be a collection of many key value pairs.

In my next blog, I will explain on how to use `useReducer` with `useContext` for global state management.

I hope you learnt a lot from this blog. Try implementing what you have learnt in your projects. If you enjoyed this post, I’d be very grateful if you’d share it. Comment below if you have any doubts or questions.

Thank you for Reading!