Intersection Observer API lets programmers check if a DOM element is currently visible (i.e. intersecting) on the screen.
It can be used to:
- display floating menu
- lazy load images
- perform animations
- detect if ads are displayed
- implement infinite scrolling
But now, let's focus on how to use it in React.
If you are like me, a lazy programmer, probably you are not interested in learning the theory. However, if that's not true, you can learn more about how to use this API in the MDN Web Docs.
So, let's see the code - here is copy-paste ready version of the hook:
useIntersectionObserver hook
// useIntersectionObserver.ts
import React, { useEffect, useState } from 'react'
const useIntersectionObserver = (ref: React.RefObject<HTMLElement>) => {
const [state, setState] = useState<IntersectionObserverEntry>()
useEffect(() => {
if (!ref.current) return
const observer = new IntersectionObserver(([elementState]) => setState(elementState), {
root: null,
rootMargin: '0px',
threshold: 0
})
observer.observe(ref.current)
return () => observer.disconnect()
}, [ref])
return state
}
export default useIntersectionObserver
It's not that complicated! Let's see how to use it.
// Component.tsx
import React, { useRef } from "react";
import useIntersectionObserver from "./useIntersectionObserver";
const Component = () => {
const ref = useRef<HTMLDivElement>(null);
const intersection = useIntersectionObserver(ref);
return (
<section style={{ position: "relative" }}>
<div style={{ position: "fixed" }}>
{intersection?.isIntersecting
? "Element is visible"
: "Element is not visible - scroll down"}
</div>
<div style={{ height: "800px" }} />
<div ref={ref} style={{ height: "200px", background: "red" }} />
</section>
);
};
export default Component;
You can edit the working example on CodeSandbox:
I hope you find it useful. Stay tuned for more copy-paste ready custom react hook posts!