copenndthagen
copenndthagen

Reputation: 50800

React lifecycle render called before componentDidUpdate

I am slightly confused with the way lifecycle order/execution happens and how things render in the DOM.

So if I take the below example, what I find is after 5 seconds, the control goes to render before it goes to componentDidUpdate. However, in render, it is able to print the updated state value i.e. XYZ even before componentDidUpdate is invoked. So how does this work and while componentDidUpdate says we can access DOM nodes inside it, I somehow was thinking that componentDidUpdate is when the state actually gets updated. Not sure where the difference is in terms of my understanding?

    import React, { Component } from "react";
    
    export default class getSnapshotBeforeUpdateMethod extends Component {
      constructor(props) {
        console.log("1 constructor");
        super(props);
        this.state = {
          name: "ABC"
        };
      }
    
      componentDidMount() {
        console.log("2a componentDidMount");
        setTimeout(() => {
          console.log("2b Inside componentDidMount");
          this.setState({ name: "XYZ" });
        }, 3000);
      }
      getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log("3 getSnapshotBeforeUpdate");
        document.getElementById("previous-state").innerHTML =
          "The previous state was " + prevState.name;
      }
      componentDidUpdate() {
        console.log("4 componentDidUpdate");
        document.getElementById("current-state").innerHTML =
          "The current state is " + this.state.name;
      }
      render() {
        console.log("5 render");
        return (
          <>
            <h5>This is a {this.state.name}</h5>
            <p id="current-state"></p>
            <p id="previous-state"></p>
          </>
        );
      }
    }

Codesandbox link https://codesandbox.io/s/class-lifecycle-method-order-0zjk4?file=/src/App.js:0-1055

Upvotes: 1

Views: 649

Answers (1)

Drew Reese
Drew Reese

Reputation: 203482

Perhaps a review of the react lifecycle diagram may help.

enter image description here

Take note that the render lifecycle method is invoked during the "render phase" when React is rendering out the virtualDOM in order to compute the diff it needs to commit, or flush, to the actual DOM. Note also that the functions/methods during this phase are pure and have no side effects, and may be paused, aborted, or restarted by React (emphasis mine).

Now note that componentDidUpdate occurs during the "commit phase" when the DOM has been updated and rendered.

Your console.log in the render method is an unintentional side-effect, but it's showing you when it was called relative to componentDidUpdate.

render is called once, or possibly multiple times, before componentDidUpdate is called once, per render cycle.

Upvotes: 2

Related Questions