<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ashish Kumar Saini</title>
    <description>The latest articles on DEV Community by Ashish Kumar Saini (@ashish8796).</description>
    <link>https://dev.to/ashish8796</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F417629%2F35cb4d8c-c71a-43c9-97d4-46cfe3d80b28.jpeg</url>
      <title>DEV Community: Ashish Kumar Saini</title>
      <link>https://dev.to/ashish8796</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ashish8796"/>
    <language>en</language>
    <item>
      <title>Infinite Scrolling Using Intersection Observer API</title>
      <dc:creator>Ashish Kumar Saini</dc:creator>
      <pubDate>Wed, 31 Mar 2021 08:41:45 +0000</pubDate>
      <link>https://dev.to/ashish8796/infinite-scrolling-using-intersection-observer-api-7a2</link>
      <guid>https://dev.to/ashish8796/infinite-scrolling-using-intersection-observer-api-7a2</guid>
      <description>&lt;p&gt;We interact with many internet-based platforms in our day to day life. We use several social media platform and shopping sites. It is easy to shop through an online shopping platform. We scroll up and down to see the products or news feed. As we go down the new set of products or news feed loads automatically.&lt;br&gt;
  Infinite scrolling is shown in the following gif.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwp1o3k10clzf113d28bp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwp1o3k10clzf113d28bp.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
    Without wasting time, now, I come to the point. I discussed the loading of the new set of products during scrolling the UI above. This loading of the new set of products is called pagination of the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pagination:-&lt;/strong&gt; Pagination is a sequence of pages which are connected and have similar content.&lt;/p&gt;

&lt;p&gt;Pagination can be done in several ways. Pagination can be done with a navigation bar at the bottom or top of the page using an anchor tag with href attribute. I m not going deep into it. &lt;br&gt;
This article is on the subject that how should do infinite scrolling using "Intersection Observer API" in react. How can we do pagination in the react using "Intersection Observer API"?&lt;br&gt;
Before the start, I assume that you are familiar with javascript, react, react hooks and intersection observer API. If you are not familiar with intersection observer API then you should first take a look at &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="noopener noreferrer"&gt;Intersection Observer API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's start now!!!.&lt;/p&gt;

&lt;p&gt;In this article, I am using Github API for the demo of the subject. I'll fetch repos of the user and will show them on the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvt3xr3w1q3tb31et351x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvt3xr3w1q3tb31et351x.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, I created a react app and made an InfiniteScrolling react functional component.&lt;br&gt;
Now, I made repoData, totalRepos, currentPage states in the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function InfiniteScrolling() {
  const [repoData, setRepoData] = useState([]);
  const [totalRepos, setTotalRepos] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);

  function fetchData() {
    (async () =&amp;gt; {
      const data = await fetch(`https://api.github.com/users/praveen-me/repos?
page=${totalRepos ? currentPage : 1}`).then(response =&amp;gt; response.json());

      if (currentPage &amp;lt; totalRepos / 30) {
        setCurrentPage(currentPage + 1);
      }

      setRepoData([...repoData, ...data]);
    })()
  }

  useEffect(() =&amp;gt; {
    (async () =&amp;gt; {
      const userData = await fetch("https://api.github.com/users/praveen-me")
.then(response =&amp;gt; response.json());
      setTotalRepos(userData.public_repos);
    })()

    fetchData();
  }, [])

  return (
    &amp;lt;div className="App"&amp;gt;
      {repoData.map((repo, index) =&amp;gt; {
      return &amp;lt;h1 className="repo" key={repo.name + index}&amp;gt;{repo.name}&amp;lt;/h1&amp;gt;
    })}
    &amp;lt;/div&amp;gt;
  );

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;FetchData()&lt;/code&gt; function is fetching data from the given URI and setting to the states. &lt;code&gt;makeRepoElem()&lt;/code&gt; function is creating an array of &lt;code&gt;h1&lt;/code&gt; element. And a list of repo name is rendered to the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb7v3h4gx3xzosm46xvp9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb7v3h4gx3xzosm46xvp9.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have added some styling to make the good appearance of the repos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function InfiniteScrolling() {
  const [repoData, setRepoData] = useState([]);
  const [totalRepos, setTotalRepos] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);

  const callBack = useCallback((node) =&amp;gt; {

    if (node) console.log(node);
  })

  function fetchData() {
    (async () =&amp;gt; {
      const data = await fetch(`https://api.github.com/users/praveen-me/repos?
page=${totalRepos ? currentPage : 1}`).then(response =&amp;gt; response.json());

      if (currentPage &amp;lt; totalRepos / 30) {
        setCurrentPage(currentPage + 1);
      }

      setRepoData([...repoData, ...data]);
    })()
  }

  useEffect(() =&amp;gt; {
    (async () =&amp;gt; {
      const userData = await fetch("https://api.github.com/users/praveen-me")
.then(response =&amp;gt; response.json());
      setTotalRepos(userData.public_repos);
    })()

    fetchData();
  }, [])

  return (
    &amp;lt;div className="App"&amp;gt;
      {repoData.map((repo, index) =&amp;gt; {
      return &amp;lt;h1 className="repo" key={repo.name + index}&amp;gt;{repo.name}&amp;lt;/h1&amp;gt;
    })}
    &amp;lt;/div&amp;gt;
  );

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, I use a &lt;code&gt;useCallback&lt;/code&gt; and store a function in it. And I reference this &lt;code&gt;useCallback&lt;/code&gt; to the last &lt;code&gt;h1&lt;/code&gt; element in the map. When the last element would be created, the stored function in the &lt;code&gt;useCallback&lt;/code&gt; would be called.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fywwqck266ud5icpj5sou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fywwqck266ud5icpj5sou.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the question is where to use intersection observer API? We will follow the following steps...&lt;br&gt;
1- We will create a new observer i.e. &lt;code&gt;const observer = new IntersectionObserver(callback, options)&lt;/code&gt;.&lt;br&gt;
2- We will observe the last &lt;code&gt;h1&lt;/code&gt; element with this observer i.e. &lt;code&gt;observer.observe(lastElement)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Whenever the last &lt;code&gt;h1&lt;/code&gt; element comes in the viewport, the callback will invoke.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function InfiniteScrolling() {
  const [repoData, setRepoData] = useState([]);
  const [totalRepos, setTotalRepos] = useState(0);
  const [currentPage, setCurrentPage] = useState(1);

  const observer = useRef();
  const callBack = useCallback((node) =&amp;gt; {
    if (observer.current) observer.current.disconnect();

    observer.current = new IntersectionObserver(argus =&amp;gt; {
      if (argus[0].isIntersecting) {
        if (currentPage &amp;lt; totalRepos / 30) {
          fetchData();
        }
      }
    })
    if (node) observer.current.observe(node);
  });

  function fetchData() {
    (async () =&amp;gt; {
      const data = await fetch(`https://api.github.com/users/praveen-me/repos?
page=${totalRepos ? currentPage : 1}`).then(response =&amp;gt; response.json());

      if (currentPage &amp;lt; totalRepos / 30) {
        setCurrentPage(currentPage + 1);
      }

      setRepoData([...repoData, ...data]);
    })()
  }

  useEffect(() =&amp;gt; {
    (async () =&amp;gt; {
      const userData = await fetch("https://api.github.com/users/praveen-me")
.then(response =&amp;gt; response.json());
      setTotalRepos(userData.public_repos);
    })()

    fetchData();
  }, [])

  return (
    &amp;lt;div className="App"&amp;gt;
      {repoData.map((repo, index) =&amp;gt; {
      return (index === repoData.length - 1) ? (&amp;lt;h1 key={repo.name + index}
 className="repo" ref={callBack}&amp;gt;{repo.name}&amp;lt;/h1&amp;gt;) : (&amp;lt;h1 className="repo" key={repo.name + index}&amp;gt;{repo.name}&amp;lt;/h1&amp;gt;)
    })}
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, We need to define an observer and assign it to the &lt;code&gt;useRef&lt;/code&gt; hook. And in the &lt;code&gt;useCallback&lt;/code&gt;, we create a new intersection observer and assign it to the observer i.e. &lt;code&gt;observer.current = new IntersectionObserver(callback, options)&lt;/code&gt;. The callback receives a list of IntersectionObserverEntry objects and the observer. In  IntersectionObserverEntry, there is a list of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserverEntry" rel="noopener noreferrer"&gt;IntersectionObserverEntry&lt;/a&gt;.&lt;br&gt;
We use &lt;code&gt;argus[0].isIntersecting&lt;/code&gt; the entry of it to check whether the target element is intersecting with the viewport or not. &lt;br&gt;
Now, we observe the target element(the element on which we have to apply the observer to invoke the callback) using this &lt;code&gt;observer.current&lt;/code&gt; observer. We apply this observer on the last &lt;code&gt;h1&lt;/code&gt; element i.e. &lt;code&gt;observer.current.observe(node)&lt;/code&gt; which we are getting by &lt;code&gt;useCallback&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (node) observer.current.observe(node);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whenever the callback is invoked, we need to disconnect the observer from the last target element and need to observe again new targeted element. i.e.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (observer.current) observer.current.disconnect();
if (node) observer.current.observe(node);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, whenever the last &lt;code&gt;h1&lt;/code&gt; element interacts with the viewport, the &lt;code&gt;fetchData()&lt;/code&gt; function is invoked and a list of fetched repo is set to the repoData state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (argus[0].isIntersecting) {
        if (currentPage &amp;lt; totalRepos / 30) {
          fetchData();
        }
      }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjo20mwgana2tnwtgqtam.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjo20mwgana2tnwtgqtam.gif" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yeee!!! We have done. &lt;br&gt;
That's the way, you can use "Intersection Observer API" in react for infinite scrolling.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
