React 延迟加载/无限滚动解决方案

Posted

技术标签:

【中文标题】React 延迟加载/无限滚动解决方案【英文标题】:React lazy load/infinite scroll solutions 【发布时间】:2017-08-08 06:36:44 【问题描述】:

我花了一段时间才弄清楚如何使用出色的 React Lazyload component 延迟加载图像。

演示延迟加载图像滚动但在测试时我无法获得相同的行为。

罪魁祸首是overflow: auto;,它与按预期工作的组件发生冲突。

在 React 中延迟加载大型图片库/幻灯片的最佳方法是什么?

React Lazyload(非常喜欢这个组件但想研究其他组件)

React Virtualized(看似沉重但功能丰富)

React Infinite(由于复杂性,进入门槛更高)

React Lazylist(直截了当,但不确定是否最适合图像)

其他...?

我有一个通用/同构应用程序,因此由于窗口对象无法在服务器上使用,上述某些应用程序会中断。

【问题讨论】:

【参考方案1】:

我是React Lazy Load Image Component 的作者,它应该适用于同构应用程序。

【讨论】:

【参考方案2】:

如果您想要一个更简单的延迟加载解决方案并且不必使用其他人的包/代码,请尝试使用IntersectionObserver API。

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

我写了一篇关于如何使用它在 React 组件中延迟加载图像的 Medium 文章(实现与 vanilla JS 基本相同)。

https://medium.com/@parkjoon94/lazy-loading-images-intersectionobserver-8c5bff730920

你只需要这部分代码(sn-p from above article):

this.observer = new IntersectionObserver(
  entries => 
    entries.forEach(entry => 
      const  isIntersecting  = entry;
      if (isIntersecting) 
        this.element.src = this.props.src;
        this.observer = this.observer.disconnect();
      
    );
  , 
);

【讨论】:

【参考方案3】:
import React from "react";
import PropTypes from "prop-types";
import axios from "axios";
import InfiniteScroll from "react-infinite-scroller";
const styles = theme => (
  root: 
    textAlign: "center",
    paddingTop: theme.spacing.unit * 20
  
);

class Parent extends React.Component 
  state = 
    allposts: [],
    posts: [],
    hasMore: true,
    curpage: 0,
    pagesize: 30,
    totalPage: 0,
    total: 0
  ;

  componentDidMount() 
    axios.get("https://jsonplaceholder.typicode.com/posts").then(res => 
      let curpage = this.state.curpage;
      let posts = res.data.slice(
        curpage * this.state.pagesize,
        (curpage + 1) * this.state.pagesize
      );
      this.setState(
        allposts: res.data,
        posts: posts,
        total: res.data.length,
        totalPage: Math.ceil(res.data.length / this.state.pagesize)
      );
    );
  

  loadmoreItem() 
    if (this.state.curpage + 1 < this.state.totalPage) 
      let curpage =
        this.state.curpage < this.state.totalPage
          ? this.state.curpage + 1
          : this.state.curpage;
      let posts = this.state.allposts.slice(
        0,
        (curpage + 1) * this.state.pagesize
      );
      this.setState( posts: posts, curpage );
     else 
      this.setState( hasMore: false );
    
  

  render() 
    if (this.state.posts.length === 0) return <h1>loading...</h1>;
    else 
      console.log(this.state);
      return (
        <div>
          <Table
            hasMore=this.state.hasMore
            posts=this.state.posts
            loadmoreItem=this.loadmoreItem.bind(this)
          />
        </div>
      );
    
  


export default Parent;

const Table = props => 
  console.log("props: ", props);
  return (
    <React.Fragment>
      <div style= height: "400px", overflow: "auto" >
        <InfiniteScroll
          pageStart=0
          loadMore=props.loadmoreItem
          hasMore=props.hasMore
          loader=
            <div className="loader" key=0>
              Loading ...
            </div>
          
          useWindow=false
          threshold=350
        >
          <table>
            <tr>
              <th>id</th>
              <th>title</th>
              <th>body</th>
            </tr>
            props.posts.map(item => 
              return (
                <tr>
                  <td>item.id</td>
                  <td>item.title</td>
                  <td>item.body</td>
                </tr>
              );
            )
          </table>
        </InfiniteScroll>
      </div>
      <button onClick=props.loadmoreItem>next</button>
    </React.Fragment>
  );
;

在此处查看实时示例

https://codesandbox.io/s/x228lmm90q

【讨论】:

以上是关于React 延迟加载/无限滚动解决方案的主要内容,如果未能解决你的问题,请参考以下文章

ember.js 无限滚动(延迟加载)

在无限滚动中延迟加载时锁定滚动位置(向上滚动)

jQuery 无限滚动/延迟加载

如何在响应本机的平面列表中应用延迟加载

如何使用 mongodb 数据延迟加载角度

React 中的延迟加载 util 函数