title: ReactJS — How to use intersection observer in a Class Component?
body: <p>I manage to use <code>react-intersection-observer</code> in a Function Component. However, I have not been successful when using it with a Class Component. I tried to follow the documentation but I am getting the following error:</p>
  
  <p><code>Invariant failed: react-intersection-observer: No DOM node found. Make sure you forward "ref" to the root DOM element you want to observe.</code></p>
  
  <p>What am I doing wrong? Thank you in advance.</p>
  
  <p>Pseudo-code</p>
  
  <ul>
  <li>Trigger animation when the element is visible in the viewport.</li>
  </ul>
  
  <p><a href="https://codesandbox.io/s/mystifying-hermann-sq5ox?file=/src/Timer.js" rel="nofollow noreferrer">CodesandBox</a></p>
  
  <pre><code>import React, { Component } from "react";
  import { Container, Row, Col } from "react-grid-system";
  import { motion } from "framer-motion";
  import { InView } from "react-intersection-observer";
  
  let years, days, hours, mins, secs;
  
  function upTime(countTo) {
    var now = new Date();
    countTo = new Date(countTo);
    var difference = now - countTo;
  
    years = Math.floor(difference / (60 * 60 * 1000 * 24) / 365);
    days = Math.floor(difference / (60 * 60 * 1000 * 24));
    hours = Math.floor((difference / (60 * 60 * 1000 * 24)) * 24);
    mins = Math.floor((difference / (60 * 60 * 1000 * 24)) * 24 * 60);
    secs = mins * 60;
  
    clearTimeout(upTime.to);
    upTime.to = setTimeout(function() {
      upTime(countTo);
    }, 1000);
  }
  
  export default class Timer extends Component {
    state = {
      y: 0,
      d: 0,
      h: 0,
      m: 0,
      s: 0,
      toggle: true
    };
  
    componentDidMount() {
      // Set inital seconds
      upTime("may,05,2006,00:00:00");
      let currentSec = secs;
  
      this.myInterval = setInterval(() =&gt; {
        upTime("may,05,2006,00:00:00");
        currentSec += 1;
  
        this.setState({
          y: years,
          d: days,
          h: hours,
          m: mins,
          s: currentSec
        });
      }, 1000);
    }
  
    componentWillUnmount() {
      clearInterval(this.myInterval);
    }
  
    render() {
      const { y, h, m, s } = this.state;
      const style = {
        listStyle: "none",
        fontFamily: "Soleil",
        fontSize: "200px",
        lineHeight: "220px",
        color: "black",
        textAlign: "left"
      };
  
      // Animation list
      const list = {
        visible: {
          opacity: 1,
          transition: { staggerChildren: 0.06 }
        },
        hidden: {
          opacity: 0,
          transition: {}
        }
      };
  
      // Animation list
      const item = {
        visible: {
          opacity: 1,
          y: 0,
          transition: { ease: "backInOut", duration: 0.8 }
        },
        hidden: { opacity: 0, y: 100 }
      };
  
      // Conditional render
      if (y !== 0) {
        return (
          &lt;Container fluid&gt;
            &lt;Row&gt;
              &lt;Col offset={{ xl: 1 }}&gt;
                &lt;InView&gt;
                  {({ inView, ref, entry }) =&gt; (
                    &lt;motion.ul
                      ref={ref}
                      style={style}
                      initial="hidden"
                      animate={inView ? "visible" : "hidden"}
                      variants={list}
                    &gt;
                      &lt;motion.li variants={item}&gt;{y}Y&lt;/motion.li&gt;
                      &lt;motion.li variants={item}&gt;{h}H&lt;/motion.li&gt;
                      &lt;motion.li variants={item}&gt;{m}M&lt;/motion.li&gt;
                      &lt;motion.li variants={item}&gt;{s}&lt;/motion.li&gt;
                    &lt;/motion.ul&gt;
                  )}
                &lt;/InView&gt;
              &lt;/Col&gt;
            &lt;/Row&gt;
          &lt;/Container&gt;
        );
      } else {
        return &lt;div&gt;"Loading..."&lt;/div&gt;;
      }
    }
  }
  </code></pre>