22

I'm on a situation where I want to make some dom-node size calculations (top, bottom and size properties of the rendered DOM node)

What I'm doing right now, on the componentDidUpdate method is to call findDOMNode on this:

 componentDidUpdate() {
        var node = ReactDOM.findDOMNode(this);

        this.elementBox = node.getBoundingClientRect();
        this.elementHeight = node.clientHeight;
        // Make calculations and stuff
}

This is working fine, but I'm a bit worried about performance, and react best practices. Several places talks about using ref property instead of findDOMNode, but all of them are for child dom elements, on my case I only want the root DOM node of my component.

The alternative using ref may look like this:

render(){
   return (
            <section // container
                ref={(n) => this.node = n}>
                 // Stuff
            </section>
}
 componentDidUpdate() {

        this.elementBox = this.node.getBoundingClientRect();
        this.elementHeight = this.node.clientHeight;
        // Make calculations and stuff
}

To be honest, attaching a ref callback to my root dom node just to get it's reference does not feel correct to me.

What is considered the best practice on this case ? Which one has better performance ?

Danielo515
  • 5,996
  • 4
  • 32
  • 66
  • 1
    Shame none of the frameworks seem to have adapted this ref handling yet and defaulut to findDOMNode even when given refs. – Zach Aug 14 '20 at 19:37

1 Answers1

15

If I refer to the doc (https://facebook.github.io/react/docs/react-dom.html#finddomnode), findDOMNode seems to be more a trick than a real option. The ref seems to be the best option. The doc implements the same draft you gave here (with the ref={(n) => this.node = n})

soywod
  • 4,377
  • 3
  • 26
  • 47
  • 1
    Reading again the documentation I just found: >Using the ref callback just to set a property on the class is a common pattern for accessing DOM elements. The preferred way is to set the property in the ref callback like in the above example. – Danielo515 Apr 16 '17 at 16:47
  • By the way, I don't know if you noticed, but JS Standard I'm on complains about `{(n) => this.node = n}` saying "Arrow function should not return assignment." I'm wondering is it legit complaint or not – revelt Jul 20 '17 at 07:38
  • 1
    @revelt It won't result in a runtime error but it literally means you shouldn't be returning an assignment. Easy fix: `{(n) => { this.node = n}}` – SaltedBlowfish Sep 13 '18 at 20:05