Search code examples
javascripthtmlreactjsreact-hooksreact-lifecycle

Why did componentDidMount run after componentWillUnmount?


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


Solution

  • 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