React Custom Hook: Check if Overflow

 by Robin Wieruch
 - Edit this Post

A neat custom that I used in some of my which checks if an element's content has overflow (here: vertical overflow):

import * as React from 'react';
export const useIsOverflow = (ref, callback) => {
const [isOverflow, setIsOverflow] = React.useState(undefined);
React.useLayoutEffect(() => {
const { current } = ref;
const trigger = () => {
const hasOverflow = current.scrollHeight > current.clientHeight;
setIsOverflow(hasOverflow);
if (callback) callback(hasOverflow);
};
if (current) {
trigger();
}
}, [callback, ref]);
return isOverflow;
};

If you want to detect a horizontal overflow instead, you can exchange the hasOverflow assignment to the following:

const hasOverflow = current.scrollWidth > current.clientWidth;

In a , the custom React hook can be used this way:

import * as React from 'react';
import { useIsOverflow } from './useIsOverflow';
const App = () => {
const ref = React.useRef();
const isOverflow = useIsOverflow(ref);
console.log(isOverflow);
// true
return (
<div style={{ overflow: 'auto', height: '100px' }} ref={ref}>
<div style={{ height: '200px' }}>Hello React</div>
</div>
);
};

The first time the hook returns an undefined, because the state hasn't been set yet.

The custom hook also accepts an optional which fires after the overflow has been checked:

const App = () => {
const ref = React.useRef();
const isOverflow = useIsOverflow(ref, (isOverflowFromCallback) => {
console.log(isOverflowFromCallback);
// true
});
console.log(isOverflow);
// true
return (
<div style={{ overflow: 'auto', height: '100px' }} ref={ref}>
<div style={{ height: '200px' }}>Hello React</div>
</div>
);
};

If an element's size changes, you could adapt the custom hook to check verify again the overflow, but only if the browser supports the ResizeObserver:

import * as React from 'react';
export const useIsOverflow = (ref, callback) => {
const [isOverflow, setIsOverflow] = React.useState(undefined);
React.useLayoutEffect(() => {
const { current } = ref;
const trigger = () => {
const hasOverflow = current.scrollHeight > current.clientHeight;
setIsOverflow(hasOverflow);
if (callback) callback(hasOverflow);
};
if (current) {
if ('ResizeObserver' in window) {
new ResizeObserver(trigger).observe(current);
}
trigger();
}
}, [callback, ref]);
return isOverflow;
};

That's it. There may be many ways to improve this custom hook (e.g. initializing the within the custom hook and return it from the custom hook to attach it to the element, fire the custom hook ), but for my cases it has been sufficient for now.

Keep reading about 

If you are wondering how to run React's useEffect Hook only on update , you may be surprised that you need React's useRef Hook as helper to create an instance variable for tracking the component's…

If you are wondering how to run React's useEffect Hook only once , you may be surprised that you need React's useRef Hook as helper to create an instance variable for tracking the component's…

The Road to React

Learn React by building real world applications. No setup configuration. No tooling. Plain React in 200+ pages of learning material. Learn React like 50.000+ readers.

Get it on Amazon.