To get the height or width of an element in React, use the useRef
, useEffect
, and useState
hooks to access the element’s offsetWidth
or offsetHeight
property:
import React, { useEffect, useState, useRef } from 'react';
function ExampleComponent() {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const elementRef = useRef(null);
useEffect(() => {
setWidth(elementRef.current.offsetWidth);
setHeight(elementRef.current.offsetHeight);
}, []);
return (
<div
ref={elementRef}
style={{ width: '50%', height: '50%', border: '1px solid black' }}
>
<p>Coding Beauty</p>
<p>{`Element size: (${width}, ${height})`}</p>
</div>
);
}
export default function App() {
return (
<div>
<ExampleComponent />
</div>
);
}
useEffect
()
runs after the component mounts or re-renders, but useLayoutEffe
ct()
runs before. They both have a dependency array that triggers them when any of those dependencies change.
We create a ref for the target element with useRef()
, and assign it to its ref
prop, so we can access the HTMLElement
object for this React element.
useRef
returns a mutable ref object that doesn’t change its value when a component is updated. Also, modifying the value of this object’s current
property does not cause a re-render. This is in contrast to the setState
update function returned from useState
.
We use useState()
to create a state that we update when useEffect()
gets called. This update makes the element’s width and height display on the page.
Get height and width of element with clientHeight
and clientWidth
You can also get an element’s height and width in React with clientHeight
and clientWidth
. Unlike offsetWidth
, it includes padding but excludes borders and scrollbars.
import React, { useRef, useState, useEffect } from 'react';
function ExampleComponent() {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const elementRef = useRef(null);
useEffect(() => {
setWidth(elementRef.current.clientWidth);
setHeight(elementRef.current.clientHeight);
}, []);
return (
<div ref={elementRef} style={{ width: '50%', height: '50%' }}>
<p>Coding Beauty</p>
<p>
<b>{`Element size: (${width}, ${height})`}</b>
</p>
</div>
);
}
export default function App() {
return (
<div>
<ExampleComponent />
</div>
);
}
Get height and width of element dynamically
You can get the height and width of an element dynamically, which means the height and width updates on window resize.
We do this with a resize
event listener:
import React, { useEffect, useState, useRef } from 'react';
function ExampleComponent() {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const elementRef = useRef(null);
useEffect(() => {
const handleResize = () => {
setWidth(elementRef.current.offsetWidth);
setHeight(elementRef.current.offsetHeight);
};
handleResize();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<div ref={elementRef} style={{ width: '50%', height: '50%' }}>
<p>Getting element width dynamically</p>
<p><b>{`Element size: (${width}, ${height})`}</b></p>
</div>
);
}
export default function App() {
return (
<div>
<ExampleComponent />
</div>
);
}
We call addEventListener()
in useEffect()
to set the resize event listener on the element before it renders on the screen.
The resize event listener is called whenever the user resizes the window. In the listener, we update the state that stores the element’s width and height, and this causes a re-render.
We call removeEventListener()
in useEffect
‘s clean-up function to stop listening for resize
events when the component is unmounted or when the dependencies change to prevent memory leaks and unintended side effects.
Get element height and width before render in React
To get the width and height of an element before render in React, we can combine two React hooks: useRef
and useLayoutEffect
.
import React, { useRef, useLayoutEffect, useState } from 'react';
function ExampleComponent() {
const [width, setWidth] = useState(0);
const [height, setHeight] = useState(0);
const elementRef = useRef(null);
useLayoutEffect(() => {
setWidth(elementRef.current.offsetWidth);
setHeight(elementRef.current.offsetHeight);
}, []);
return (
<div style={{ width: '50%', height: '50%' }}>
<p>Coding Beauty</p>
<div ref={elementRef}>
Element size: ({width}, {height})
</div>
</div>
);
}
export default function App() {
return (
<div>
<ExampleComponent />
</div>
);
}
So the difference between “before render” and “after render” is useLayoutEffect()
and useEffect()
.
useLayoutEffect()
works just like useEffect()
, but the key difference is that it fires before the browser repaints the screen – before React renders the component.
We pass an empty dependencies array to useLayoutEffect()
to make sure it only gets called once.
Here we create a ref for the target element with useRef()
, and assign it to its ref
prop, so we can access the HTMLElement
object for this React element.
useRef
returns a mutable ref object that doesn’t change its value when a component is updated. Also, modifying the value of this object’s current
property does not cause a re-render. This is in contrast to the setState
update function returned from useState
.
We do use useState()
though, to create a state that we update when useLayoutEffect()
gets called. So calling setWidth()
will cause the component to be re-rendered.
To get the actual width and height, we use the offsetWidth
and offsetHeight
properties, which include borders, padding, and any scrollbars.
Key takeaways
- To get the height or width of an element in React, combine the
useRef
,useEffect
, anduseState
hooks to get the value ofoffsetWidth
andoffsetHeight
. clientWidth
andclientHeight
are similar tooffsetWidth
andoffsetHeight
, but they include padding and exclude borders and scrollbars.- To get the dimensions of the element dynamically, create a
window
resize
event listener to automatically update the size when the user resizes the browser window. - To get the size of the element before render, replace
useEffect
withuseLayoutEffect
.
11 Amazing New JavaScript Features in ES13
This guide will bring you up to speed with all the latest features added in ECMAScript 13. These powerful new features will modernize your JavaScript with shorter and more expressive code.