Skip to content

Instantly share code, notes, and snippets.

@TedSean
Forked from JamesBliss/react-useCallback.md
Created January 6, 2021 13:20
Show Gist options
  • Save TedSean/899d45a6e3f18f0d9043241b57b75370 to your computer and use it in GitHub Desktop.
Save TedSean/899d45a6e3f18f0d9043241b57b75370 to your computer and use it in GitHub Desktop.
Measuring a DOM node

React => measuring a DOM node

Your first instinct will be to use a useRef which can be a good solution, although an object ref doesn’t notify us about changes to the current ref value. This means when the ref.current changes you will not see the updated value.

Solution 1.

Use a callback ref (this example is taken from the react hooks FAQ) This is a super simple and pretty nice solution for one-off measurements.

function MeasureExample() {
  const [height, setHeight] = useState(0);

  const measuredRef = useCallback(node => {
	  if (node !== null) {
	  setHeight(node.getBoundingClientRect().height);
  }}, []);
	  
  return (
    <>
      <h1 ref={measuredRef}>Hello world</h1>
      <h2>The above header is {Math.round(height)}px tall</h2>
    </>
  );
}

Solution 2

This solution is a pretty elegant fix for this problem while keeping the integrity/behaviour .current of a traditional ref.

import React from 'react'

function useRefCallback() {
  const ref = React.useRef(null)
  const setRef = React.useCallback(node => {
    if (ref.current) {
      // Make sure to cleanup any events/references
      // Ref.current at this point will be the preview instanct
    }
    
    if (node) {
      // Check if a node is passed. Otherwise, node would be null.
      // You can now do what you need to, addEventListeners, measure, etc.
    }
    
    // Save a reference to the node
    ref.current = node
  }, [])
  
  return [ref, setRef]
}

function App() {
  const [setRef] = useRefCallback()
  return <div ref={setRef}>Ref element</div>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment