Boosting React App with Custom Hook : useOnScreen

Boosting React App with Custom Hook : useOnScreen

Oct 09 2023

When it comes to building web applications, performance is a critical factor in ensuring a smooth user experience. One common requirement is to determine whether an element is currently visible on the screen. This task is essential for implementing features like lazy loading images, infinite scrolling, or tracking visibility-based events. In this article, we'll introduce you to a custom React hook called useOnScreen, which simplifies visibility detection in React applications, making your life as a developer easier.


Introducing useOnScreen

The useOnScreen hook is designed to help you detect whether an element is currently visible on the screen or not. It leverages the Intersection Observer API, a modern JavaScript feature that allows you to monitor changes in the visibility of elements. With this hook, you can easily determine whether an element is within the viewport, enabling you to trigger actions accordingly.

Here's how the useOnScreen hook works:

1import { RefObject, useEffect, useState } from 'react'
2
3export const useOnScreen = (ref: RefObject<any>) => {
4  const [isIntersecting, setIntersecting] = useState(false)
5  const observer = new IntersectionObserver(([entry]) => setIntersecting(entry.isIntersecting))
6
7  useEffect(() => {
8    observer.observe(ref.current)
9    return () => {
10      observer.unobserve(ref.current)
11    }
12  }, [])
13
14  return isIntersecting
15}

How to Use useOnScreen

Here's a complete example of using the useOnScreen hook to progressively load an image when the user scrolls down the page and the image becomes visible:

1import React, { useRef } from 'react'
2import { useOnScreen } from './useOnScreen'
3
4function App() {
5  const imageRef = useRef()
6  const isImageVisible = useOnScreen(imageRef)
7
8  return (
9    <div>
10      <div style={{ height: '100vh' }}>Scroll down</div>
11      <div ref={imageRef}>
12        {isImageVisible && (
13          <img src="image.jpg" alt="Image" />
14        )}
15      </div>
16    </div>
17  )
18}
19
20export default App

See more articles