Search code examples
javascriptreactjseventsinfinite-scroll

Javascript / React - scroll event triggered when navigating to another page


I'm building a company's internal social network (it's actually a training project, not a real life application) and I'm struggling with a scroll event that's causing me troubles.

I'm using React 18 and React router dom v6.

I have a Home page displaying posts from all users 5 by 5 with an infinite scroll. I also have a Profile page which does the same with the posts from a specific user. My infinite scroll is built more or less like the one in this tutorial (the version without external library).

Everything works well on each page except in a particular scenario. Let's say I'm on the Home page, I scroll to the bottom and get 5 more posts, then click in the header on the link to my Profile page. The Profile page will display the 5 first posts twice, which is obviously not what I want.

But that only occurs if I was below the first 5 posts on the Home page before navigating to the Profile page. If I scroll back up before navigating, or if I don't fetch additional posts before navigating, no issue.

I believe I isolated the problem: it comes from the function that detects the bottom of the page and requests 5 more posts. In the scenario described above, this function gets triggered when arriving on the new page, on top of the initial render. So my initial render requests the first 5 posts from my API and my bottom-of-page function does the same.

Here is the function

window.onscroll = async function () {
    if (loading === true) return;
    if (
        window.location.href.includes('profile') &&
        window.innerHeight + Math.ceil(window.scrollY) >=
            document.body.offsetHeight + 80 &&
        reachedLastProfilePost === false
    ) {
        FetchFivePostsFromUser();
    }
};

So my issues are:

  1. I cannot understand why this function is triggered, since I'm not scrolling when the new page is loading.
  2. I don't know how to fix this.

I tried convoluted fixes like implementing a scroll to top on navigation because my issue seems to disappear if I'm towards the top of the page before navigating. Also tried a timeout on the fetch requests, and other stuff. But I'm now officially out of ideas.

Well, that was my first question here on Stack Overflow and I'm not a native English speaker so please excuse me if it was too long or not clear enough. And don't hesitate to request clarifications or more code excerpts if needed.


Solution

  • It appears that my issue was that I was not cleaning up my bottom-of-page detection function properly.

    Being new to React I was assuming that it was cleaning up the functional component and all its sub-functions when unmounting the component, i.e when I was leaving the page. But that was an incorrect asumption.

    So what I did is I modified the function as below:

    const handleScroll = async () => {
        if (loading === true) return;
        if (
            window.location.href.includes('home') &&
            window.innerHeight + Math.ceil(window.scrollY) >=
                document.body.offsetHeight + 80 &&
            reachedLastPost === false
        ) {
        await FetchFivePosts();
        }
    };
    

    And I passed it as a callback to an event listener that I create in a useEffect hook and properly clean with removeEventListener in the return of the useEffect.

    Not 100% sure but I think that's the proper way to do it. I would appreciate if somebody can confirm it, though.