I'm making a "sticky" header when scrollY
meets offsetTop
, but I don't want to hard code the offset. I've been attempting to store the initial offsetTop
which can then be checked inside the isSticky()
method attached to the scroll
listener.
So far I've been unable to make the value stick (no pun intended) and it appears to be null
inside the method being run.
const ProfileHeader: React.FC<ProfileHeaderData> = ({ profile }) => {
const bannerUrl = getBannerImageUrl(profile.id, null, profile.bannerImageVersion);
const logoUrl = getLogoImageUrl(profile.id, null, profile.logoImageVersion);
const headerRef = useRef<HTMLDivElement>(null);
const [sticky, setSticky] = useState("");
const [headerOffSet, setHeaderOffSet] = useState<number>(null);
console.log(`Outside: ${headerOffSet}`);
// on render, set listener
useEffect(() => {
console.log(`Render: ${headerRef.current.offsetTop}`);
setHeaderOffSet(headerRef.current.offsetTop);
window.addEventListener("scroll", isSticky);
return () => {
window.removeEventListener("scroll", isSticky);
};
}, []);
const isSticky = () => {
/* Method that will fix header after a specific scrollable */
const scrollTop = window.scrollY;
let originalOffset = headerOffSet ?? headerRef.current.offsetTop;
if (headerOffSet === null) {
console.log(`Setting header off set`);
setHeaderOffSet(originalOffset);
}
console.log(`top: ${scrollTop} | offset: ${originalOffset} | state: ${headerOffSet}`);
const stickyClass = scrollTop >= originalOffset ? styles.sticky : "";
setSticky(stickyClass);
};
return (
<div className={styles.container}>
<div className={styles.bannerContainer}>
{profile.bannerImageVersion && (
<Image
src={bannerUrl}
layout='fill'
className={styles.banner}
/>
)}
</div>
<div ref={headerRef} className={`${styles.header} ${sticky}`}>
<div className={styles.logoContainer}>
{profile.logoImageVersion && (
<Image
src={logoUrl}
layout='fill'
className={styles.logo}
/>
)}
</div>
<FlagCircleIcon {...profile.country} size={32} />
<h1 className={styles.displayName}>{profile.displayName}</h1>
</div>
</div>
)
}
On the initial page load, I get the following console output:
As I start to scroll, the output is as follows:
Seems like the state is never set?