1

I have an infinitely scrollable component, I want it to load more data when the users scrolls to the bottom of the page but it just loads the first set of data and then stops. Below is my code:

import { Avatar, List, Spin, message } from 'antd';
import React, { Component } from 'react';

import InfiniteScroll from 'react-infinite-scroller';
import Services from '../../services/Services';

/**
 * infinitely scrollable timeline of uploaded content
 */
class Timeline extends Component {

  /**
   *
   * @param {*} props
   */
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      hasMore: true,
      data: []
    };
    this.fetchData = this.fetchData.bind(this);
  }

  /**
   * on load
   */
  componentDidMount() {
    this.fetchData();
  }

  /**
   * fetch the data
   */
  fetchData() {
    Services.getData()
        .then((response) => this.handleData(response))
        .catch((error) => this.handleError(error));
  }


  /**
   * handle the data
   * @param {*} response
   */
  handleData(response) {
    const data = this.state.data.concat(response.data);
    this.setState({ data: data });
  }

  /**
   * handle the infinite on load
   */
  handleInfiniteOnLoad() {
    this.setState({
      loading: true,
    });
    this.fetchData();
    this.setState({
      loading: false
    });
  };

  /**
   * handle any error
   * @param {*} error
   */
  handleError(error) {
    console.log(error);
  }

  /**
   * @return {*}
   */
  render() {
    return (
      <div className="demo-infinite-container">
        <InfiniteScroll
          initialLoad={false}
          pageStart={0}
          loadMore={this.fetchData}
          hasMore={!this.state.loading && this.state.hasMore}
          useWindow={true}
          loader={<div className="loader" key={0}>Loading ...</div>}
        >
          <List
            dataSource={this.state.data}
            renderItem={item => (
              <List.Item key={item.id}>
                <List.Item.Meta
                  avatar={
                    <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
                  }
                  title={<a href="https://ant.design">{item.id}</a>}
                  description={item.id}
                />
                <div>Content</div>
              </List.Item>
            )}
          >
            {this.state.loading && this.state.hasMore && (
              <div className="demo-loading-container">
                <Spin />
              </div>
            )}
          </List>
        </InfiniteScroll>
      </div>
    );
  }
}
export default Timeline;

The code is copied from ant design but it is using my own data that I retrieve from the backend.

Thanks in advance!

K. Martin
  • 73
  • 13
  • in `InfiniteScroll` props use `loadMore={this.fetchData}` this instead of `loadMore={this.fetchData()}` – shubham jha Oct 27 '20 at 14:34
  • I've done that and now it won't load any more data when I scroll to the bottom – K. Martin Oct 27 '20 at 14:55
  • that's different issue, you need to set an appropriate value for `hasMore`, for now try with `hasMore={true}` – shubham jha Oct 27 '20 at 15:01
  • I realise now that it is a different issue and have updated the question accordingly, thank you for the help. I have already set an appropriate value for ```hasMore``` which equates to true – K. Martin Oct 27 '20 at 15:04
  • you need to add logic for increase data in `this.state.data` if it has more data when scroll , your `loadMore` function downloads all the data in one go , you can store all data in state and when `loadMore` gets called increase the data you are rendering. – shubham jha Oct 27 '20 at 15:10
  • Because there is a huge amount of data that can be retrieved, I need to only retrieve the data that I am rendering and then call the back end to retrieve more when the user scrolls to the bottom – K. Martin Oct 27 '20 at 15:19
  • you have not provided `dataLength` props try with `dataLength={this.state.data.length}` – shubham jha Oct 27 '20 at 15:27
  • That has not worked – K. Martin Oct 27 '20 at 15:29
  • I think `dataLength` is the important prop they have mentioned in doc – shubham jha Oct 27 '20 at 15:30
  • It does not say so in the readme of the component: https://github.com/danbovey/react-infinite-scroller. I have also tried adding it and nothing has changed – K. Martin Oct 27 '20 at 15:31
  • that library has depricated use this one https://github.com/ankeetmaini/react-infinite-scroll-component API is almost same – shubham jha Oct 27 '20 at 15:34
  • Okay, I have changed it to the new component and added the dataLength and it is still not working – K. Martin Oct 27 '20 at 15:39
  • you can play with this code https://codesandbox.io/s/yk7637p62z to know what is issue in your code if still, you couldn't find the issue post minimum code to reproduce in the sandbox and share link – shubham jha Oct 27 '20 at 15:43

1 Answers1

1

I finally found that I needed to add styles to the surrounding div to make it scrollable, rather than the whole page being scrollable. The code is below:

<div className="demo-infinite-container" style={{ overflow: 'auto', padding: '8px 24px', height: '300px'}}>

K. Martin
  • 73
  • 13