使用React-Window实现虚拟滚动效果的示例代码

 更新时间:2024年01月26日 13:58:22   作者:慕仲卿  
React-Window 是一个为 React 应用程序中高效渲染大数据集而设计的库,它基于窗口化或虚拟化的原则运行,本文将使用React-Window实现虚拟滚动效果,感兴趣的可以了解下

1. 了解 React-Window

React-Window 是一个为 React 应用程序中高效渲染大数据集而设计的库。它基于窗口化或虚拟化的原则运行,这对于提高数据量大的 Web 应用程序的性能至关重要。

2. React-Window 原理

  • 窗口化: React-Window 仅渲染用户可视区域中当前可见的元素。这最小化了 DOM 元素的数量,减少内存使用并提升性能。
  • DOM 元素的可重用性: 用户滚动时,React-Window 重用现有的 DOM 元素来展示新项,进一步提升性能。
  • 简化的 API: 相比于 React-Virtualized,它提供了更简单、更流畅的 API,使用起来更容易,同时功能强大。

3. 安装

通过 npm 安装 React-Window:

npm install react-window

4. 基本使用

一个基本的列表实现:

import { FixedSizeList as List } from 'react-window';

const MyList = () => (
    <List
        height={150}
        itemCount={1000}
        itemSize={35}
        width={300}
    >
        {({ index, style }) => <div style={style}>Item {index}</div>}
    </List>
);

5. 高级使用案例和示例

5.1 自定义项目渲染器

自定义列表或网格中每个项目的渲染方式。

import { FixedSizeList as List } from 'react-window';

// 偶数和奇数项组件
const EvenItem = ({ index }) => <div>Even: Item {index}</div>;
const OddItem = ({ index }) => <div>Odd: Item {index}</div>;

const MyCustomItem = ({ index, style }) => (
    <div style={style}>
        {index % 2 === 0 ? <EvenItem index={index} /> : <OddItem index={index} />}
    </div>
);

const MyList = () => (
    <List
        height={150}
        itemCount={1000}
        itemSize={35}
        width={300}
    >
        {MyCustomItem}
    </List>
);

5.2 动态加载

结合数据获取实现用户滚动时动态加载和渲染数据。

import { InfiniteLoader, List } from "react-window-infinite-loader";

const loadMoreItems = /* 加载更多项目的函数 */

<InfiniteLoader
    isItemLoaded={/* 检查项目是否加载的函数 */}
    itemCount={1000}
    loadMoreItems={loadMoreItems}
>
    {({ onItemsRendered, ref }) => (
        <List
            onItemsRendered={onItemsRendered}
            ref={ref}
            {/* 其他属性 */}
        >
            {/* 项目渲染器 */}
        </List>
    )}
</InfiniteLoader>

有关此示例的更多详细信息,请查看下一章节。

5.3 性能优化

演示减少渲染 DOM 元素的数量。

// 使用相同的 FixedSizeList 示例,但使用大量数据集
<List
    height={150}
    itemCount={100000}
    itemSize={35}
    width={300}
>
    {({ index, style }) => <div style={style}>Item {index}</div>}
</List>

6. 详细实现动态加载

为了展示如何在使用 Express 构建的后端中与 React-Window 结合实现动态加载,我们创建一个示例,前端从后端获取数据,用户通过列表滚动时请求更多数据。后端将提供分页数据,前端在达到当前加载项的末尾时请求更多数据。

使用 Express 的后端设置

创建一个简单的 Express 服务器:

首先,建立一个能够提供分页数据的 Express 服务器。

 express = require('express');
const app = express();
const cors = require('cors');
const PORT = 3000;

app.use(cors());
// 模拟数据数组
const data = new Array(1000).fill(null).map((_, index) => ({ id: index, name: `Item ${index}` }));

// 获取分页数据的端点
app.get('/data', (req, res) => {
    const { page = 1, limit = 50 } = req.query;
    console.log('req.query:', req.query)
    const startIndex = (page - 1) * limit;
    const endIndex = page * limit;
    res.json({
        data: data.slice(startIndex, endIndex),
        total: data.length
    });
});

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

在这个设置中,创建了一个模拟数据数组,/data 端点根据请求的页码和限制提供部分数据。

使用 React-Window 和无限加载的前端设置

在前端实现无限加载:

使用 React 和 React-Window 实现无限加载特性。

import React, { useState, useEffect } from 'react';
import { FixedSizeList as List } from 'react-window';
import axios from 'axios';

const ROW_HEIGHT = 35;

function InfiniteLoadingList() {
    const [items, setItems] = useState([]);
    const [total, setTotal] = useState(0);
    const [page, setPage] = useState(1);

    const loadMoreItems = async () => {
        const { data } = await axios.get(`http://localhost:3000/data?page=${page}&limit=50`);
        setItems(prev => [...prev, ...data.data]);
        setTotal(data.total);
        setPage(prev => prev + 1);
    };

    useEffect(() => {
        loadMoreItems();
    }, []);

    useEffect(() => {
        console.log('items', items);
    }, [items]);

    const isItemLoaded = index => index < items.length;

    const renderItem = ({ index, style }) => (
        <div style={style}>
            {isItemLoaded(index) ? items[index].name : 'Loading...'}
        </div>
    );

    return (
        <List
            height={400}
            itemCount={total}
            itemSize={ROW_HEIGHT}
            width={300}
            onItemsRendered={({ visibleStopIndex }) => {
            console.log('visibleStopIndex:', visibleStopIndex)
                if (!isItemLoaded(visibleStopIndex) && items.length < total) {
                    loadMoreItems();
                }
            }}
        >
            {renderItem}
        </List>
    );
}

export default InfiniteLoadingList;

在这个 React 组件中,使用 useStateuseEffect 管理列表的状态,并在用户滚动到已加载项目末尾附近时获取新数据。FixedSizeListonItemsRendered 函数检查是否需要加载新数据。

总结

这个设置展示了在 React 应用程序中使用 React-Window 实现基本的动态加载和使用 Express 后端提供分页数据的简单实现。它有效地展示了如何通过根据需要逐步加载数据来处理大型数据集,改善性能和用户体验。

7. 结论

React-Window 对于解决 React 应用程序中渲染大型数据集相关的性能问题起着关键作用。它对虚拟化的方法,结合简化的 API,使其成为开发者的首选。通过仅渲染可见内容并高效地重用 DOM 元素,React-Window 确保即使在数据量庞大的情况下,应用程序也能保持响应性和性能。

到此这篇关于使用React-Window实现虚拟滚动效果的示例代码的文章就介绍到这了,更多相关React虚拟滚动内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • react hooks中的useState使用要点

    react hooks中的useState使用要点

    这篇文章主要为大家介绍了react hooks中的useState使用要点详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • React为什么需要Scheduler调度器原理详解

    React为什么需要Scheduler调度器原理详解

    这篇文章主要为大家介绍了React为什么需要Scheduler调度器原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • React动画实现方案Framer Motion让页面自己动起来

    React动画实现方案Framer Motion让页面自己动起来

    这篇文章主要为大家介绍了React动画实现方案Framer Motion让页面自己动起来,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • Electron+React进行通信的方法

    Electron+React进行通信的方法

    electron其实是一个桌面应用程序,不是一个标准的前端web程序,所有没有什么请求的发生,控制台network看不到请求,而是只能通过console.log去打印查看,而且通信协议使用的不是http而是gRPC协议,这篇文章主要介绍了Electron+React如何进行通信,需要的朋友可以参考下
    2022-06-06
  • react批量引入svg图标的方法

    react批量引入svg图标的方法

    这篇文章主要介绍了react批量引入svg图标的方法,在批量引入之前,我们需要安装一个包并配置到typescript.json文件中,需要的朋友可以参考下
    2024-03-03
  • 聊聊React onClick 传递参数的问题

    聊聊React onClick 传递参数的问题

    很多朋友向小编反映一个问题关于React onClick 传递参数的问题,当点击删除按钮需要执行删除操作,针对这个问题该如何处理呢?下面小编给大家带来了React onClick 传递参数的问题,感兴趣的朋友一起看看吧
    2021-10-10
  • ReactNative Image组件使用详解

    ReactNative Image组件使用详解

    本篇文章主要介绍了ReactNative Image组件使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • react-native 配置@符号绝对路径配置和绝对路径没有提示的问题

    react-native 配置@符号绝对路径配置和绝对路径没有提示的问题

    本文主要介绍了react-native 配置@符号绝对路径配置和绝对路径没有提示的问题,文中通过图文示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01
  • React生命周期函数深入全面介绍

    React生命周期函数深入全面介绍

    生命周期函数指在某一时刻组件会自动调用并执行的函数。React每个类组件都包含生命周期方法,以便于在运行过程中特定的阶段执行这些方法
    2022-09-09
  • React性能debug场景解决记录

    React性能debug场景解决记录

    这篇文章主要为大家介绍了React性能debug场景解决记录,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05

最新评论