3

I am trying to grab the difference between componentDidMount and componentWillUnmount and tried the following code :


class App extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      name: "",
    };
  }

  componentDidMount() {
    console.log("Inside componentDidMount");
  }

  componentWillUnmount() {
    console.log("Inside ComponentWillUnMount");
  }

  render() {
    return (
      <div className="App">
        {console.log("I am in render")}
        <header className="App-header">
          <input
            type="text"
            value={this.state.name}
            onChange={(e) => this.setState({ name: e.target.value })}
            placeholder="enter your name"
          />
          <p>Edit and save to reload.</p>
        </header>
      </div>
    );
  }
}

My understanding so far is

  1. componentDidMount will be called after the component is mounted and called only once even after any number of re-renders ( please correct me if I am wrong here)
  2. componentWillUnmount will be called once when the component is getting unmount.

But I observed in the console that componentDidMount is being called after render which is expected and but also after componentWillUnMount.

My questions are :

  1. Why is componentWillUnMount called as I have only App component and no other components to render and I am still on the first screen? Why should App component be unmounted as I am still on that screen where I can see what App component contains ( which is the input )

  2. why did componentDidMount run after componentWillUnMount ?

and why do we need to call super() with props inside the constructor?

Result with Class component

I even tried the above code with a functional component using useEffect and the result is the same.

const AppSample = () => {
    useEffect(() => {
        console.log('I am in useEffect');
        return () => {
            console.log("Inside clean up function")
        }
    }, []);

    const [name , setName ] = useState('')

    return  (
        <div>
        {
            console.log(" I am inside render")
        }
            <input value={ name } onChange={(e) => setName(e.target.value)} />
        </div>
    )
}

console.log('I am in running') is printed twice ie., once after rendering and another after the cleanup function is executed

Result With functional component

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • 1
    I think the persorn answering should also clear the air around functional component use case with useEffect as well. – reciever Apr 21 '22 at 09:44

2 Answers2

2

You must have <StrictMode> enabled in your index.js file.

Replace <StrictMode> with <>

Then You'll find that render() and componentDidMount are fired only once in your App component and componentWillUnmount will not fire unless App component is unmounted

reference on Strict Mode: https://github.com/facebook/react/issues/12856#issuecomment-613145789

Kritish Bhattarai
  • 1,501
  • 15
  • 20
1

here is explain:

componentWillUnmount This method is called when a component is being removed/updated from the DOM.

Here is detailed diagram how lifecycle works:1

So you can see after first render and before ComponentDidMount react does update of DOM and after this update componentWillUnmount will be triggered.

We can discuss this if you want or if I miss something here, but this is my opinion about this.

Best regards and hope it helps

  • But why did React call `componentDidMount` even after `componentWillUnMount` ? – React Learner Apr 21 '22 at 10:01
  • As I know lifecycle is next: 1. Construct 2. Render 3. componentDidMount Because Render (Updates/Removes) DOM it will fire componentWillUnMount before componentDidMount As kritiz sad you can disable this behavior by changing strict mode settings. This will solve your problem – Matic Stare Apr 21 '22 at 10:52