听滚动事件做无限滚动..?
Listening to scroll events to do infinite scrolling..?
我需要做无限滚动,所以我首先想到的是,我怎么知道table的滚动属性?以便我可以决定加载更多项目并更新状态?
比如,如何知道仍然只有 10 个项目未看到(超出视口)?
我刚刚在codepen.io上写了一个infinite scrolling ReactJS演示,请看一下,至少给我一个UP,谢谢,哈哈。
不确定我是否能解释清楚,但我已经尽力了:)
how would I know the scrolling properties of the table
Answer
当您进行无限滚动时,您决定加载更多的时刻是当最后一个列表元素位于底部时。首先,我们需要定义一个边界和一个规则,当用户滚动页面时,你会从哪里获取更多的数据。
在我的演示中,我将容器的底线设置为数据获取边界。
// jsx
<div className="container" ref={ref => this.container = ref}>
{ list.map((item, index) => (
<p className="list-item" key={`item-${index}`}>{ item.name }</p>
))}
<div ref={ref => this.bottomLine = ref}></div>
</div>
// listen to the scroll event of the container
// when the bottom-line element reaches the bottom of the container
// fetchData() will be triggered
componentDidMount() {
this.container.addEventListener('scroll', () => {
const CONTAINER_HEIGHT = this.container.getBoundingClientRect().height;
const { top: bottomLineOffsetTop } = this.bottomLine.getBoundingClientRect();
if (bottomLineOffsetTop <= CONTAINER_HEIGHT) {
console.log('load more data');
this.fetchData();
}
});
}
how to know that there is still only 10 items not seen ( beyond the viewport)
Answer
另外,你需要一个规则,来标记你是否有更多的数据要加载,或者只是标记有noMoreData
并停止加载.
其实在生产环境中,我们不会统计还剩多少条,也可能不知道。因为我们需要向服务器端请求数据,比如RESTful API,只有这样我们才能知道是否有更多的项目。
比如我从xx.api.com/getList?pageNo=1&size=10
请求数据,也就是说我从第一页开始,我希望每页的长度是10。
如果它返回一个空数组或者长度小于10的数组,那么我可以把状态noMoreData
标记为true
。 if (noMoreData === true)
、fetchData()
只会 return 并且不会再从 api 请求数据。
fetchData() {
const { list, pageNo, displayCount, noMoreData } = this.state;
if (noMoreData) {
console.log('no more data');
return;
}
if (pageNo > 6) {
// no more data
this.setState({
noMoreData: true
});
} else {
let responseList = [];
// mock the response of a API request
for(let i = 0; i < 5; i++) {
responseList.push({
name: `from-page-${pageNo}`
});
}
this.setState({
list: [ ...list, ...responseList ],
pageNo: pageNo + 1
});
}
}
我需要做无限滚动,所以我首先想到的是,我怎么知道table的滚动属性?以便我可以决定加载更多项目并更新状态?
比如,如何知道仍然只有 10 个项目未看到(超出视口)?
我刚刚在codepen.io上写了一个infinite scrolling ReactJS演示,请看一下,至少给我一个UP,谢谢,哈哈。
不确定我是否能解释清楚,但我已经尽力了:)
how would I know the scrolling properties of the table
Answer
当您进行无限滚动时,您决定加载更多的时刻是当最后一个列表元素位于底部时。首先,我们需要定义一个边界和一个规则,当用户滚动页面时,你会从哪里获取更多的数据。
在我的演示中,我将容器的底线设置为数据获取边界。
// jsx
<div className="container" ref={ref => this.container = ref}>
{ list.map((item, index) => (
<p className="list-item" key={`item-${index}`}>{ item.name }</p>
))}
<div ref={ref => this.bottomLine = ref}></div>
</div>
// listen to the scroll event of the container
// when the bottom-line element reaches the bottom of the container
// fetchData() will be triggered
componentDidMount() {
this.container.addEventListener('scroll', () => {
const CONTAINER_HEIGHT = this.container.getBoundingClientRect().height;
const { top: bottomLineOffsetTop } = this.bottomLine.getBoundingClientRect();
if (bottomLineOffsetTop <= CONTAINER_HEIGHT) {
console.log('load more data');
this.fetchData();
}
});
}
how to know that there is still only 10 items not seen ( beyond the viewport)
Answer
另外,你需要一个规则,来标记你是否有更多的数据要加载,或者只是标记有noMoreData
并停止加载.
其实在生产环境中,我们不会统计还剩多少条,也可能不知道。因为我们需要向服务器端请求数据,比如RESTful API,只有这样我们才能知道是否有更多的项目。
比如我从xx.api.com/getList?pageNo=1&size=10
请求数据,也就是说我从第一页开始,我希望每页的长度是10。
如果它返回一个空数组或者长度小于10的数组,那么我可以把状态noMoreData
标记为true
。 if (noMoreData === true)
、fetchData()
只会 return 并且不会再从 api 请求数据。
fetchData() {
const { list, pageNo, displayCount, noMoreData } = this.state;
if (noMoreData) {
console.log('no more data');
return;
}
if (pageNo > 6) {
// no more data
this.setState({
noMoreData: true
});
} else {
let responseList = [];
// mock the response of a API request
for(let i = 0; i < 5; i++) {
responseList.push({
name: `from-page-${pageNo}`
});
}
this.setState({
list: [ ...list, ...responseList ],
pageNo: pageNo + 1
});
}
}