Intersection Observer in React

Posted by everrover on March 11, 2022

#react
#reacthooks
#jsobservers
#redux

Intersection Observer monitors the element visibility on the viewport, and fires a callback once an element is visible on the viewport as per the provided configurations. A single observer instance can monitor multiple elements within the DOM, using the same configuration. The most important fact is that IntersectionObserver API is an async API and is non-blocking. Though it still adds an overhead (since a thread runs for each observed element) and so using sentinel objects and recycling observed elements is recommended as for the case of lazy-loading.

Here is the initialization method along with configuration,

jsx
const observer = new IntersectionObserver (callback, {
    root: null,
    rootMargin: '24px 32px',
    threshold: [.8, 1.0]
})

The root defines the element within which the visibility is monitored. By default it points to the main viewport. threshold defines the points at which the callback is to be triggered. It is an array of values between 0 and 1. 0 meaning that as soon as even the smallest part of element is visible, the callback is to be triggered. 1 means that entire element should be visible on the screen before the callback is fired. rootMargin draws out an imaginary margin (not a part of CSS) around the element which is then used in threshold calculation and callbacks. It can have negative values but only accepts pixel dimensions.

Generally callbacks get triggered whenever element crosses visibility threshold(i.e. transition from >threshold to <threshold or vice versa. These callbacks are defined as follows,

jsx
const cb = (entries, observer) => {
    entries.forEach(entry=>{
        console.log(entry)
        // do something
    }
}

The observer is optional argument that has the reference to the actual observer. This we can then use the reference for example, let's say to unobserve an element once it has come into view. Or maybe to start observing some other element. The entry object has several pieces of information. Though, perhaps the most important I have used in my demo are isIntersecting and target. isIntersecting defines weather a element is crossing the visibility threshold or not, after the callback was fired. target is element under observation.

There are three basic methods on observer. These are

  • .observe() : Starts observing a given element
observer.observe(element)
  • .unobserve() : Stops observing a given element
observer.unobserve(element)
  • .disconnect() : Stops observing all elements under observation
observer.disconnect()

The above mentioned element is the target element returned via document.querySelector("#sth") and in case of React is ref returned via JSX element.

IntersectionObserver, in my opinion is one of the most important observers in JS. The practical use-cases include lazy loading, infinite scrolling implementation, transition animation on visibility, amongst many more which I am unaware of. The entire React-Reveal Library is based around it I guess.

I have built a small project around the same concept here.

Sources