I have a component on a page in react. It's sole job is to toggle light/dark state when the component intersects with the bottom of the viewport (either direction: up or down). The implementation I currently have works well for this. The implementation I have also works if I navigate to another page (say the about page) and then navigate back to the page with component in it. (Using react-router btw). It will render with the right state (light/dark) depending on whether the component is above or below the viewport when it is mounted. There is one condition I cant figure out though. When the component is above the bottom of the viewport (should be light mode at that point), and you refresh the page, I can't get it to render with the right darkmode state (light mode) when the page loads again. This is my current implementation:
const DarkModeIntersection = ({ darkmode, setDarkmode }) => {
const ref = useRef(null);
const [firstLoad, setFirstLoad] = useState(true);
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (firstLoad) {
setFirstLoad(false);
return;
}
// Exit callback if intersection event is called on the top boundary
if (entry.boundingClientRect.y < 200) return;
// Ie scrolling down the page: Transition from dark - light
if (entry.isIntersecting) {
setDarkmode(false);
document.body.style.background = "white";
return;
}
// event triggered where - its not the top intersection
// its not scrolling down the page
// Ie we are scrolling up - from light to dark;
// if bounding client rect .y <
console.log(entry.rootBounds.bottom);
console.log(entry.boundingClientRect.y);
if (entry.rootBounds.bottom < entry.boundingClientRect.y) {
setDarkmode(true);
document.body.style.background = "black";
}
},
{ threshold: 0, delay: 300 }
);
if (ref.current) {
observer.observe(ref.current);
}
return () => {
if (ref.current) {
observer.unobserve(ref.current);
}
};
}, [firstLoad]);
return <div ref={ref} className={styles.intersection}></div>;
};
The problem with this is that when I refresh the page, the value of entry.boundingClientRect.y is some random number (not its actual value). How do I wait for the actual value to be available, and then set the darkmode state when it becomes available?
Would appreciate any help with this.