Accepted answer

You have at least three options how to do that:

  1. Track if component is in viewport (visible to user). And then render it. You can use this HOC

  2. Track ‘y’ scroll position explicitly with

  3. Write your own HOC using Intersection Observer API

To render component you may need another HOC, which will return Chart component or ‘null’ based on props it receives.


I think the easiest way to do this in React is using react-intersection-observer.


import { useInView } from 'react-intersection-observer';

const Component = () => {
  const { ref, inView, entry } = useInView({
    /* Optional options */
    threshold: 0,

      //do something here when inView is true
  }, [inView])

  return (
    <div ref={ref}>
      <h2>{`Header inside viewport ${inView}.`}</h2>

I also reccommend using triggerOnce: true in the options object so the effect only happens the first time the user scrolls to it.


you can check window scroll position and if the scroll position is near your div - show it. To do that you can use simple react render conditions.

import React, {Component} from 'react';
import PropTypes from 'prop-types';

class MyComponent extends Component {

    this.state = {
        elementToScroll1: false,
        elementToScroll2: false,

    this.firstElement = React.createRef();
    this.secondElement = React.createRef();
componentDidMount() {
    window.addEventListener('scroll', this.handleScroll);

componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScroll);
    //check if scroll position is near to your elements and set state {elementToScroll1: true}
    //check if scroll position is under to your elements and set state {elementToScroll1: false}
render() {
    return (
            <div ref={this.firstElement} className={`elementToScroll1`}>
                {this.state.elementToScroll1 && <div>First element</div>}
            <div ref={this.secondElement} className={`elementToScroll2`}>
                {this.state.elementToScroll2 && <div>Second element</div>}

MyComponent.propTypes = {};

export default MyComponent;

this may help you, it's just a quick solution. It will generate you some rerender actions, so be aware.


I have tried many libraries but couldn't find something that best suited my needs so i wrote a custom hook for that, I hope it helps

import { useState, useEffect } from "react";

const OPTIONS = {
  root: null,
  rootMargin: "0px 0px 0px 0px",
  threshold: 0,

const useIsVisible = (elementRef) => {
  const [isVisible, setIsVisible] = useState(false);

  useEffect(() => {
    if (elementRef.current) {
      const observer = new IntersectionObserver((entries, observer) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
      }, OPTIONS);
  }, [elementRef]);

  return isVisible;

export default useIsVisible;

and then you can use the hook as follows :

import React, { useRef } from "react";
import useVisible from "../../hooks/useIsVisible";

function Deals() {
  const elemRef = useRef();
  const isVisible = useVisible(elemRef);
  return (
    <div ref={elemRef}>hello {isVisible && console.log("visible")}</div>

Related Query

More Query from same tag