【问题标题】:Listening to scroll events to do infinite scrolling..?监听滚动事件以进行无限滚动..?
【发布时间】:2018-09-21 10:50:36
【问题描述】:

我需要无限滚动,所以我首先想到的是,我怎么知道表格的滚动属性?以便我可以决定加载更多项目并更新状态?

例如,如何知道仍然只有 10 个项目没有看到(超出视口)?

【问题讨论】:

    标签: react-table


    【解决方案1】:

    我刚刚在 codepen.io 上写了一个infinite scrolling ReactJS 演示,请检查一下,至少给我一个UP,谢谢,哈哈。

    不知道能不能解释清楚,但我已经尽力了:)

    我怎么知道表格的滚动属性

    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();
        }
      });
    }
    

    如何知道仍然只有 10 个项目没有看到(超出视口)

    Answer 另外,您需要一个规则,标记是否还有更多数据要加载,或者只标记有noMoreData 并停止加载。

    实际上,在生产环境中,我们不会统计剩余的物品数量,也可能不知道。由于我们需要从服务器端请求数据,比如 RESTful API,只有这样我们才能知道是否还有更多的项目。

    比如我向xx.api.com/getList?pageNo=1&amp;size=10请求数据,也就是说我从第一页开始,我希望每页的长度是10。

    如果它响应一个空数组或一个长度小于 10 的数组,那么我可以将状态 noMoreData 标记为 trueif (noMoreData === true)fetchData() 只会返回,不会再从 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
          });
        }
      }
    

    【讨论】:

    • 感谢玉莹的回答,很清楚,当然你应该得到赏金:)
    • @simo 感谢赏金,我现在可以到处评论了。
    • 很高兴听到这样的消息.. :)
    猜你喜欢
    • 2015-05-30
    • 1970-01-01
    • 2012-09-13
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多