Preact: Using callback refs to measure node height doesn't work

Created on 22 Jul 2019  路  1Comment  路  Source: preactjs/preact

Having trouble with callback refs and measuring node height.

Using example straight from React docs, when the elems are wrapped in a Fragment, evrything is ok. When the elems are wrapped in div, it starts to crumble:

Running 10.0.0-rc.0.

import ReactDOM, { useState, useCallback } from "preact/compat";

function Test() {
  const [height, setHeight] = useState(0);
  const measuredRef = useCallback(node => {
    if (node !== null) {
      setHeight(node.getBoundingClientRect().height);
    }
  }, []);
  return (
    <div> {/* when wrapped in div instead of Fragment, doesn't work */}
      <h1 ref={measuredRef}>Hello, world</h1>
      <h2>The above header is {Math.round(height)}px tall</h2>
    </div>
  );
}

ReactDOM.render(<Test />, document.body);

Sandbox here.

The node reports 0px height. In React, works fine.

Using classes, it works both in Preact and React.

import ReactDOM, { Component } from "preact/compat";

export default class Test extends Component {

    constructor (props) {
        super(props);
        this.state = { height: 0 };
        this.measuredRef = React.createRef();
    }

    componentDidMount () {
        this.setState({ height:
            this.measuredRef.current.getBoundingClientRect().height
        });
    }

    render () {
        return <div>
            <h1 ref={this.measuredRef}>Hello, world</h1>
            <h2>The above header is {Math.round(this.state.height)}px tall</h2>
        </div>;
    }
}

ReactDOM.render(<Test />, document.body);

Sandbox here.

Most helpful comment

Closing as a non-issue as discussed on chat. Callback refs are not guaranteed to execute after element is painted to DOM, and the difference in behavior of Preact v React comes from different implementation of the same spec (which doesn't specify normative behavior in this case).

The solution is to use useEffect instead of callback refs.

>All comments

Closing as a non-issue as discussed on chat. Callback refs are not guaranteed to execute after element is painted to DOM, and the difference in behavior of Preact v React comes from different implementation of the same spec (which doesn't specify normative behavior in this case).

The solution is to use useEffect instead of callback refs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mizchi picture mizchi  路  3Comments

KnisterPeter picture KnisterPeter  路  3Comments

matthewmueller picture matthewmueller  路  3Comments

jasongerbes picture jasongerbes  路  3Comments

kossnocorp picture kossnocorp  路  3Comments