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.