Reactjs.org: clarify when componentDidUpdate fires

Created on 23 Aug 2018  路  5Comments  路  Source: reactjs/reactjs.org

Re-posting this issue from facebook/react:
https://github.com/facebook/react/issues/2796

https://reactjs.org/docs/react-component.html#componentdidupdate is unclear on when it is called with regards to the render function.

The docs state that it's "Invoked immediately after updating occurs" but it is unclear what is meant with updating in this case: it can refer to either the component as a whole updating (meaning post-render), or it can refer to setState() having been processed (which might mean pre-render).

It would be good to explicitly state when this function fires in its documentation (even if somewhere else on the site this is described in text or graphic form already).

There was a PR for this that was merged at one point: https://github.com/facebook/react/pull/2801

But the current website does not include this change. I believe the language from the above PR is still correct and would be helpful to people since it's more specific than what's there currently.

Most helpful comment

I have a similar question: does componentDidUpdate() fire after every render, or only renders that result in an actual change to the DOM? e.g. if the virtual DOM is the same as the actual DOM, then componentDidUpdate() still fire?

All 5 comments

I have a similar question: does componentDidUpdate() fire after every render, or only renders that result in an actual change to the DOM? e.g. if the virtual DOM is the same as the actual DOM, then componentDidUpdate() still fire?

The suggested change to the docs was:

Invoked immediately after the component's updates are flushed to the DOM. This method is not called for the initial render.

This seems to not be quite correct however. For example, the DOM for this component should never change (at least in theory):

class Test extends React.Component {
    componentDidUpdate(prevProps) {
        console.log('componentUpdated', prevProps, this.props)
    }

    render() {
        return <div>hi</div>
    }
}

...but componentDidUpdate() still fires if there are prop or state changes. e.g.:

class App extends React.Component {
    state = {
        foo: 1
    }

    componentDidMount() {
        setTimeout(() => {
            this.setState({ foo: 2 })
        })
    }

    render() {
        <Test foo={this.state.foo} />
    }
}

I am not an expert on the componentDidUpdate; all I know is that it would be helpful for the docs to be more explicit about when it fires. Hopefully someone with more knowledge -- or someone who takes the time to research it -- can open a PR to address this. (But FYI, there is a long backlog of un-reviewed PRs in this repo [including one of my own, unrelated to this issue], so unfortunately the docs probably won't be updated anytime soon even if someone does create a PR.)

It seems to be the case that componentDidUpdate() fires after every render() (except the first one), regardless of whether the actual DOM is updated or not. That might well be the desired behavior (since I guess it's possible for render() to be called, not actually update the DOM, but you'd still want to fire off a network request in componentDidUpdate(), for example.

I don't fully understand your second example. With the setTimeout() are you incrementing the value of this.state.foo, or are you saying that if you call setState() where you're not actually changing any of the values of the state object, that both render() and componentDidUpdate() are called?

I edited my above comment to show a full code example.

Right, now it makes more sense. And yeah, I think it is the case that componentDidUpdate() fires after every render(), even though it's not super clear in the docs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gajomon picture gajomon  路  4Comments

tajo picture tajo  路  4Comments

msert29 picture msert29  路  5Comments

grundmanise picture grundmanise  路  5Comments

ahtee picture ahtee  路  4Comments