componentDidMount equivalent on a React function/Hooks component?

JavascriptReactjsReact Hooks

Javascript Problem Overview


Are there ways to simulate componentDidMount in React functional components via hooks?

Javascript Solutions


Solution 1 - Javascript

For the stable version of hooks (React Version 16.8.0+)

For componentDidMount

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

For componentDidUpdate

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

For componentWillUnmount

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

So in this situation, you need to pass your dependency into this array. Let's assume you have a state like this

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

And whenever count increases you want to re-render your function component. Then your useEffect should look like this

useEffect(() => {
  // <div>{count}</div>
}, [count]);

This way whenever your count updates your component will re-render. Hopefully this will help a bit.

Solution 2 - Javascript

There is no exact equivalent for componentDidMount in react hooks.


In my experience, react hooks requires a different mindset when developing it and generally speaking you should not compare it to the class methods like componentDidMount.

With that said, there are ways in which you can use hooks to produce a similar effect to componentDidMount.

Solution 1:

useEffect(() => {
  console.log("I have been mounted")
}, [])

Solution 2:

const num = 5

useEffect(() => {
  console.log("I will only run if my deps change: ", num)
}, [num])

Solution 3 (With function):

useEffect(() => {
  const someFunc = () => {
    console.log("Function being run after/on mount")
  }
  someFunc()
}, [])

Solution 4 (useCallback):

const msg = "some message"

const myFunc = useCallback(() => {
  console.log(msg)
}, [msg])

useEffect(() => {
  myFunc()
}, [myFunc])

Solution 5 (Getting creative):

export default function useDidMountHook(callback) {
  const didMount = useRef(null)

  useEffect(() => {
    if (callback && !didMount.current) {
      didMount.current = true
      callback()
    }
  })
}

It is worth noting that solution 5 should only really be used if none of the other solutions work for your use case. If you do decide you need solution 5 then I recommend using this pre-made hook use-did-mount.

Source (With more detail): Using componentDidMount in react hooks

Solution 3 - Javascript

There's no componentDidMount on functional components, but React Hooks provide a way you can emulate the behavior by using the useEffect hook.

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

Please read the documentation on useEffect.

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>

Solution 4 - Javascript

useEffect() hook allows us to achieve the functionality of componentDidMount, componentDidUpdate componentWillUnMount functionalities.

Different syntaxes of useEffect() allows to achieve each of the above methods.

i) componentDidMount

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

ii) componentDidUpdate

useEffect(() => {
  //code here
}, [x,y,z]);

//where x,y,z are state variables on whose update, this method should get triggered

iii) componentDidUnmount

useEffect(() => {
  //code here
  return function() {
    //code to be run during unmount phase
  }
}, []);

You can check the official react site for more info. Official React Page on Hooks

Solution 5 - Javascript

Although accepted answer works, it is not recommended. When you have more than one state and you use it with useEffect, it will give you warning about adding it to dependency array or not using it at all.

It sometimes causes the problem which might give you unpredictable output. So I suggest that you take a little effort to rewrite your function as class. There are very little changes, and you can have some components as class and some as function. You're not obligated to use only one convention.

Take this for example

function App() {
  const [appointments, setAppointments] = useState([]);
  const [aptId, setAptId] = useState(1);

  useEffect(() => {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = aptId;
          console.log(aptId);
          setAptId(aptId + 1);
          return item;
        })
        setAppointments(apts);
      });
  }, []);

  return(...);
}

and

class App extends Component {
  constructor() {
    super();
    this.state = {
      appointments: [],
      aptId: 1,
    }
  }

  componentDidMount() {
    fetch('./data.json')
      .then(response => response.json())
      .then(result => {
        const apts = result.map(item => {
          item.aptId = this.state.aptId;
          this.setState({aptId: this.state.aptId + 1});
          console.log(this.state.aptId);
          return item;
        });
        this.setState({appointments: apts});
      });
  }

  render(...);
}

This is only for example. so lets not talk about best practices or potential issues with the code. Both of this has same logic but the later only works as expected. You might get componentDidMount functionality with useEffect running for this time, but as your app grows, there are chances that you MAY face some issues. So, rather than rewriting at that phase, it's better to do this at early stage.

Besides, OOP is not that bad, if Procedure-Oriented Programming was enough, we would never have had Object-Oriented Programming. It's painful sometimes, but better (technically. personal issues aside).

Solution 6 - Javascript

ComponentDidMount

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

Solution 7 - Javascript

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>
  );
}

Please visit this official docs. Very easy to understand the latest way.

https://reactjs.org/docs/hooks-effect.html

Solution 8 - Javascript

Info about async functions inside the hook:

Effect callbacks are synchronous to prevent race conditions. Put the async function inside:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
}, [someId]); // Or [] if effect doesn't need props or state

Solution 9 - Javascript

useLayoutEffect hook is the best alternative to ComponentDidMount in React Hooks.

useLayoutEffect hook executes before Rendering UI and useEffect hook executes after rendering UI. Use it depend on your needs.

Sample Code:

import { useLayoutEffect, useEffect } from "react";

export default function App() {
  useEffect(() => {
    console.log("useEffect Statements");
  }, []);

  useLayoutEffect(() => {
    console.log("useLayoutEffect Statements");
  }, []);
  return (
    <div>
      <h1>Hello Guys</h1>
    </div>
  );
}
 

Solution 10 - Javascript

You want to use useEffect(), which, depending on how you use the function, can act just like componentDidMount().

Eg. you could use a custom loaded state property which is initially set to false, and switch it to true on render, and only fire the effect when this value changes.

Documentation

Solution 11 - Javascript

the exact equivalent hook for componentDidMount() is

useEffect(()=>{},[]);

hope this helpful :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjeykoView Question on Stackoverflow
Solution 1 - JavascriptMertcan DikenView Answer on Stackoverflow
Solution 2 - JavascriptAtomictsView Answer on Stackoverflow
Solution 3 - JavascriptYangshun TayView Answer on Stackoverflow
Solution 4 - JavascriptVanmeeganathan P KView Answer on Stackoverflow
Solution 5 - JavascriptAniket KariyaView Answer on Stackoverflow
Solution 6 - JavascriptMD SHAYONView Answer on Stackoverflow
Solution 7 - JavascriptPankaj KumarView Answer on Stackoverflow
Solution 8 - JavascriptzemilView Answer on Stackoverflow
Solution 9 - JavascriptSmack AlphaView Answer on Stackoverflow
Solution 10 - JavascriptmarkmoxxView Answer on Stackoverflow
Solution 11 - JavascriptAravinthView Answer on Stackoverflow