according to the doc

If you’re migrating code from a class component, note useLayoutEffect fires in the same phase as componentDidMount and componentDidUpdate. However, we recommend starting with useEffect first and only trying useLayoutEffect if that causes a problem.

So if you want your side effect to run in a class component with the same behaviour you gotta use componentDidMount and componentDidUpdate like you thought. The difference between useEffect and useLayoutEffect is that useEffect only runs after the DOM has been updated (the effect will run after the render is committed to the screen). useLayoutEffect will trigger the effect right after the DOM mutations are computed. Therefore, updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.

Here there's a good explanation about useEffect and useLayoutEffect. But thinking on class components, it's equivalent to componentDidMount and componentDidUpdate because it is the commit phase. That's the phase where changes to DOM are allowed to happen as well as side effects and scheduled updates. Both componentDidMount and componentDidUpdate have the synchronous behaviour just like useLayoutEffect. useEffect is the usual recommended option because it won't block the browser rendering which is better for performance in most cases, being an optimized hook version of componentDidMount and componentDidUpdate.

Answer from Thamy Bessa on Stack Overflow
🌐
Kent C. Dodds
kentcdodds.com › blog › useeffect-vs-uselayouteffect
useEffect vs useLayoutEffect
This can be useful if you need to make DOM measurements (like getting the scroll position or other styles for an element) and then make DOM mutations or trigger a synchronous re-render by updating state. As far as scheduling, this works the same way as componentDidMount and componentDidUpdate.
Discussions

React Hooks and Component Lifecycle Equivalent
What are the equivalents of the componentDidMount, componentDidUpdate, and componentWillUnmount lifecycle hooks using React hooks like useEffect? More on stackoverflow.com
🌐 stackoverflow.com
How to use componentWillMount() in React Hooks?
In the official docs of React it mentions - If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and More on stackoverflow.com
🌐 stackoverflow.com
Why useEffect hook runs before the DOM is loaded?
It works on both componentDidMount and componentDidUpdate lifecycle. ... If you need access to the DOM you can use useLayoutEffect instead. useLayoutEffect runs after any DOM mutations. From the docs: The signature is identical to useEffect, but it fires synchronously after all DOM mutations. More on stackoverflow.com
🌐 stackoverflow.com
react useEffect trigger although dependency value remain the same?
From that same URL: "Tip If you’re migrating code from a class component, note useLayoutEffect fires in the same phase as componentDidMount and componentDidUpdate. More on stackoverflow.com
🌐 stackoverflow.com
August 7, 2019
🌐
Reddit
reddit.com › r/reactjs › react documentation on uselayouteffect makes me confused
r/reactjs on Reddit: React documentation on useLayoutEffect makes me confused
June 27, 2023 -

The legacy documentation has the following note about the useLayoutEffect hook:

If you’re migrating code from a class component, note useLayoutEffect fires in the same phase as componentDidMount and componentDidUpdate. However, we recommend starting with useEffect first and only trying useLayoutEffect if that causes a problem.

And it makes me confused. Both componentDidMount and componentDidUpdate run after render method in a class component. This makes me think that code inside both componentDid... lifecycle methods will run after the UI is already rendered on a screen.

And useLayoutEffect has this in the description:

Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint

Which means "before UI s rendered on a screen", doesn't it? Then how is this possible?

useLayoutEffect fires in the same phase as componentDidMount and componentDidUpdate

Or did I get something wrong?

Top answer
1 of 4
64

componentDidMount

Pass an empty array as the second argument to useEffect() to run only the callback on mount only.

function ComponentDidMount() {
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
    console.log('componentDidMount');
  }, []);

  return (
    <div>
      <p>componentDidMount: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <ComponentDidMount />
  </div>,
  document.querySelector("#app")
);
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

componentDidUpdate

componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render. useEffect runs on every render including the first. So if you want to have a strict equivalent as componentDidUpdate, you have to use useRef to determine if the component has been mounted once. If you want to be even stricter, use useLayoutEffect(), but it fires synchronously. In most cases, useEffect() should be sufficient.

This answer is inspired by Tholle, all credit goes to him.

function ComponentDidUpdate() {
  const [count, setCount] = React.useState(0);

  const isFirstUpdate = React.useRef(true);
  React.useEffect(() => {
    if (isFirstUpdate.current) {
      isFirstUpdate.current = false;
      return;
    }

    console.log('componentDidUpdate');
  });

  return (
    <div>
      <p>componentDidUpdate: {count} times</p>
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <ComponentDidUpdate />,
  document.getElementById("app")
);
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

componentWillUnmount

Return a callback in useEffect's callback argument and it will be called before unmounting.

function ComponentWillUnmount() {
  function ComponentWillUnmountInner(props) {
    React.useEffect(() => {
      return () => {
        console.log('componentWillUnmount');
      };
    }, []);

    return (
      <div>
        <p>componentWillUnmount</p>
      </div>
    );
  }
  
  const [count, setCount] = React.useState(0);

  return (
    <div>
      {count % 2 === 0 ? (
        <ComponentWillUnmountInner count={count} />
      ) : (
        <p>No component</p>
      )}
      <button
        onClick={() => {
          setCount(count + 1);
        }}
      >
        Click Me
      </button>
    </div>
  );
}

ReactDOM.render(
  <div>
    <ComponentWillUnmount />
  </div>,
  document.querySelector("#app")
);
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>

<div id="app"></div>

2 of 4
18

From React docs:

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

By that saying they mean:

componentDidMount is sort of useEffect(callback, [])

componentDidUpdate is sort of useEffect(callback, [dep1, dep2, ...]) - the array of deps tell React: "if one of the deps is change, run the callback after rendering".

componentDidMount + componentDidUpdate is sort of useEffect(callback)

componentWillUnmount is sort of the returned function from the callback:

useEffect(() => { 
    /* some code */
    return () => { 
      /* some code to run when rerender or unmount */
    }
)

With the help of Dan Abramov's phrasing from his blog, and some additions of my own:

While you can use those hooks, it’s not an exact equivalent. Unlike componentDidMount and componentDidUpdate, it will capture props and state. So even inside the callbacks, you’ll see the props and state of the specific render (which means in componentDidMount the initial props and state). If you want to see “latest” something, you can write it to a ref. But there’s usually a simpler way to structure the code so that you don’t have to. The returned function which supposes to be alternative to componentWillUnmount also is not an exact equivalent, since the function will run every time the component will re-render and when the component will unmount. Keep in mind that the mental model for effects is different from component lifecycles, and trying to find their exact equivalents may confuse you more than help. To get productive, you need to “think in effects”, and their mental model is closer to implementing synchronization than to responding to lifecycle events.

Example from Dan's blog:

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

  useEffect(() => {
    setTimeout(() => {
      console.log(`You clicked ${count} times`);
    }, 3000);
  });

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

If we use the class implementation:

componentDidUpdate() {
  setTimeout(() => {
    console.log(`You clicked ${this.state.count} times`);
  }, 3000);
}

this.state.count always points at the latest count rather than the one belonging to a particular render.

🌐
GeeksforGeeks
geeksforgeeks.org › reactjs › reactjs-uselayouteffect-hook
ReactJS useLayoutEffect Hook - GeeksforGeeks
July 23, 2025 - But to prevent blocking the page loading, we should always use the useEffect hook. ... The useLayoutEffect hook works in the same phase as componentDidMount and componentDidUpdate methods.
Top answer
1 of 16
757

You cannot use any of the existing lifecycle methods (componentDidMount, componentDidUpdate, componentWillUnmount etc.) in a hook. They can only be used in class components. And with Hooks you can only use in functional components. The line below comes from the React doc:

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

suggest is, you can mimic these lifecycle method from class component in a functional components.

Code inside componentDidMount run once when the component is mounted. useEffect hook equivalent for this behaviour is

useEffect(() => {
  // Your code here
}, []);

Notice the second parameter here (empty array). This will run only once.

Without the second parameter the useEffect hook will be called on every render of the component which can be dangerous.

useEffect(() => {
  // Your code here
});

componentWillUnmount is use for cleanup (like removing event listeners, cancel the timer etc). Say you are adding a event listener in componentDidMount and removing it in componentWillUnmount as below.

const mouseMoveHandler = () => {}

componentDidMount() {
  window.addEventListener('mousemove', mouseMoveHandler)
}

componentWillUnmount() {
  window.removeEventListener('mousemove', mouseMoveHandler)
}

Hook equivalent of above code will be as follows:

useEffect(() => {
  const mouseMoveHandler = () => {}

  window.addEventListener('mousemove', mouseMoveHandler);

  // returned function will be called on component unmount 
  return () => {
    window.removeEventListener('mousemove', mouseMoveHandler)
  }
}, [])
2 of 16
255

useComponentWillMount hook

const useComponentWillMount = (cb) => {
    const willMount = useRef(true)

    if (willMount.current) cb()

    willMount.current = false
}

This hook could be a saver when there is an issue of sequence (such as running before another script). If that isn't the case, use useComnponentDidMount which is more aligned with React hooks paradigm.

useComponentDidMount hook

const useComponentDidMount = cb => useEffect(cb, []);

If you know your effect should only run once at the beginning use this solution. It will run only once after component has mounted.

useEffect paradigm

Class components have lifecycle methods which are defined as points in the timeline of the component. Hooks don't follow this paradigm. Instead effects should be structured by their content.

function Post({postID}){
  const [post, setPost] = useState({})

  useEffect(()=>{
    fetchPosts(postID).then(
      (postObject) => setPost(postObject)
    )
  }, [postID])

  ...
}

In the example above the effect deals with fetching the content of a post. Instead of a certain point in time it has a value it is dependent on - postID. Every time postID gets a new value (including initialization) it will rerun.

Component Will Mount discussion

In class components componentWillMount is considered legacy (source 1, source2). It's legacy since it might run more than once, and there is an alternative - using the constructor. Those considerations aren't relevant for a functional component.

🌐
DEV Community
dev.to › lawrencespractice › when-to-use-useeffect-and-uselayouteffect-in-react-3n79
When to Use useEffect and useLayoutEffect in React - DEV Community
November 28, 2023 - If you’re migrating code from a class component, note useLayoutEffect fires in the same phase as componentDidMount and componentDidUpdate.
🌐
React
legacy.reactjs.org › docs › hooks-reference.html
Hooks API Reference – React
If you’re migrating code from a class component, note useLayoutEffect fires in the same phase as componentDidMount and componentDidUpdate.
Find elsewhere
🌐
Reacttraining
reacttraining.com › blog › useEffect-is-not-the-new-componentDidMount
useEffect(fn, []) is not the new componentDidMount()
January 31, 2020 - useLayoutEffect was designed to have the same timing as componentDidMount.
🌐
React
legacy.reactjs.org › docs › hooks-effect.html
Using the Effect Hook – React
The majority of effects don’t need to happen synchronously. In the uncommon cases where they do (such as measuring the layout), there is a separate useLayoutEffect Hook with an API identical to useEffect.
🌐
KnowledgeHut
knowledgehut.com › home › blog › web development › react uselayouteffect() - hook api reference in react
React useLayoutEffect() - Hook API Reference In React
April 25, 2024 - The only caveat is that this occurs ... the browser from painting. In contrast, componentDidMount and componentDidUpdate run synchronously after rendering in-class components....
🌐
Medium
medium.com › @alexandereardon › uselayouteffect-and-ssr-192986cdcf7a
useLayoutEffect and SSR. How to get warning free usage of… | by Alex Reardon | Medium
April 29, 2019 - They are a replacement for thecomponentDidMount, componentDidUpdate and componentWillUnmount lifecycle methods on class components. Kent C. Dodds has put together a great guide on when to use useEffect and when to use useLayoutEffect. TLDR: most of the time you will want useEffect · useLayoutEffect is put forward as the safest upgrade path for class components · useLayoutEffectfires in the same phase as componentDidMount and componentDidUpdate — React Documentation
Top answer
1 of 2
5

(1)first useEffect call is when component mount.

useEffect(() => {
    console.log('log')
  }, [test])

(2)if you pass second Array dependencies argument to useEffect and that argument wasn't empty, any time one of that dependency changes useEffect also recalled.

useEffect(() => {
    console.log('log')
  }, [test])

(3) if array of dependencies was empty, useEffect only one time called(after component mount for first time).

useEffect(() => {
    console.log('log')
  }, [])

(4)if useEffect implementing without second argument any time component state update useEffect also called.

useEffect(() => {
    console.log('log')
  })

for your situation you can check if test is 0 cancel execute useEffect body code like this:

function App() {
  const [test, setTest ] = useState(0)

  useEffect(() => {
   if(test < 1) return;
    console.log('log')
  }, [test])


  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}
2 of 2
3

From https: Using the Effect Hook

What does useEffect do? By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates.

Your component rendered, useEffect triggered, and your log ran.

It sounds like you might be confusing useEffect (which only takes a single argument, a callback) with other hooks that take multiple arguments.

---- EDIT (Comments-Related) ----

useEffect is not a direct replacement for class-based componentDidMount and componentDidUpdate methods, but because of the timing of when it runs it can often be used to replace those methods. See for further info. You may also want to read about the related useLayoutEffect hook.

If your intent is to hook up some logic "on load", such as an event handler, you don't need a hook to do that. Instead you just need a React event handler attribute, eg.

<option onChange={changeHandler} />

(See for further info.)

🌐
Talent500
talent500.com › blog › useeffect-vs-uselayouteffect-in-react
useEffect vs useLayoutEffect in React: Key Differences and Best Practices
September 15, 2022 - One thing to keep in mind is that ... is different from how class components behave, where componentDidUpdate and componentDidMount run synchronously following the rendering....
🌐
GitHub
github.com › facebook › react › issues › 14927
useLayoutEffect in ssr · Issue #14927 · facebook/react
February 22, 2019 - Also, the documentation states that useLayoutEffect runs on the same phase as componentDidMount (that is, on the client side), and here my server issues complaints to me about my code.
Author   dimensi
🌐
Reddit
reddit.com › r/reactjs › difference between uselayouteffect and useeffect
r/reactjs on Reddit: Difference between useLayoutEffect and useEffect
August 22, 2021 - After React has updated the DOM ... nodes and component instances. It then synchronously runs the componentDidMount and componentDidUpdate class lifecycle methods, and the useLayoutEffect hooks....
🌐
Reddit
reddit.com › r/reactjs › when to use useeffect or uselayouteffect
r/reactjs on Reddit: When to use useEffect or useLayoutEffect
February 15, 2020 - From the react official docs: "Unlike componentDidMount and componentDidUpdate, the function passed to useEffect fires after layout and paint, during a deferred event.
🌐
Telerik
telerik.com › blogs › uselayouteffect-powerful-hook
useLayoutEffect Is a Powerful Hook
May 17, 2022 - We have the componentDidMount lifecycle method that runs when the component is created and inserted into the DOM. ... We have the componentDidUpdate lifecycle method that runs after some update occurs in our component.