DEV Community

Óscar Pérez
Óscar Pérez

Posted on

Intersection observer api & lazy loading in REACT

INTRODUCTION

Let's embark on an exciting journey to control how our app behaves as the user scrolls and ensure our components only render when they are in the user's view. And to top it off, we want to achieve this in a lazy loading fashion!

Introducing the Lazy Component Wrapper - a simple guide to achieving this seamlessly. Let's dive in and experience the magic of lazy rendering!

LAZY COMPONENT WRAPPER

This component will render the children component only when it becomes visible to the user. By using the Intersection Observer API:

function LazyComponentWrapper({ children, className, id }: LazyComponentWrapperProps) {
    const [isVisible, setIsVisible] = useState(false);
    const componentRef = useRef<HTMLElement | null>(null);

    useEffect(() => {
        const observer = new IntersectionObserver(
            (entries) => {
                entries.forEach((entry) => {
                    if (entry.isIntersecting) {
                        setIsVisible(true);
                        observer.unobserve(entry.target);
                    }
                });
            },
            { threshold: 0.5 } as IntersectionObserverInit
        );

        if (componentRef.current) {
            observer.observe(componentRef.current!);
        }

        return () => {
            if (componentRef.current) {
                observer.unobserve(componentRef.current!);
            }
        };
    }, []);

    return (
        <section
            ref={componentRef}
            className={`${className} ${isVisible ? styles.visible : styles.notVisible}`}
            id={id}>
            {isVisible && children}
        </section>
    );
}
Enter fullscreen mode Exit fullscreen mode

Not only does this component enable lazy rendering, but it also allows us to add captivating animations and styles to animate the components as they appear on the user's screen. And to achieve this enchanting effect, we'll make use of CSS modules!.

.visible {
    opacity: 1;
    transform: translateY(0);
    transition: all 0.5s ease-in-out;
}

.notVisible {
    opacity: 0;
    transform: translateY(80px);
}
Enter fullscreen mode Exit fullscreen mode

LAZY IMPORTS AND SUSPENSE

Finally, let's import our components and wrap them with our magnificent LazyComponentWrapper:✨

const Component = lazy(() => import("../../Component.tsx"));

<LazyComponentWrapper>
   <Suspense fallback={<div>Loading...</div>}>
      <Component />
   </Suspense>
</LazyComponentWrapper> 
Enter fullscreen mode Exit fullscreen mode

Now, your component will render only when the user needs it, thanks to the use of lazy loading and the Intersection Observer API.

Additionally, adding specific styles with CSS modules adds an extra touch of charm to the user experience.

Happy coding! ✨🚀

@oscarprdev

Top comments (0)