title: How can I stop duplicate array in my React - using infinite scroll?
body: <p>I have tried to do an infinite scroll by using <a href="https://www.npmjs.com/package/react-infinite-scroll-component" rel="nofollow noreferrer">React-Infinite-Scroll-Component</a></p>
  <p>Everything is working perfectly as I think, but the problem is whenever I change the Genres, or press F5 to reload the page, or somehow, the scrollbar is always at the very bottom, I did try to fix it with <code>window.scrollTo(0,0)</code> but it's still not working.</p>
  <p>Or somehow do I mess up the code because I tried to work around it very hard, but I don't think I execute it well enough.</p>
  <p>The code is very <em><strong>long</strong></em> but here's a brief explanation of what I'm trying to do in it.</p>
  <p>I received a slug which defined as a <code>genre</code> with <code>useParams</code>, for example <code>action</code> or <code>adventure</code>, then I set it as a state <code>genreAnime</code>, then I check if it's the same genre, it'll do the infinite load with <code>concat array</code> and increase the page up to 1 for the next load, else I'll set a new <code>array</code> and initial the page back to 1 or else it'll keep merging with an old array of previous <code>genre</code>. The <code>totalPage</code> is set to 91, whenever it renders for the second time it'll automatically get the latest <code>totalPage</code> and set it back, so it's safe to go.</p>
  <p>The <code>translateGenre</code> is just for translating the genre into text, so please don't bother it.</p>
  <p>But then whenever I refresh (F5) or whenever I browse for a bit, then I change the genre, it'll get a duplicate of the same <code>first array</code> (due to warning and I see it has 2 same items). Due to the scrollbar of mine always staying at the &quot;end&quot; or at the <code>default</code> value of <em><strong>React-Infinite-Scroll-Component</strong></em>, which is 0.8, it means when users come below 80% of the total height, it'll trigger the <code>next</code> function of <code>Infinite-Scroll-Component</code></p>
  <p>Here's my code:</p>
  <pre><code>function AnimeGenre({ instance }) {
      const { genre } = useParams()
  
      const CancelToken = axios.CancelToken
      const source = CancelToken.source()
  
      const [animeList, setAnimeList] = useState([])
      const [genreAnime, setGenreAnime] = useState(&quot;&quot;)
      const [page, setPage] = useState(1)
      const [totalPage, setTotalPage] = useState(91)
      const [translateGenreAnime, setTranslateGenreAnime] = useState(&quot;&quot;)
  
      const getList = async () =&gt; {
          await instance
              .get(`/anime/${genre}?page=${page}`, {
                  cancelToken: source.token,
              })
              .then((response) =&gt; {
                  const newPage = page + 1
                  setPage(newPage)
                  const newList = response.data.data.map((anime) =&gt; ({
                      slug: anime.slug,
                      thumbnail: anime.thumbnail,
                      name: anime.name,
                      views: anime.views,
                  }))
                  setTotalPage(response.data.pagination.totalPage)
                  setAnimeList((prev) =&gt; {
                      return [...new Set([...prev, ...newList])]
                  })
              })
              .catch((thrown) =&gt; {
                  if (axios.isCancel(thrown)) return
              })
      }    
      useEffect(() =&gt; {
          if (genre === genreAnime) {
              getList()
              translateGenre()
          } else {
              window.onbeforeunload = function () {
                window.scrollTo(0, 0)
               }
              window.scrollTo({
                  top: 0,
              })
              setPage(1)
              setAnimeList([])
              setGenreAnime(genre)
          }
  
          return () =&gt; {
              source.cancel()
          }
      }, [genreAnime, genre])
  
      const translateGenre = () =&gt; {
          for (let i = 0; i &lt; GENRES.length; i++) {
              if (genreAnime == GENRES[i].slug) {
                  setTranslateGenreAnime(GENRES[i].name)
              }
          }
      }
  
      return (
          &lt;&gt;
              &lt;div&gt;
                  &lt;h1&gt;ANIME {translateGenreAnime}&lt;/h1&gt;
              &lt;/div&gt;
              &lt;div className=&quot;anime-list&quot;&gt;
                  &lt;InfiniteScroll
                      initialScrollY={0}
                      style={{ overflow: &quot;none&quot; }}
                      dataLength={animeList.length}
                      next={getList}
                      hasMore={page === totalPage ? false : true}
                      loader={
                          &lt;Row xs={1} sm={2} md={3} lg={4}&gt;
                              {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((skeleton) =&gt; (
                                  &lt;Col key={skeleton}&gt;
                                      &lt;Card&gt;
                                          &lt;Card.Body style={{ maxHeight: &quot;100%&quot; }}&gt;
                                              &lt;Skeleton
                                                  variant=&quot;rectangular&quot;
                                                  width=&quot;100%&quot;
                                                  height=&quot;192px&quot;
                                                  animation=&quot;wave&quot;
                                                  sx={{ bgcolor: &quot;grey.900&quot; }}
                                              /&gt;
  
                                              &lt;Skeleton
                                                  variant=&quot;text&quot;
                                                  animation=&quot;wave&quot;
                                                  sx={{ bgcolor: &quot;grey.900&quot; }}
                                              /&gt;
                                          &lt;/Card.Body&gt;
                                      &lt;/Card&gt;
                                  &lt;/Col&gt;
                              ))}
                          &lt;/Row&gt;
                      }
                      endMessage={&lt;h4&gt;NO MORE THINGS TO LOAD&lt;/h4&gt;}
                  &gt;
                      &lt;Row xs={1} sm={2} md={3} lg={4}&gt;
                          {animeList.map((anime) =&gt; (
                              &lt;Col key={anime.slug}&gt;
                                  &lt;Card&gt;
                                      &lt;div className=&quot;card-container&quot;&gt;
                                          &lt;Card.Img
                                              variant=&quot;top&quot;
                                              src={anime.thumbnail}
                                              fluid=&quot;true&quot;
                                          /&gt;
                                          &lt;div className=&quot;overlay-card&quot;&gt;
                                              &lt;a className=&quot;icon&quot;&gt;{&lt;BsFillPlayFill size={40} /&gt;}&lt;/a&gt;
                                          &lt;/div&gt;
                                      &lt;/div&gt;
                                      &lt;Card.Body&gt;
                                          &lt;Card.Title&gt;
                                              &lt;TextTruncate
                                                  line={2}
                                                  element=&quot;span&quot;
                                                  truncateText=&quot;…&quot;
                                                  text={anime?.name}
                                              /&gt;
                                          &lt;/Card.Title&gt;
                                      &lt;/Card.Body&gt;
                                  &lt;/Card&gt;
                                  &lt;div className=&quot;w-100&quot;&gt;&lt;/div&gt;
                              &lt;/Col&gt;
                          ))}
                      &lt;/Row&gt;
                  &lt;/InfiniteScroll&gt;
              &lt;/div&gt;
           &lt;&gt;
          }
  </code></pre>
  <p>It's work fine whenever the <code>scrollbar</code> stay at the very top, because it won't surpass the threshold of 80% of the height.</p>
  <p>Working one:</p>
  <p><a href="https://i.stack.imgur.com/5LRo8.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/5LRo8.gif" alt="Scrollbar on top is work" /></a></p>
  <p>Fail when I browse a bit and change the <code>GENRE</code>, due to the scrollbar is stay at bottom, then later on, it'll do the scrollTo(0,0). Which is not what I want, I want the opposite, it must always go to top first...</p>
  <p><a href="https://i.stack.imgur.com/4aTBw.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4aTBw.gif" alt="Fail when change GENRE" /></a></p>
  <p>The second fail is when I press reload the page with F5 button. It'll somehow display very weird (the scrollbar).</p>
  <p><a href="https://i.stack.imgur.com/Bugbr.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Bugbr.gif" alt="F5 fail" /></a></p>
  <p>UPDATE:</p>
  <p>I tried to disable <code>smooth-scrolling behavior</code> and set up the scroll to top into the <code>header</code> component that has the navbar, that's seem more proper way to do it, it's get my scrollbar to the top as I want whenever I clicked something in the header or refresh using F5.</p>
  <p>But still if at the first time render, I browse the page and scroll down too fast, I'll get duplicate error due to I meet the threshold and the previous function is still being executed, if I wait for the first render to fully load, then pretty much I am fine, is there any proper way to do infinite scroll, please show me some simple way, I feel like I'm making it too compicated.</p>