Today, I want to talk about the IntersectionObserver
, a built-in JavaScript API which is primarily used for lazy-loading images and implementing infinite scrolling. Creating an instance of this API is straightforward, as demonstrated below:
const observer = new IntersectionObserver(callback,options);
A callback
function is required to trigger when intersecting entities change, while options
is an object that defines the observer's behavior and policy. Utilizing this API enables the lazy loading of images in a React app. Refer to this page for a comprehensive understanding of this API.
To utilize this API in a React application, you need to follow a few steps.
Firstly Create a file called Observer.js
which contains the observer
object and its corresponding callback function. The structure of Observer.js
will appear as follows:
export let observer;
export function initObserver() {
observer = new IntersectionObserver(observerCallback);
}
function observerCallback(entries) {
// TODO
}
The initObserver
function initializes the observer
object, the body of the observerCallback
function will be completed later. The initObserver
needs to be called at the top level of the react tree, such as in main.jsx
.
To render the images and enable observation, we need to create an Image
component, which enables us to use the observer
. The code snippet provided below demonstrates the implementation of the Image
component.
import React, { useEffect, useRef, useState } from "react";
import { observer } from "./Observer";
export default function Image({ src }) {
const [isSeen, setIsSeen] = useState(false);
const containerRef = useRef(null);
useEffect(() => {
if (containerRef.current) {
containerRef.current.onObserve = () => {
setIsSeen(true);
};
observer.observe(containerRef.current);
}
return () => observer.unobserve(containerRef.current);
}, []);
return isSeen ? (
<img src={src} />
) : (
<div
ref={containerRef}
style={{ width: "250px", height: "350px", backgroundColor: "black" }}
/>
);
}
This component uses a prop named src
, which represents the URL source of the image. Additionally, it requires a ref
to reference an alternative element for the image which is called containerRef
. In the example given, a basic div
with a black background is used, but you have the flexibility to customize this element according to your specific requirements.
In the useEffect
setup function, we first check if the containerRef
has a reference. If it has, we add a function called onObserve
to it. Inside this function, we change the component state isSeen
to true, indicating that the image should be rendered and displayed. Then, we make the observer
intersects the containerRef
. Finally, in the clean-up function of the useEffect
, we remove the containerRef
from the list of observed entries by calling the unobserve
function.
Now, moving on to the final step, we will go back to the Observer.js
file and proceed with initializing the body of the observerCallback
function. It should verify if an entry intersects and then invoke its onObserve
function. Therefore, the updated code will appear as follows:
function observerCallback(entries) {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.onObserve();
}
});
}
Thank you for taking the time to read this article. I hope you found it helpful. If you have any questions or comments, please share them with me.
Top comments (0)