0

I´m developing a React application with infinite scrolling using the Intersection Observer API (not using any 3rd library for infinite scrolling). My backend handles pagination properly, and the infinite scrolling also fetches the next parts when reaching the threshold. The problem is, that each time I scroll down and reach the threshold, the window is scrolled back to the top, which is not what I expect. It seems that not just the new items are going to be rendered, but instead the entire list of items.

Here is the way I´ve implemented it in React with Redux so far:

import React, {useEffect, useRef, useCallback} from "react";
import Spinner from "../../UI/Spinner";
import {withRouter} from "react-router-dom";
import {connect} from "react-redux";
import * as actions from "../../store/actions/index";

const List = props => {
    const {items, next, loading, loadMoreData} = props;
    const loader = useRef(null);
    const loadMore = useCallback((entries) => {
        const target = entries[0];
        if (target.isIntersecting && next) {
            !loading && loadMoreData(next);
        }
    }, [loading, next, loadMoreData]);

    useEffect(() => {
        const options = {
            threshold: 1.0
        };

        // Observer API 
        const observer = new IntersectionObserver(loadMore, options);
        const currentLoader = loader.current;
        if (loader && currentLoader) {
            observer.observe(currentLoader);
        }
        return () => observer.unobserve(loader.current);
    }, [loader, loadMore]);

    const content = <Spinner/>;
    if (!loading) {
        content = items.map((item, index) => return (<div key={index}>{item}</div>))
    }

    return (
    <div>
      {content}
      <div ref={loader}></div>
    </div>
    )
}

const mapStateToProps = state => {
    return {
        items: state.items.items,
        next: state.items.next,
        loading: state.items.loading,
        error: state.items.error
    };
};

const mapDispatchToProps = dispatch => {
    return {
        fetchMoreData: (next) => dispatch(actions.fetchDataStart(next)),
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(withRouter(List));

 

So summing up the problem is the following:

After scrolling down the screen and after reaching the set threshold the data is fetched successfully and added to my redux store. But the entire list is rendered again on the top of the page and I have to scroll down again. Any ideas how to solve this?

stefano
  • 315
  • 2
  • 16

1 Answers1

2

This topic can be closed. It was a small and stupid mistake. The re-rendering of the whole list is caused by the if statement where I populate my content variable. Removing this solves the issue and infinite scroll works like a charm.

stefano
  • 315
  • 2
  • 16