Get the Width of an Element using a Ref in React


Borislav Hadzhiev

Last updated: Apr 27, 2022


Photo from Unsplash

Get the Width of an Element using a Ref in React #

To get the width of an Element using a ref in React:

  1. Set the ref prop on the element.
  2. In the useLayoutEffect hook, update the state variable for the width.
  3. Use the offsetWidth property to get the width of the element.
import {useLayoutEffect, useRef, useState} from 'react'; export default function App() { const ref = useRef(null); const [width, setWidth] = useState(0); const [height, setHeight] = useState(0); useLayoutEffect(() => { setWidth(ref.current.offsetWidth); setHeight(ref.current.offsetHeight); }, []); return ( <div ref={ref}> <h2>Width: {width}</h2> <h2>Height: {height}</h2> </div> ); }

The useRef() hook can be passed an initial value as an argument. The hook returns a mutable ref object whose .current property is initialized to the passed argument.

Notice that we have to access the current property on the ref object to get access to the div element on which we set the ref prop.

When we pass a ref prop to an element, e.g. <div ref={myRef} />, React sets the .current property of the ref object to the corresponding DOM node.

We passed an empty dependencies array to the useLayoutEffect hook, so it's only going to run when the component mounts.

useLayoutEffect(() => { setWidth(ref.current.offsetWidth); setHeight(ref.current.offsetHeight); }, []);

The useLayoutEffect hook is identical to useEffect, but fires synchronously after all DOM mutations.

The useLayoutEffect hook is often used to read layout from the DOM.

We used the useLayoutEffect hook because we need to wait for the ref to be set on the element and for the element to get rendered before accessing its offsetHeight and offsetWidth properties.

The offsetWidth property returns the width of the element in pixels, including any borders, padding and vertical scrollbars (if present).

The offsetHeight property returns the height of the element in pixels, including vertical padding and borders.

Alternatively, you can use the clientWidth property, which returns the width of the element in pixels, including padding but excluding borders, margins and vertical scrollbars (if present).

useLayoutEffect(() => { setWidth(ref.current.clientWidth); setHeight(ref.current.clientHeight); }, []);
I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.