Using the useState() hook in React.js

OpenJavaScript 0

Last updated: September 27, 2022.

The useState() hook is used to trigger a re-rendering of the DOM each time the value of a variable changes.

Table of contents

Without useState()

The following code block does not use the useState() hook:

function App() {
  
  let counter = 0;

  function incrementByOne() {
    counter++;
    console.log(counter);
  };

  return (
    <div>
      <span>{counter}</span><br/>
      <button onClick={() => { incrementByOne() }}>Click me</button>
    </div>
  );
}

export default App;

When the user clicks on the button, the value of the counter increases by one. But this does not trigger a re-rendering of the DOM. So the value of counter in the DOM remains 0.

Triggering DOM re-rendering with useState()

If the value of a variable is initialized using the useState() hook, a change in its value will trigger a re-rendering of the DOM.

To use useState(), you first need to import it from the "react" library.

Then, inside array destructuring syntax, choose a variable name and a function name for updating the value of the variable. Finally, you assign a starting value to the variable by calling useState().

Now, when you want to update the value of the variable, call the updating function name, passing in the new value. This will trigger a DOM re-render.

For example, here is a working example of a counter:

import { useState } from "react";

function App() {
  // Create 'counter' variable, updating function named 'setCounter' and initial value of 0
  let [counter, setCounter] = useState(0);

  function incrementByOne() {
    counter++;
    setCounter(counter);
    console.log(counter);
  };

  return (
    <div>
      <span>{counter}</span><br/>
      <button onClick={() => { incrementByOne() }}>Click me</button>
    </div>
  );
}

export default App;

Multiple state values

You can use useState() more than once.

When the value of a state variable is updated, React will update the DOM to take this into account.

import { useState } from "react";

function App() {
  
  let [counter, setCounter] = useState(0);
  let [counter2, setCounter2] = useState(0);

  function incrementByOne(counterName) {
    if (counterName === "counter") {
      counter++
      setCounter(counter)
    } else if (counterName === "counter2") {
      counter2++
      setCounter2(counter2)
    }
  };

  return (
    <div>
      <span>{counter}</span>
      <button onClick={() => { incrementByOne("counter") }}>Update counter</button><br/>
      <span>{counter2}</span>
      <button onClick={() => { incrementByOne("counter2") }}>Update counter2</button>
    </div>
  );
}

export default App;

Why not directly update the DOM?

You could update the value in the DOM directly. But using useState() has two key advantages.

First, if you pass the value of the variable initialized with state into another component, it will trigger a re-render there also. So, using useState() allows you to update the value and trigger re-renders across all components of your React app.

Second, the efficiency of React derives from allowing it to make DOM updates in the most efficient way possible. To fully utilize the power of React, direct intervention in the DOM should be avoided.

Related links

React.js documentation: Using the State Hook