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

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

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

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

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

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

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

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

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

其他...?

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

【问题讨论】:

    标签: javascript reactjs universal


    【解决方案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

        【讨论】:

          猜你喜欢
          • 2011-01-11
          • 2012-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多