One common requirement when working with dynamic layouts is the need to determine the width of an element dynamically. In this post, we will create a React hook that calculates the width of an element dynamically.
First, let's create a new file called hooks.js
to house our hook. In this file, we'll start by importing the necessary React hooks:
/**
* Gets width for referenced element, recalculates after page resize.
*
* @param {*} ref Element reference.
*
* @returns {number} Element width.
*/
export function getWidth(ref) {
const [width, setWidth] = useState(false);
if (typeof window != 'undefined') { // Client only.
useEffect(() => {
let recalcWidth = () => {
let w = ref?.current?.offsetWidth || 0;
setWidth(w);
};
// Recalculate on window resize.
window.addEventListener('resize', recalcWidth);
}, [ref]);
}
return width ? width : 0;
}
Let's break down the logic behind the getWidth
hook:
width
state variable to 0 using the useState
hook. This state variable will hold the current width of the element.useEffect
hook, we define the recalcWidth
function. This function calculates the width of the element and updates the width
state variable.recalcWidth
function to the resize
event of the window
object using addEventListener
.handleResize
function once to capture the initial width of the element.width
variables from the hook.Now that our hook is ready, let's see how we can utilize it within a component. Here's an example:
import React, { useRef, useEffect } from 'react';
import getWidth from './hooks';
export default function testComponent() {
const ref = useRef();
let width = getWidth(ref); // Image width, recalculates on resize.
useEffect(() {
// Do something on width change.
},[width]);
return (
<div ref={ref}>
The width of this element is: {width}px
</div>
);
}
In the above example, we import and use the getWidth
hook. By attaching a reference object to the element and passing it to getWidth
we enable the hook to calculate and update the width dynamically. The current width is then displayed inside the component and can be used to trigger a change or event.