Endless Scrolling with React JS

I am considering ways to implement infinite scroll using React. I came across react-infinite-scroll and found it ineffective as it just adds nodes to the DOM and doesn't delete them. Is there a proven solution with React that will add, remove and maintain a constant number of nodes in the DOM.

Here is the jsfiddle problem. In this problem, I want to have only 50 elements in the DOM at a time. others must be downloaded and deleted when the user scrolls up and down. We started using React because of its optimization algorithms. Now I could not find a solution to this problem. I came across airbnb infin js . But it is implemented using jQuery. To use this endless scroll of airbnb, I have to lose the React optimization that I don't want to do.

Sample code I want to add a scroll (here I load all the elements. My goal is to load only 50 elements at a time)

/** @jsx React.DOM */ var Hello = React.createClass({ render: function() { return (<li>Hello {this.props.name}</li>); } }); var HelloList = React.createClass({ getInitialState: function() { var numbers = []; for(var i=1;i<10000;i++){ numbers.push(i); } return {data:numbers}; }, render: function(){ var response = this.state.data.map(function(contact){ return (<Hello name="World"></Hello>); }); return (<ul>{response}</ul>) } }); React.renderComponent(<HelloList/>, document.getElementById('content')); 

Seeking help ...

+84
javascript html reactjs infinite-scroll
Jan 20 '14 at 16:04
source share
3 answers

Basically, when scrolling, you want to decide which elements are visible, and then render to display only those elements, with one spacer element at the top and bottom to represent the elements off-screen.

Vjeux made a fiddle here that you can look at: jsfiddle .

When scrolling is performed

 scrollState: function(scroll) { var visibleStart = Math.floor(scroll / this.state.recordHeight); var visibleEnd = Math.min(visibleStart + this.state.recordsPerBody, this.state.total - 1); var displayStart = Math.max(0, Math.floor(scroll / this.state.recordHeight) - this.state.recordsPerBody * 1.5); var displayEnd = Math.min(displayStart + 4 * this.state.recordsPerBody, this.state.total - 1); this.setState({ visibleStart: visibleStart, visibleEnd: visibleEnd, displayStart: displayStart, displayEnd: displayEnd, scroll: scroll }); }, 

and then the render function will only display lines in the range displayStart..displayEnd .

You may also be interested in ReactJS: bidirectional infinite scroll modeling .

+55
Jan 20 '14 at 17:51
source share

Visit our React Infinite library:

https://github.com/seatgeek/react-infinite

December 2016 Update

In fact, I recently used response-virtualized in many of my projects and found that it covers most use cases much better. Both libraries are good, it depends on what you are looking for. For example, response-virtualized supports variable height JIT measurement through an HOC called CellMeasurer , an example here https://bvaughn.imtqy.com/react-virtualized/#/components/CellMeasurer .

November 2018 update

Many lessons from reaction-virtualization have been moved to the smaller, faster, and more efficient reactive window library of the same author.

+24
Nov 13 '14 at 16:59
source share
 import React, { Component } from 'react'; import InfiniteScroll from 'react-infinite-scroller'; const api = { baseUrl: '/joblist' }; class Jobs extends Component { constructor(props) { super(props); this.state = { listData: [], hasMoreItems: true, nextHref: null }; } fetchData(){ var self = this; var url = api.baseUrl; if(this.state.nextHref) { url = this.state.nextHref; } fetch(url) .then( (response) => { return response.json() }) .then( (json) => { var list = self.state.listData; json.data.map(data => { list.push(data); }); if(json.next_page_url != null) { self.setState({ nextHref: resp.next_page_url, listData: list }); } else { self.setState({ hasMoreItems: false }); } }) .catch(error => console.log('err ' + error)); } } componentDidMount() { this.fetchData(); } render() { const loader = <div className="loader">Loading ...</div>; let JobItems; if(this.state.listData){ JobItems = this.state.listData.map(Job => { return ( <tr> <td>{Job.job_number}</td> <td>{Job.title}</td> <td>{Job.description}</td> <td>{Job.status}</td> </tr> ); }); } return ( <div className="Jobs"> <div className="container"> <h2>Jobs List</h2> <InfiniteScroll pageStart={0} loadMore={this.fetchData.bind(this)} hasMore={this.state.hasMoreItems} loader={loader}> <table className="table table-bordered"> <thead> <tr> <th>Job Number</th> <th>Title</th> <th>Description</th> <th>Status</th> </tr> </thead> <tbody> {JobItems} </tbody> </table> </InfiniteScroll> </div> </div> ); } } export default Jobs; 
+1
Apr 11 '18 at 8:16
source share



All Articles