使用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虚拟滚动内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript的React框架中的JSX语法学习入门教程

    JavaScript的React框架中的JSX语法学习入门教程

    这篇文章主要介绍了JavaScript的React框架中的JSX语法学习入门教程,React是由Facebook开发并开源的高人气js框架,需要的朋友可以参考下
    2016-03-03
  • react实现阻止父容器滚动

    react实现阻止父容器滚动

    这篇文章主要介绍了react实现阻止父容器滚动方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • React为 Vue 引入容器组件和展示组件的教程详解

    React为 Vue 引入容器组件和展示组件的教程详解

    这篇文章主要介绍了React为 Vue 引入容器组件和展示组件的教程详解,文中很详细的给大家介绍了使用容器组件的原因,需要的朋友可以参考下
    2018-05-05
  • 再次谈论React.js实现原生js拖拽效果引起的一系列问题

    再次谈论React.js实现原生js拖拽效果引起的一系列问题

    React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.本文给大家介绍React.js实现原生js拖拽效果,需要的朋友一起学习吧
    2016-04-04
  • React Native验证码倒计时工具类分享

    React Native验证码倒计时工具类分享

    这篇文章主要为大家分享了React Native验证码倒计时工具类,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • 深入理解React与闭包的关系

    深入理解React与闭包的关系

    本文将深入探讨React与闭包之间的关系,我们将首先介绍React和闭包的基本概念,然后详细解释React组件中如何使用闭包来处理状态和作用域的问题,希望通过本文的阅读,你将对React中闭包的概念有更深入的理解,并能够在开发React应用时更好地应用闭包
    2023-07-07
  • react电商商品列表的实现流程详解

    react电商商品列表的实现流程详解

    这篇文章主要介绍了react实现电商商品列表的流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • vue3中获取ref元素的几种方式总结

    vue3中获取ref元素的几种方式总结

    这篇文章主要介绍了vue3中获取ref元素的几种方式总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • 浅谈箭头函数写法在ReactJs中的使用

    浅谈箭头函数写法在ReactJs中的使用

    这篇文章主要介绍了浅谈箭头函数写法在ReactJs中的使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • react+antd实现动态编辑表格数据

    react+antd实现动态编辑表格数据

    这篇文章主要为大家详细介绍了react+antd实现动态编辑表格数据,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08

最新评论