问题
I need to do infinite scrolling, so the first thing came into my mind, how would I know the scrolling properties of the table? so that I can decide loading more items and update the state?
Like, how to know that there is still only 10 items not seen ( beyond the viewport) ?
回答1:
I just wrote a infinite scrolling ReactJS demo on codepen.io, please check it out and at least give me an UP, thanks, haha.
Not sure if I can explain clearly, but I've tried my best :)
how would I know the scrolling properties of the table
Answer
When you do infinite scrolling, the moment that you decide to load more, is when the last list element is at the bottom. First of all, we need to define a boundary as well as a rule, when a user scrolls the page, where will you fetch more data.
In my demo, I set the bottom line of the container as the data-fetching boundary.
// 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
Also, You need a rule, to mark whether you have more data to load, or just mark there is noMoreData
and stop loading.
In fact, in production environment, we will not count how many items are left, or maybe we don't know. As we need to request the data from the server side, like RESTful APIs, only then will we know whether there are more items.
For example, I request data from xx.api.com/getList?pageNo=1&size=10
, which means I start from the first page, and I want the length of per page is 10.
If it responses with an empty array or an array the length of which is less than 10, then I can mark the state noMoreData
as true
. if (noMoreData === true)
, fetchData()
will just return and will not request data from the api anymore.
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
});
}
}
来源:https://stackoverflow.com/questions/49776986/listening-to-scroll-events-to-do-infinite-scrolling