Chris Yoon
Chris Yoon

Reputation: 85

React Redux + Infinite Scroll = re-rendering whole list?

new to React and I'm trying to use this component https://github.com/danbovey/react-infinite-scroller to integrate infinite scrolling into my list component (which uses redux).

However the issue I'm facing is that when I scroll down to the bottom of the list, it successfully loads more items, but it seems to re-render the whole entire list instead of only rendering new items to the bottom of the list. This also causes the window to scroll back to the top which is not what I expected.

Any ideas what's wrong? Posted my code below:

import React, { useEffect } from 'react';
import './ItemList.sass';
import { connect } from 'react-redux';
import { fetchItems } from '../../../actions/itemListActions'
import ItemListing from './ItemListing'
//import InfiniteScroll from 'react-infinite-scroll-component';
import InfiniteScroll from 'react-infinite-scroller';

const ItemList = ({ items, fetchItems }) => {
    const itemsPerLoad = 15;

    useEffect(() => {
        if (items && !items.isNew) {
            return;
        }
        fetchItems({
            offset: 0,
            limit: 15,
            isNew: true,
            sort: null,
            reverse: null,
            filters: {},
            search: null
        })
    }, [])

    const loadMore = () => {
        console.log("Loading more");
        if (items.isFetching) {
            return;
        }

        if (items.isNew) {
            return;
        }
        
        fetchItems({
            offset: items.data.length,
            limit: itemsPerLoad,
            isNew: false,
            sort: items.sort,
            reverse: items.reverse,
            filters: items.filters,
            search: items.search
        });
    }

    return (
        <div className="item-list">
            <div>Total items: {items.total}</div>
            {items.isFetching ? (
                <div>Loading..</div>
            ) : items.error ? (
                <div>An error occured. Please try again later.</div>
            ) : (
                <InfiniteScroll
                    loadMore={loadMore}
                    hasMore={items.total > items.data.length}
                    loader={<div key={0}>Loading...</div>}
                    initialLoad={false}
                    >
                    {items.data &&
                    items.data.map(item =>
                        <ItemListing
                            key={item.id}
                            item={item}>
                        </ItemListing>
                    )}
                </InfiniteScroll>
            )}
        </div>
    );
}

const mapStateToProps = state => {
    return {
        items: state.itemList.items
    }
}

const mapDispatchToProps = dispatch => {
    return {
        fetchItems: (params) => dispatch(fetchItems(params))
    }
}

export default connect(mapStateToProps,mapDispatchToProps)(ItemList);

Upvotes: 2

Views: 2762

Answers (1)

hrgui
hrgui

Reputation: 630

Here are some things to try:

  1. Ensure item.id is defined. Otherwise, React is going to re-render the entire list.
  2. When you are fetching the next set of items, notice that there is a ternary condition items.isFetching ? items.error block : InfiniteScroll. This would cause <InfiniteScroll /> to get remounted again on every single fetch.

Upvotes: 7

Related Questions