React counter component two different ways - useReducer and customHooks.
Tags: react, hooks, javascript
Published: 2023-01-08 19:52:58

Whenever we need to implement custom logic into a react application,  `useReducer` is the way to go. For this simple counter component, we would want to give the user freedom to add custom input values to increase or decrease a number. `customHooks` also enable expanding and sharing custom logic across a react application. We shall see in this tutorial how both hooks can be used to build a simple counter component.

### useReducer
`useReducer` is used to manage state in a react application i.e it handles multiple states across a single react application in a simple and clean way. For the purose of this tutorial we shall use `reducer` to implement three features in the counter;
* **Increase count**
* **Decrease count**
* **Reset count** 
* **Add a preset value**

First import `useReducer` function from react library
``` javascript
import React, {useReducer} from 'react'
```

Then we shall create a single object that will contain all definitions of the application's initial state.
``` javascript
const  initialState = {count:0}
```

 Then with javascript array destructuring, define the `useReducer` function  that takes into consideration `state` and `dispatch`. `state` returns the current state while `dispatch` updates the current state.
``` javascript
const  [state, dispatch] = useReducer(reducer, initialState);
```

The next step is to define the reducer function that takes tow parameters `state` and  `action`. The first parameter `state` that defines the current state of the application while `action` is the current action to perform to update state.

``` javascript
const reducer = (state, action) => {
    switch(action.type) {
        
      case 'Increase':
        return {count: state.count + 1}
        
      case 'Decrease':
        return {count: state.count - 1}
        
          case 'Plus10':
        return {count: state.count + 10}
  
      case 'Minus10':
        return {count: state.count - 10} 
  
      case 'BackToZero':
        return {count: state.count * 0} 
      default:
        return state
    }

  
```

Next we will call each function  in the main react component using the dispatch function, for instance in the increase function that increses the value of the count by 1, increase function is called as follows: 


``` javascript
const reducer = (state, action) => {
    switch(action.type) {
        
      case 'Increase':
        return {count: state.count + 1}
        
    }

    const IncreaseCount = () => {
    dispatch({type: 'Increase'})
  }
```
**Putting it all together**

``` javascript
import React, {useReducer} from 'react'

const reducer = (state, action) => {
    switch(action.type) {
        
      case 'Increase':
        return {count: state.count + 1}
        
      case 'Decrease':
        return {count: state.count - 1}
        
          case 'Plus10':
        return {count: state.count + 10}
  
      case 'Minus10':
        return {count: state.count - 10} 
  
      case 'BackToZero':
        return {count: state.count * 0} 
      default:
        return state
    }

  }
  const  initialState = {count:0}
  

const Counter = () => {

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

  const IncreaseCount = () => {
    dispatch({type: 'Increase'})
  }
    const DecreaseCount = () => {
    dispatch({type: 'Decrease'})
  }
    const IncreaseBy10 = () => {
    dispatch({type: 'Plus10'})
  }
    const DecreaseBy10 = () => {
    dispatch({type: 'Minus10'})
  }
  const ResetValue = () => {
    dispatch({type: 'BackToZero'})
  }

  return (
    
          <div className='counter'>
    
    <div className='count-label'>
    <p>Count: {state.count}</p>
    </div>
      <div className='count-buttons'>
      <button onClick={DecreaseCount}>-</button>
      <button onClick={IncreaseBy10}>+10</button>
      <button onClick={ ResetValue} >reset</button>
      <button onClick={DecreaseBy10}>-10</button>
      <button onClick={IncreaseCount}>+</button>
      </div>

    </div>
    
  )
}

export default Counter;
```

### customHooks
We will build the custom counter hook with `useState` , the first requirement therefore is to import it from the react library as below.

``` javascript
import  {useState} from 'react'
```
We will use a single function to create the component. First call useState and define the to parameters that will handle the current state and hold the state as it updates.

``` javascript
import  {useState} from 'react'

const CounterCustomHook = () => {
    const [state, setState] = useState(0);
```

Next we'll create functions that will handle the increase, decrease, reset and custom values. Here you are free to expand the function logic to fit the needs of your application. The customHook return statements will return an array of all the defined states and the state variable.
The updated function should look as below;

``` javascript
import  {useState} from 'react'

const CounterCustomHook = () => {
    const [state, setState] = useState(0);

  const increament = () => {
  setState(state => state + 1)
}
  const decreament = () => {
    setState(state => state - 1)
  }
  const addTen = () => {
    setState(state => state + 2)
  }
  const resetValue = () => {
    setState(0)
  }
  const removeTen =() =>{
    setState(state => state - 10)
  }
  return(
    [state, increament, decreament, addTen,resetValue, removeTen]
  )
    
}

export default CounterCustomHook;
```

**Rendering the custom Hook**

To render the custom hook, create a  react component and import the previous hook created. The import statement depends on your folder structure.


``` javascript
import React from 'react'


import CounterCustomHook from '../hooks/counterCustomHook'

const UseCounterHook = () => {
  const [state, increament, decreament, addTen,resetValue] = CounterCustomHook()
  return (
<div className='card-holder'>
  <div id='custom-hookcard'>

  
    <div className='counter'>
    
    <div id='count-label'>
    <h4>Custom Service queue</h4>
    <p>Secure a spot in the queue!</p>
    <h4>Count: {state}</h4>
    </div>
      <div className='count-buttons' id='single-buttons'>
      <button onClick={increament}>+</button>
      <button onClick={addTen}> Get +2 </button>
      <button onClick={resetValue}>reset</button>
      {/* <button onClick={removeTen}>-10</button> */}
      <button onClick={decreament} >-</button>
      
      </div>
      
    </div>
    </div>
    </div> 
    )
}

export default UseCounterHook;
```