1

Problem

When the button is clicked, the output of the ref current value is skipped. Please refer to the output below for reference. However if the toggle.current = current + 1 is outside of the useState callback, it worked as accordingly.

Code

import "./styles.css";
import { useState, useRef } from "react";

export default function App() {
  const [array, setArray] = useState(["a"]);
  const toggle = useRef(1);

  const handleChange = () => {
    setArray((a) => {
      let current = toggle.current;
      console.log(current);
      toggle.current = current + 1;
      return [...a, "a"];
    });
  };

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <button onClick={() => handleChange()}>hi</button>
    </div>
  );
}

Desired Output

1
2
3
4
5
6

Actual Output

1
2
4
6
8
Will Lim
  • 11
  • 2

1 Answers1

5

You must be using StrictMode.

StrictMode will intentionally double invoke "render" and some other lifecycle methods to detect side-effects. Strict mode checks are run in development mode only; they do not impact the production build.

Here is a code snippet / demo.

Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87