DEV Community

Cover image for React counter component two different ways - useReducer and customHooks.
Agw-a
Agw-a

Posted on

React counter component two different ways - useReducer and customHooks.

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

import React, {useReducer} from 'react'
Enter fullscreen mode Exit fullscreen mode

Then we shall create a single object that will contain all definitions of the application's initial state.

const  initialState = {count:0}
Enter fullscreen mode Exit fullscreen mode

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.

const  [state, dispatch] = useReducer(reducer, initialState);
Enter fullscreen mode Exit fullscreen mode

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.

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
    }


Enter fullscreen mode Exit fullscreen mode

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:

const reducer = (state, action) => {
    switch(action.type) {

      case 'Increase':
        return {count: state.count + 1}

    }

    const IncreaseCount = () => {
    dispatch({type: 'Increase'})
  }
Enter fullscreen mode Exit fullscreen mode

Putting it all together

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;
Enter fullscreen mode Exit fullscreen mode

customHooks

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

import  {useState} from 'react'
Enter fullscreen mode Exit fullscreen mode

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.

import  {useState} from 'react'

const CounterCustomHook = () => {
    const [state, setState] = useState(0);
Enter fullscreen mode Exit fullscreen mode

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;

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;
Enter fullscreen mode Exit fullscreen mode

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.

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;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)