Javascript 使用React JS无限滚动
我正在寻找用React实现无限滚动的方法。我发现它效率低下,因为它只是将节点添加到DOM中,而没有删除它们。是否有任何经过验证的React解决方案可以在DOM中添加、删除和保持恒定数量的节点 问题就在这里。 在这个问题中,我希望在DOM中一次只包含50个元素。其他的应该在用户上下滚动时加载和删除。 我们已经开始使用React,因为它的优化算法。现在我找不到解决这个问题的办法。我遇到过。但是它是用Jquery实现的。要使用这个airbnb无限卷轴,我必须放松我不想做的React优化 如果我正在加载所有项目,则要添加的示例代码。我的目标是一次只加载50个项目Javascript 使用React JS无限滚动,javascript,html,infinite-scroll,reactjs,Javascript,Html,Infinite Scroll,Reactjs,我正在寻找用React实现无限滚动的方法。我发现它效率低下,因为它只是将节点添加到DOM中,而没有删除它们。是否有任何经过验证的React解决方案可以在DOM中添加、删除和保持恒定数量的节点 问题就在这里。 在这个问题中,我希望在DOM中一次只包含50个元素。其他的应该在用户上下滚动时加载和删除。 我们已经开始使用React,因为它的优化算法。现在我找不到解决这个问题的办法。我遇到过。但是它是用Jquery实现的。要使用这个airbnb无限卷轴,我必须放松我不想做的React优化 如果我正在加载
/** @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'));
寻找帮助…基本上,滚动时,您希望确定哪些元素可见,然后重新滚动以仅显示这些元素,在顶部和底部使用单个间隔元素来表示屏幕外的元素 在这里做了一把小提琴,你可以看看: 滚动时执行
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范围内的行
您可能还对以下内容感兴趣。请查看我们的React无限库: 2016年12月更新 事实上,我最近已经在我的很多项目中使用了它,并且发现它更好地涵盖了大多数用例。这两个库都很好,这完全取决于你在寻找什么。例如,react virtualized支持通过一个名为CellMeasurer的HOC进行可变高度JIT测量,如下所示 2018年11月更新
react虚拟化的许多经验教训已从同一作者那里移植到更小、更快、更高效的库中。这是一项伟大的技术。。。谢谢!但是,当每行的记录高度不同时,它将失败。我正在尝试解决这种情况。如果我能让它工作,我会发布它。@manalang你找到了每行不同高度的解决方案了吗?另一个要检查的项目是infinity.js for inspiration。如果有动态高度元素,则可以创建页面的概念,该页面是视口中的一组元素。假设有3个元素,第三个元素是超长的,从页面延伸出去。然后你可以说,页面高度是最大的3个元素的大小。然后使用最小元素高度构造虚拟节点。所以var count=pageHeight/minElementHeight。因此,即使只渲染了3个元素,您也可以构造50个元素,但这仍然会给您带来良好的性能。“生成”按钮出现,但没有其他按钮。@sophie alpert:可以更新JSFIDLE吗?我知道你会很忙,但如果你能更新它,这将使许多像我这样的人受益:D@jos:使用此库。它将删除/附加视口中显示的DOM节点。只有在渲染前知道元素的高度时,此库才能工作。@Druska,从技术上讲是的,但是您也可以使用useWindowAsScrollContainer选项将窗口用作滚动容器。react infinite库是否支持网格?确实如此,
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;