用几行代码实现无限滚动

2025-05-24

用几行代码实现无限滚动

介绍

什么是无限滚动?

无限滚动是一种网页设计技术,它会在用户向下滚动页面时持续加载内容,从而消除了分页的需要。
一些使用无限滚动的网站例如:Twitter9gag等……

我们要构建什么

替代文本

我不知道它看起来有什么好看的,但你可以改进和设计它,让它看起来更好,这只是一个基本的例子,并介绍一个概念

先决条件

  • 本教程假设您具备 React 的工作知识
  • 我们将使用React Hooks
  • 在开始之前,请确保您的环境中安装了 Node、Yarn 或 npm。
  • 当然有网络浏览器

入门

npx create-react-app infiniteScroll
Enter fullscreen mode Exit fullscreen mode

创建完项目文件夹后,您可以通过 cd 进入该文件夹并运行它:

cd infiniteScroll 
npm start
Enter fullscreen mode Exit fullscreen mode

这将以开发模式运行应用程序,您可以使用链接http://localhost:3000/在浏览器中查看它。

它看起来会像这样:

替代文本

组件设置

创建新的无限滚动组件并将以下代码粘贴到其中:

import React, { useState  } from 'react';
// styling post container
const divStyle = {
    color: 'blue',
    height: '250px',
    textAlign: 'center',
    padding: '5px 10px',
    background: '#eee',
    marginTop: '15px'
};

// styling container wrapper
const containerStyle = {
    maxWidth: '1280px',
    margin: '0 auto',
}

const InfiniteScroll = () => {
    // initialize list of posts
    const [postList, setPostList] = useState({
        list: [1,2,3,4]
    }); 


    return (<div className="container" style={containerStyle}>
        <div className="post-list">
            {
                postList.list.map((post, index) => {
                    return (<div key={index} 
                             className="post" 
                             style={divStyle}>
                        <h2> {post } </h2>
                    </div>)
                })
            }
            <div className="loading">
                    <h2>Load More</h2>
           </div>
        </div>
    </div>)
}

export default InfiniteScroll;
Enter fullscreen mode Exit fullscreen mode

您的页面现在看起来如下:

替代文本

添加无限滚动

为此,我们将使用Interaction Observer API。Intersection
Observer 是一个非常强大的 JavaScript API,它简化了 JavaScript 中基于滚动的事件。Intersection Observer 不会持续检查元素与顶部的距离,而是会监视元素何时进入或退出视口。

我们将使用交互观察器来观察用户何时进入特定点,然后加载更多帖子。

  • 首先,我们将从React导入 **useRef * 和useEffect hook,并将它们附加到 Load More div*
  • 然后在组件安装时在 Load More div 上注册 IntersectionObserver
  • 添加新的状态变量页面,用于跟踪当前页面。为了更真实地模拟示例,我们将如何在连接后端时执行此操作。
  • 页面更新的最后一步,只需加载更多帖子

以下是完整的代码:

import React, { useEffect, useState, useRef  } from 'react';

const divStyle = {
    color: 'blue',
    height: '250px',
    textAlign: 'center',
    padding: '5px 10px',
    background: '#eee',
    marginTop: '15px'
};


const containerStyle = {
    maxWidth: '1280px',
    margin: '0 auto',
}
const InfiniteScroll = () => {
    const [postList, setPostList] = useState({
        list: [1,2,3,4]
    }); 
    // tracking on which page we currently are
    const [page, setPage] = useState(1);
    // add loader refrence 
    const loader = useRef(null);

    useEffect(() => {
         var options = {
            root: null,
            rootMargin: "20px",
            threshold: 1.0
         };
        // initialize IntersectionObserver
        // and attaching to Load More div
         const observer = new IntersectionObserver(handleObserver, options);
         if (loader.current) {
            observer.observe(loader.current)
         }

    }, []);


    useEffect(() => {
        // here we simulate adding new posts to List
        const newList = postList.list.concat([1,1,1,1]);
        setPostList({
            list: newList
        })
    }, [page])

    // here we handle what happens when user scrolls to Load More div
   // in this case we just update page variable
    const handleObserver = (entities) => {
        const target = entities[0];
        if (target.isIntersecting) {   
            setPage((page) => page + 1)
        }
    }


    return (<div className="container" style={containerStyle}>
        <div className="post-list">
            {
                postList.list.map((post, index) => {
                    return (<div key={index} className="post" style={divStyle}>
                        <h2> {post } </h2>
                    </div>)
                })
            }
             <!-- Add Ref to Load More div -->
            <div className="loading" ref={loader}>
                    <h2>Load More</h2>
           </div>
        </div>
    </div>)
}

export default InfiniteScroll;
Enter fullscreen mode Exit fullscreen mode

这是我在 Dev.to 上的第一篇文章,感谢您的阅读 :)

如果您喜欢这篇文章,您可以通过以下方式找到更多内容:

在 Twitter 上关注我:

文章来源:https://dev.to/hunterjsbit/react-infinite-scroll-in-few-lines-588f
PREV
非常适合初学者的 API,助您开始实践前端开发🧑‍💻
NEXT
使用 Javascript 的简单英语综合大 O 符号指南