0

I know that calling setState() immediately in componentDidMount() is a performance issue and it is better to use the constructor in some cases.

But in the last sentence of the React documentation it talks about a USE CASE that states that calling setState() immediately in componentDidMount() if it is VIABLE, what does THAT USE CASE mean.

Documentation React:

You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the constructor() instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.

I would like an simple example (with code), PLEASE, because I have not been able to see it in words alone

1 Answers1

0

Sometimes you might need access to the DOM elements managed by React—for example, to focus a node, scroll to it, or measure its size and position. There is no built-in way to do those things in React, so you will need a ref to the DOM node. During the first render, the DOM nodes have not yet been created, so ref.current will be null. And during the rendering of updates, the DOM nodes haven’t been updated yet. So it’s too early to read them. This is why sometimes you have to wait to read ref and set state in componentDidMount, or in useEffect for functionnal components

Example to get the height of an element:

class DivSize extends Component {

  constructor(props) {
    super(props)

    this.state = {
      height: 0
    }
  }

  componentDidMount() {
    const height = this.divElement.clientHeight;
    this.setState({ height });
  }

  render() {
    return (
      <div 
        ref={ (divElement) => { this.divElement = divElement } }
      >
        Size: <b>{this.state.height}px</b> but it should be 18px after the render
      </div>
    )
  }
}
Reifocs
  • 704
  • 3
  • 16
  • Ok, great @Calfut, if you have the possibility you could give me a simple example in code. –  Sep 20 '22 at 11:54
  • 2
    added example.. – Reifocs Sep 20 '22 at 12:12
  • Ok, great @Calfut, so, with that clientHeight, for example, can I now ALREADY create a "final-definitive" state that is based on the DOM measurements? –  Sep 20 '22 at 12:46
  • and the last one: Is THIS WAY (with refs) of obtaining the measurements reliable, i.e. are they the actual measurements as seen on the screen, right? –  Sep 20 '22 at 12:47
  • And I say "final-definitive state" because the height: 0(intermediate state in this case) will never be SEEN by the user ACCORDING TO THE DOCUMENTATION. –  Sep 20 '22 at 12:49
  • 2
    Yes it's reliable, this is the equivalent to the querySelector from the DOM API, and yeah you should use this pattern to measure DOM elements in react. – Reifocs Sep 20 '22 at 12:57
  • 2
    If the reason why you have to do it like this is still unclear to you, I suggests that you read this https://beta.reactjs.org/learn/render-and-commit#step-3-react-commits-changes-to-the-dom – Reifocs Sep 20 '22 at 12:59
  • Thanks @Calfut, now it's ALL clear to me about componentDidMount(), it was the ONLY thing I was missing to understand, that last statement of documentation. I'll look at the link you posted, I think I could use more details on how the DOM is drawn. Done, marked as best answer –  Sep 20 '22 at 13:07