score:2

Accepted answer

Why is it re-rendering like crazy?

I think that is because you are changing the state in the render function so that trigger a side-effect.

I tried using useEffect to fire the event once but that didn't make sense as it fired on componentDidMount which wasn't triggered by the first click.

useEffect its also componentDidUpdate event

And you can handle the event in an auxiliary function "toggle"

function App() {
  const [isOpen, setIsOpen] = useState(false);
  const [counter, setCounter] = useState(0);

  function toggle() {
    if (!isOpen) {
      setCounter(counter + 1);
    }
    setIsOpen(!isOpen);
  }

  useEffect(() => {
    if (counter === 1) {
      doSomething();
    }
  }, [counter]);

  return (
    <div className="App">
      <button onClick={() => toggle()}>Click here</button>
    </div>
  );
}

The "[counter]" says that whenever the counter variable change, the callback function is going to be executed.

 useEffect(() => {
       if (counter === 1) {
         doSomething();
       }
    }, [counter]);

Related Query

More Query from same tag