useEffect with an empty array is not componentDidMount

An effect with an empty dependency array runs once after the first render, which resembles a mount hook and differs in when it fires and what it can see.

useEffect(() => {
  // runs AFTER paint. componentDidMount ran before it.
}, [])

useLayoutEffect(() => {
  // runs before paint — this is the closer analogue,
  // and it blocks the browser, so use it only for
  // measurements that would otherwise flash.
}, [])

// and the empty array is a claim: this effect reads
// nothing from props or state. the linter checks it.

The difference matters for anything measuring the DOM: an effect that reads a height and sets state causes a visible flicker, because the browser painted the first value. The empty array is also a lie in most of the code that has one — it usually reads a prop, and the exhaustive-deps rule flags it, and the flag is disabled with a comment. Reading the comment is nearly always instructive.