最新消息:20190529 VPS服务器已从腾讯云香港换为Vultr新加坡,主题仍用朋友推荐的大前端D8

【已解决】ReactJS中如何实现上拉加载更多数据

ReactJS crifan 1397浏览 0评论

之前已经实现了:

首次进页面后,加载列表,但是只是加载了1页(10条)数据:

  searchCowListByList(start = 1) {
    const url = `/cow/cow/search/list?start=${start}&limit=10`;
    this.props.fetch(url, {}, ( data ) => {
      console.log(data);
      const { cowList } = this.state;
      this.setState({
        cowList: start === 1 ? data : cowList.concat(data)
      });
    });
  }

页面:

reactjs scroll up load more page

javascript – Infinite scrolling with React JS – Stack Overflow

seatgeek/react-infinite: A browser-ready efficient scrolling container based on UITableView

CassetteRocks/react-infinite-scroller: ⏬ Infinite scroll component for React in ES6

RealScout/redux-infinite-scroll: React infinite scroll component designed for a Redux data-flow.

brigade/react-waypoint: A React component to execute a function whenever you scroll to an element.

先去试试:

CassetteRocks/react-infinite-scroller: ⏬ Infinite scroll component for React in ES6

➜  ucowsapp git:(master) ✗ npm install react-infinite-scroller –save
npm WARN ucows-app@6.0.0 No repository field.
npm WARN ucows-app@6.0.0 No license field.
added 1 package and removed 3 packages in 12.154s

然后用代码:

import InfiniteScroll from ‘react-infinite-scroller’;
@connect(reducer, bindActions(actions))
export default class CowManagement extends Component {
  state = {
    cowList: [],
    curPageNum : 1,
    hasMore : true
  };
  constructor(props) {
    super(props);
    autoBind(this);
    this.searchKeyword = "";
    // this.delayedLoadMore = _.debounce(this.searchCowListByList, 200);
    this.searchCowListByList();
  }
  searchCowListByList() {
    console.log(`searchCowListByList: this.state.curPageNum=${this.state.curPageNum},nextPageNum=${nextPageNum}`);
    let nextPageNum = this.state.curPageNum + 1;
    console.log(`nextPageNum=${nextPageNum}`);
    this.setState({ curPageNum : nextPageNum});
    const url = `/cow/cow/search/list?start=${this.state.curPageNum}&limit=10`;
    this.props.fetch(url, {}, ( data ) => {
      console.log(data);
      console.log(typeof(data));
      console.log(data.length);
      //if (data === []) {
      if (data.length === 0) {
        this.setState({hasMore : false});
      }
      console.log(`this.state.hasMore=${this.state.hasMore}`);
      const { cowList } = this.state;
      this.setState({
        cowList: this.state.curPageNum === 1 ? data : cowList.concat(data)
        // cowList: data
      });
    });
  }
  loadMore(){
    console.log("loadMore");
    //setTimeout(this.searchCowListByList, 200);
    this.searchCowListByList();
  }
  render() {
    const { cowList } = this.state;
    const { reproductiveStateTypeDict } = this.props;
    // console.log(cowList);
    return (
      <div class={style.the_herd_all}>
        <Search
          placeholder="请输入牛号搜索"
          onInputChange={this.onInputChange}
        />
        <div class={style.the_herd_all}>
          <ul class={style.nn_a_list}>
                  {/* useWindow={false}
                  threshold={250}
                  element={"a"}
                  initialLoad={false} */}
            <div style="height:600px;overflow:auto;">
              <InfiniteScroll
                  pageStart={0}
                  loadMore={this.loadMore}
                  hasMore={this.state.hasMore}
                  loader={<div className="loader">正在加载 …</div>}
              >
              {
                cowList.map(item => {
                  return (
                    <CowListItem data={item} reproductiveStateTypeDict={reproductiveStateTypeDict} />
                  );
                })
              }
              </InfiniteScroll>
            </div>
          </ul>
        </div>
      </div>
    );
  }
}

但是郁闷的是:

结果是,进入页面后,还没有上拉,就加载完毕所有的页面了:

调试了半天,始终无法实现:

首次进入页面,显示第一页

然后上拉滚动页面到底部时,再去加载第二页,直到无法加载为止。

换用:

RealScout/redux-infinite-scroll: React infinite scroll component designed for a Redux data-flow.

➜  ucowsapp git:(master) ✗ npm install redux-infinite-scroll –save
npm WARN ucows-app@6.0.0 No repository field.
npm WARN ucows-app@6.0.0 No license field.
added 1 package in 11.919s

然后代码改为,类似的写法:

  loadMore(){
    console.log("loadMore");
    //setTimeout(this.searchCowListByList, 200);
    this.searchCowListByList();
  }
  renderItemList(){
    return (
      this.state.cowList.map(item => {
        return (
          <CowListItem data={item} reproductiveStateTypeDict={this.props.reproductiveStateTypeDict} />
        );
      })
    );
  }
  render() {
    // const { cowList } = this.state;
    // const { reproductiveStateTypeDict } = this.props;
    // console.log(cowList);
    return (
      <div class={style.the_herd_all}>
        <Search
          placeholder="请输入牛号搜索"
          onInputChange={this.onInputChange}
        />
        <div class={style.the_herd_all}>
          <ul class={style.nn_a_list}>
                  {/* useWindow={false}
                  threshold={250}
                  element={"a"}
                  initialLoad={false} */}
             {/* <div style="height:600px;overflow:auto;">
              <InfiniteScroll
                  pageStart={0}
                  loadMore={this.loadMore}
                  hasMore={this.state.hasMore}
                  loader={<div className="loader">正在加载 …</div>}
              >
              </InfiniteScroll>
            </div> */}
              {/* {
                cowList.map(item => {
                  return (
                    <CowListItem data={item} reproductiveStateTypeDict={reproductiveStateTypeDict} />
                  );
                })
              } */}
            <InfiniteScroll
              hasMore={this.state.hasMore}
              children={this.renderItemList()}
              loadMore={this.loadMore}
              showLoader={true}
            />
          </ul>
        </div>
      </div>
    );
  }
}

结果问题依旧:

首次进去,就加载完毕所有的数据了。。。

再去试试:

seatgeek/react-infinite: A browser-ready efficient scrolling container based on UITableView

➜  ucowsapp git:(master) ✗ npm install react-infinite –save
npm WARN ucows-app@6.0.0 No repository field.
npm WARN ucows-app@6.0.0 No license field.
added 3 packages in 12.187s

结果代码写好了:

  loadMore(){
    console.log("loadMore");
    this.setState({ isInfiniteLoading: true });
    //setTimeout(this.searchCowListByList, 200);
    this.searchCowListByList();
  }
  renderItemList(){
    return (
      this.state.cowList.map(item => {
        return (
          <CowListItem data={item} reproductiveStateTypeDict={this.props.reproductiveStateTypeDict} />
        );
      })
    );
  }
  elementInfiniteLoad() {
    return <div className="infinite-list-item">
      Loading…
    </div>;
  }
            <Infinite
              elementHeight={40}
              containerHeight={550}
              infiniteLoadBeginEdgeOffset={200}
              onInfiniteLoad={this.loadMore}
              loadingSpinnerDelegate={this.elementInfiniteLoad}
              isInfiniteLoading={this.state.isInfiniteLoading}
            >
              {this.renderItemList()}
            </Infinite>

调用库时,库出错了:

reactjs scroll up bottom load more

react js scroll up bottom load more

react js scroll bottom load more

react-infinite-scroller not work

React infinite scrolling:reactjs

brillout/awesome-react-components: Catalog of React Components & Libraries

nmn/react-infinity: A UITableView Inspired list and grid display solution with element culling and smooth animations

后来去看库:

CassetteRocks/react-infinite-scroller: ⏬ Infinite scroll component for React in ES6

的源码,发现在InfiniteScroll下面是一个div的list:

而不是我此处的所有的item的列表平铺出来的。

结果代码改为:

        <div class={style.the_herd_all}>
          <InfiniteScroll
              pageStart={this.state.curPageNum}
              loadMore={this.loadMore}
              hasMore={this.state.hasMore}
              loader={<div className="loader">正在加载 …</div>}
          >
            <ul class={style.nn_a_list}>
              <div>
                {
                  this.state.cowList.map(item => {
                    return (
                      <CowListItem data={item} reproductiveStateTypeDict={this.props.reproductiveStateTypeDict} />
                    );
                  })
                }
              </div>
            </ul>
          </InfiniteScroll>
        </div>

问题依旧。

此处,把其源码粘贴到项目中,然后稍作改动未Preact的代码。期间遇到:

【已解决】如何把React.createElement转换为preact的语法

然后,去调试,发现个诡异的事情:

第一次加载时,滚动的高度就有22了:

el.scrollHeight=22,el.parentNode.scrollTop=0,el.parentNode.clientHeight=22 -> offset=0

更诡异的是:

在用户没有滚动时,始终继续触发,滚动高度低于thedshold阈值,所以始终继续调用loadMore了:

这部分的log是:

即,在第一次initialLoad=true

el.scrollHeight=22,el.parentNode.scrollTop=0,el.parentNode.clientHeight=22 -> offset=0
InfiniteScroll.js?9381:137 offset < Number(this.props.threshold)=true

加载调用loadMore: pageNum=1后,

还是:

el.scrollHeight=22,el.parentNode.scrollTop=0,el.parentNode.clientHeight=22 -> offset=0
InfiniteScroll.js?9381:137 offset < Number(this.props.threshold)=true

所以导致无限循环下去调用loadMore去加载所有数据了。

所以问题就是要找到:

为何每次都是:

滚动高度el.scrollHeight为22?不应该是0吗?

另外,每次都是:

el.parentNode.scrollTop=0

el.parentNode.clientHeight=22

所以导致:

offset=0

react scrollHeight

react scrollHeight parentNode.clientHeight

有人遇到类似问题:

loading forever without stopping on safari mobile · Issue #26 · CassetteRocks/react-infinite-scroller

那scrollHeight改回offsetHeight去试试:

      // offset = el.scrollHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      offset = el.offsetHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      console.log(`el.scrollHeight=${el.scrollHeight},el.offsetHeight=${el.offsetHeight},el.parentNode.scrollTop=${el.parentNode.scrollTop},el.parentNode.clientHeight=${el.parentNode.clientHeight} -> offset=${offset}`);

结果问题依旧:

el.scrollHeight=22,el.offsetHeight=22,el.parentNode.scrollTop=0,el.parentNode.clientHeight=22 -> offset=0
InfiniteScroll.js?9381:138 offset < Number(this.props.threshold)=true

scrollHeight和offsetHeight都是22,且一直没变,还是一直加载。

Dom scroll parent with unfixed height · Issue #51 · CassetteRocks/react-infinite-scroller

抽空去看看,是否需要使用这个:

digidem/react-dimensions: React higher-order component to get dimensions of container

再试试parentNode.scrollHeight:

      // offset = el.scrollHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      // offset = el.offsetHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      offset = el.parentNode.scrollHeight – el.parentNode.scrollTop – el.parentNode.clientHeight;
      console.log(`el.scrollHeight=${el.scrollHeight},el.offsetHeight=${el.offsetHeight},el.parentNode.scrollHeight=${el.parentNode.scrollHeight},el.parentNode.scrollTop=${el.parentNode.scrollTop},el.parentNode.clientHeight=${el.parentNode.clientHeight} -> offset=${offset}`);

结果问题依旧:

el.scrollHeight=22,el.offsetHeight=22,el.parentNode.scrollHeight=22,el.parentNode.scrollTop=0,el.parentNode.clientHeight=22 -> offset=0
InfiniteScroll.js?9381:139 offset < Number(this.props.threshold)=true

然后去调试,修改了每行row的高度为90,结果log出来的滚动高度还是22

element clientHeight offsetHeight scrollHeight 22

把:

  renderItemList(){
    return (
      this.state.cowList.map(item => {
        return (
          <CowListItem data={item} reproductiveStateTypeDict={this.state.reproductiveStateTypeDict} />
        );
      })
    );
  }

改为:

    let itemList = [];
    this.state.cowList.map((item) => {
      itemList.push(
        <CowListItem data={item} reproductiveStateTypeDict={this.state.reproductiveStateTypeDict} />
      );
    });
    console.log(itemList);

结果问题依旧。

【已解决】ReactJS中如何判断页面滚动到底部以实现下拉加载更多页面数据

转载请注明:在路上 » 【已解决】ReactJS中如何实现上拉加载更多数据

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
68 queries in 0.088 seconds, using 18.86MB memory