I'm using a React hook to track the scroll position on a page. The hook code is as follows:
import { useLayoutEffect, useState } from 'react';
const useScrollPosition = () => {
const [scrollPosition, setScrollPosition] = useState(window.pageYOffset);
useLayoutEffect(() => {
const updatePosition = () => {
setScrollPosition(window.pageYOffset);
};
window.addEventListener('scroll', updatePosition);
return () => window.removeEventListener('scroll', updatePosition);
}, []);
return scrollPosition;
};
export default useScrollPosition;
I then use this in various ways, for example in this component where a class is applied to an element if the page has scrolled more than 10px:
const Component = () => {
const scrollPosition = useScrollPosition();
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const newScrolled = scrollPosition > 10;
if (newScrolled !== scrolled) {
setScrolled(newScrolled);
}
}, [scrollPosition]);
return (
<div
className={clsx(style.element, {
[style.elementScrolled]: scrolled,
})}
>
{children}
</div>
);
};
This all works and does what I'm trying to achieve, but the component re-renders continuously on every scroll of the page.
My understanding was that by using a hook to track the scroll position, and by using useState/useEffect to only update my variable "scrolled" in the event that the scroll position passes that 10px threshold, the component shouldn't be re-rendering continuously on scroll.
Is my assumption wrong? Is this behaviour expected? Or can I improve this somehow to prevent unnecessary re-rendering? Thanks