1

This example is given in the react documentation to describe the use of useEffect.

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

Could this not be re-written without using useEffect as below? Why is useEffect preferred?

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  const handleChange = () => {
      setCount(count + 1);
      document.title = `You clicked ${count} times`;
  }

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={handleChange}>
        Click me
      </button>
    </div>
  );
}
Sam Archer
  • 149
  • 2
  • 10

1 Answers1

1

There are two issues here:

  • Calling a state setter won't reassign the stateful const variable in the current render - you need to wait until the next render for count to be updated, so

    const handleChange = () => {
        setCount(count + 1);
        document.title = `You clicked ${count} times`;
    }
    

    won't work. Your second snippet will result in You clicked 0 times after a single click.

  • Even if that were possible, when there are multiple places where a state setter may be called, putting something that should happen afterwards after every single one isn't very maintainable - it'd be better to be able to put that code to run afterwards in only one place.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Great answer, thanks. I fully understand your second bullet point. For the first one, how come '

    You clicked {count} times

    ' does update correctly?
    – Sam Archer Dec 05 '21 at 04:24
  • @SamArcher You can think of `setState` functions [as being async](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous). If `count` happened to be updated before setting the document title, that was incidental (not guaranteed). If you need to work with an updated value in the same scope as your `setState` call, you should use a different variable than the `state` value. – jsejcksn Dec 05 '21 at 04:54