React hook to determine element width dynamically
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.
Step 1: Initializing the Hook
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;
}
Step 2: Understanding the Hook
Let’s break down the logic behind the getWidth hook:
- We begin by initializing the
widthstate variable to 0 using theuseStatehook. This state variable will hold the current width of the element. - The function takes an element reference.
- Inside the
useEffecthook, we define therecalcWidthfunction. This function calculates the width of the element and updates thewidthstate variable. - We attach the
recalcWidthfunction to theresizeevent of thewindowobject usingaddEventListener. - Additionally, we invoke the
handleResizefunction once to capture the initial width of the element. - Finally, we return the
widthvariables from the hook.
Step 3: Using 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.