Tutorial
An Easy Way to Know When React Components Enter the Browser Viewport
While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or edited it to ensure you have an error-free learning experience. It's on our list, and we're working on it! You can help us out by using the "report an issue" button at the bottom of the tutorial.
In this article, you’ll learn how to use React Visibility Sensor to detect when your React components have entered the viewport.
How do you programmatically determine when a React component enters the viewport? Well, it ain’t easy! It requires a good deal of scrolling event listeners, calculating the sizes of your elements… Ahhhn no fun!
Using React Visibility Sensor provides you with a React component that accomplishes this using a really simple API.
Scrollin’ In the Deep
Let’s jump right into a demo!
Try scrolling the page. The images become “aware” when they’ve entered the viewport…
This functionality is pretty easy to build with React Visibility Sensor. We’ll look at two React components to see how this demo was made.
First, the <img>
component that relies on visibility detection…
import React, { Component } from 'react';
import VizSensor from 'react-visibility-sensor';
class VizAwareImg extends Component {
state = {
imgViz: false
}
render() {
return (
<VizSensor
onChange={(isVisible) => {
this.setState({imgViz: isVisible})
}}
>
<img
src={this.props.src}
style={{
width: 300,
height: 300,
opacity: this.state.imgViz ? 1 : 0.25,
transition: 'opacity 500ms linear'
}}
/>
</VizSensor>
);
}
}
And below is the App
component. It isn’t crucial to deeply analyze the code below. I’m just providing it to give you the big picture of this demo:
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div style={{background: 'violet', color: 'purple'}}>
<div style={{height: '100vh'}}>
<div>Jellyfish</div>
<div>⏬</div>
</div>
{[
'https://unsplash.com/jellyfish-1.jpeg',
'https://unsplash.com/jellyfish-2.jpeg',
'https://unsplash.com/jellyfish-3.jpeg',
'https://unsplash.com/jellyfish-4.jpeg',
'https://unsplash.com/jellyfish-5.jpeg',
'https://unsplash.com/jellyfish-6.jpeg'
].map((imgpath) => <VizAwareImg src={imgpath}/>)}
</div>
);
}
}
There’s actually quite a bit of customization props you can provide to React Visibility Sensor. One of the customizations I usually make is to allow for partialVisibility
of elements.
Customizing React Visibility Sensor
If you scroll back to the demo, the images only appear when they’ve fully entered the viewport. However, it may be desirable to know when just a part of the element has entered the viewport.
class VizAwareImg extends Component {
state = {
imgViz: false
}
render() {
return (
<VizSensor
partialVisibility {/* 👈 BOOM! Just add that... */}
onChange={(isVisible) => {
this.setState({imgViz: isVisible})
}}
>
<img
src={this.props.src}
style={{
opacity: this.state.imgViz ? 1 : 0.25,
width: 300,
height: 300,
transition: 'opacity 500ms linear'
}}
/>
</VizSensor>
);
}
}
Now, if you scroll the page the image’s opacity changes when it barely creeps into the viewport (you may need a desktop-sized screen to see this):
In addition to partialVisibility there are many customization props, like:
- Throttling the scroll listener
- Specifying the minimum number of pixels to appear in the viewport (default: when
partialVisibility
istrue
elements are considered visible when only 1px appears) - Listen when the browser window is resized
- Or just deactivating the scroll listener all together if you don’t need to listen for the event any longer
Images are from the amazing community of Unsplash.com photographers
Wrapping Up
Being self-aware is one of the greatest powers that you can aspire to have… I’m talking about React.js!
When your React components know they’re visible, your app can do more sophisticated things. For example:
- Lazy-loading images when they’re visible
- Show a “Thanks for Visiting!” message when users have scrolled to the footer of your website
- Logging custom events to Google Analytics
- Expand a comment widget when users scroll to the end of a blog post
- … And more!
View the documentation on Github