我正在寻找用React实现无限滚动的方法。我遇到过react-infinite-scroll,发现它的效率很低,因为它只是向DOM添加节点,而不是删除它们。有没有经过验证的React解决方案,可以在DOM中添加、删除和维护固定数量的节点。
这就是jsfiddle问题。在这个问题中,我希望在DOM中一次只有50个元素。当用户向上和向下滚动时,应加载和删除其他内容。我们已经开始使用React,因为它的优化算法。现在我找不到解决这个问题的办法。我遇到了airbnb infinite js。但它是用Jquery实现的。要使用这个airbnb无限滚动,我必须松开我不想做的React优化。
示例代码我想添加滚动是(在这里我加载所有的项目。我的目标是一次只加载50个项目)
/** @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'));
寻找帮助...
发布于 2014-01-21 01:51:03
基本上,当滚动时,您希望确定哪些元素是可见的,然后重新渲染以仅显示这些元素,并在顶部和底部使用单个间隔元素来表示屏幕外的元素。
Vjeux在这里做了一个小提琴,你可以看看:jsfiddle。
滚动时,它将执行
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
});
},
然后,render函数将只显示范围displayStart..displayEnd
中的行。
您也可能对ReactJS: Modeling Bi-Directional Infinite Scrolling感兴趣。
发布于 2018-04-11 16:16:22
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;
https://stackoverflow.com/questions/21238667
复制相似问题