DEV Community

Cover image for How To Implement & Set Input Value with React Hooks in a Counter Application.
Adebayo Pokanu
Adebayo Pokanu

Posted on

How To Implement & Set Input Value with React Hooks in a Counter Application.

Hi techies!
In this post, I will be putting you through on how to implement set value function with input tag and button using the following React Hooks: useState, useRef and useReducer.

We will be working on two counters; one will be controlled by useState hook while the other will be controlled by useReducer hook.
The counters will be having the following functions:

  • Increment
  • Decrement
  • Reset
  • Set Value/handleClick
  • handleOnChange

Counter 1: useState Hook
The first thing to do here is to import the useState hook from react.

import {useState} from "react";
Enter fullscreen mode Exit fullscreen mode

After importing the useState hook, the next thing to do is to set it up.

useState accepts two argument. The first one is a value to store the data of the state while the second argument is a function to update the data in the state value. We also set the default value to zero.

const [count, setCount] = useState(defaultValue || 0);
Enter fullscreen mode Exit fullscreen mode

Functions and buttons
Now, we need to set the functions and buttons.
Before setting anything, we need to import one more hook – useRef hook. This hook is needed for our Set Value function and input tag.

import { useState, useRef } from "react";
Enter fullscreen mode Exit fullscreen mode

After importing, we set it up by declaring an inputRef value and initialize it to null.

const inputRef = useRef(null);
Enter fullscreen mode Exit fullscreen mode

Declaring the functions

const increment = () => setCount((countValue) => countValue + 1);
const decrement = () => setCount((countValue) => countValue - 1);
const setValue = () => setCount(inputRef.current.value - `${count}`);
const reset = () => setCount(defaultValue);
Enter fullscreen mode Exit fullscreen mode

N.B: In the set value function, we use template literal to deduct count from inputRef.current.value so that when the inputed value is set to the count variable, and the increment or decrement button is triggered, it will update the count state starting from the inputed value instead of displaying the two values together.

Final code set up.

import { useState, useRef } from "react";

export default function App(defaultValue) {
 const [count, setCount] = useState(defaultValue || 0);
 const inputRef = useRef(null);

 const increment = () => setCount((countValue) => countValue + 1);
 const decrement = () => setCount((countValue) => countValue - 1);
 const setValue = () => setCount(inputRef.current.value - `${count}`);
 const reset = () => setCount(defaultValue);

return (
      <>
        <div className="counter__wrapper">
         <div className="counter-box">{count}</div>

          <div className="counter-btn-wrapper">
           <button
            disabled={count >= 20}
            className="counter__btn operation-btn"
            onClick={increment}
          > + </button>

          <button className="reset-btn" onClick={reset}>
            Reset
          </button>

          <button
            disabled={count <= 0}
            className="counter__btn operation-btn"
            onClick={decrement}
          > - </button>
        </div>
        <div className="set__value">
          <div className="input__value">
            <input ref={inputRef} name="number" type="text" placeholder="0" />
          </div>
          <button onClick={setValue}>Set Value</button>
        </div>
      </div>
   </>

)
}
Enter fullscreen mode Exit fullscreen mode

Counter 2: useReducer Hook
As usual, we import useReducer from react.

import { useReducer } from "react";
Enter fullscreen mode Exit fullscreen mode

Declare a default/initial state variable.
Initialize it with a counter object set to zero and input object set to empty string.

const defaultState = { counter: 0, input: "" };
Enter fullscreen mode Exit fullscreen mode

OR

const initialState = { counter: 0, input: "" };
Enter fullscreen mode Exit fullscreen mode

Note: You can declare your own preferred variable name.

Declare a reducer function with a switch statement.
In the statement, we will be having five (5) cases and a default. The five (5) cases are:

  • “increment”: to update the state of the counter by adding + 1
  • “decrement”: to update the state of the counter by subtracting -1
  • “reset”: to return the state of the counter to default value 0
  • “setvalue”: to update the state of the input value to whatever the user inputs
  • “updatecounter”: to update the state of the counter to the current value in the input
const defaultState = { counter: 0, input: "" };
const reducer = (state = { name: "" }, action) => {
  switch (action.type) {
    case "increment":
      return { ...state, counter: state.counter + 1 };
    case "decrement":
      return { ...state, counter: state.counter - 1 };
    case "reset":
      return defaultState;
    case "setvalue":
      return { ...state, input: action.payload };
    case "updatecounter":
      return { ...state, counter: action.payload };
    default:
      throw new Error("Invalid action type");
  }
};
Enter fullscreen mode Exit fullscreen mode

Functions

  • increment with dispatch type set to “increment”
  • decrement with dispatch type set to “decrement”
  • reset with dispatch type set to “reset”
  • handleOnChange with event (e) in the call back function and - dispatch type set to “setvalue”. It will also have a payload set to e.target.value
  • handleClick with dispatch type set to “updatecounter”. The payload will be set to state.input and deducting the counter with a _template literal _
dispatch({
      type: "updatecounter",
      payload: state.input - `${state.counter}`,
    });
Enter fullscreen mode Exit fullscreen mode

so that when the inputed value is set to the counter, and the increment or decrement is triggered, it will update the counter state starting from the inputed value instead of displaying the two values together.

Final code set up.

import { useReducer } from "react";

const defaultState = { counter: 0, input: "" };

const reducer = (state = { name: "" }, action) => {
  switch (action.type) {
    case "increment":
      return { ...state, counter: state.counter + 1 };
    case "decrement":
      return { ...state, counter: state.counter - 1 };
    case "reset":
      return defaultState;
    case "setvalue":
      return { ...state, input: action.payload };
    case "updatecounter":
      return { ...state, counter: action.payload };
    default:
      throw new Error("Invalid action type");
  }
};

export default function App() {
  const [state, dispatch] = useReducer(reducer, defaultState);

  const handleClick = () => {
    dispatch({
      type: "updatecounter",
      payload: state.input - `${state.counter}`,
    });
  };

  const increment = () => {
    dispatch({ type: "increment" });
  };

  const decrement = () => {
    dispatch({ type: "decrement" });
  };

  const reset = () => {
    dispatch({ type: "reset" });
  };

  const handleOnChange = (e) => {
    dispatch({ type: "setvalue", payload: e.target.value });
  };
return (
      <>
        <div className="counter-box">
            {state.counter}
          </div>

        <div className="counter-btn-wrapper">
          <button
            disabled={state.counter >= 20}
            className="counter__btn operation-btn"
            onClick={increment}
          > + </button>

          <button className="reset-btn" onClick={reset}>
            Reset
          </button>

          <button
            disabled={state.counter <= 0}
            className="counter__btn operation-btn"
            onClick={decrement}
          > - </button>
        </div>

        <div className="set__value">
          <div className="input__value">
            <input
              onChange={handleOnChange}
              value={state.input}
              name="number"
              type="text"
              placeholder="0"
            />
          </div>
          <button onClick={handleClick}>Set Value</button>
        </div>
      </>
)
};
Enter fullscreen mode Exit fullscreen mode

That will be all for now.
Check out for the full code and style implementation in my github repo

You can as well follow me on twitter

Top comments (0)