DEV Community

GihanRangana
GihanRangana

Posted on

2 1

React useInView Hook - How to create useInView Hook in ReactJs

Learn how to create a powerful useInView hook in React using the Intersection Observer API. Elevate your development skills as we guide you through step-by-step instructions to create a custom useInView hook. Enhance user experience, optimize performance, and effortlessly track element visibility in your React projects.

Follow this video to step-by-step instructions

useInView.ts

import { useRef, useState, useEffect, RefObject } from 'react';

interface IOptions {
    root?: Element | null | undefined;
    rootMargin?: string,
    thresholds?: ReadonlyArray<number>
}

type useInViewType = {
    inView: boolean
    ref: RefObject<T> | null,
    observe: (element: RefObject<T>, callback: (entries: IntersectionObserverEntry[]) => void) => IntersectionObserver | null,
    unObserve: (observer: IntersectionObserver) => void
}

const useInView = (options: IOptions): useInViewType => {
    const [inView, setInView] = useState(false)

    const containerRef = useRef(null)

    const callback = (entries: IntersectionObserverEntry[]) => {
        const [entry] = entries
        setInView(entry.isIntersecting)
    }

    useEffect(() => {

        const _observer = new IntersectionObserver(callback, options)
        if (containerRef.current) _observer.observe(containerRef.current)

        return () => {
            if (containerRef.current) _observer.unobserve(containerRef.current)
        }

    }, [containerRef, options])

    // For Manual observers
    const observe = (element: RefObject<T>, callback: (entries: IntersectionObserverEntry[]) => void) => {
        const _observer = new IntersectionObserver(callback, options)
        containerRef.current = element.current

        return _observer
    }

    const unObserve = (observer: IntersectionObserver) => {
        if (containerRef.current) observer.unobserve(containerRef.current)
    }

    return {
        inView,
        ref: containerRef,
        observe,
        unObserve
    }

}

export default useInView;
Enter fullscreen mode Exit fullscreen mode

Usage:


function App() {

    const [data, setData] = useState<any[]>([])
    const [page, setPage] = useState(1)

    const { ref, inView } = useInView({ thresholds: [2] })

    useEffect(() => {
        setData([...new Array(5 * page)])
    }, [page])

    useEffect(() => {
        if (inView) setPage(prev => prev + 1)
    }, [inView])

    return (
        <div className={styles.mainContainer}>
            {data.map((row: any, index: number) => {
                return <Card key={`card-${index.toString()}`} index={index} />
            })}

            <button ref={ref} className={styles.loadMore}>Load More</button>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Working Demo:

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay