使用React-Window實現(xiàn)虛擬滾動效果的示例代碼
1. 了解 React-Window
React-Window 是一個為 React 應用程序中高效渲染大數(shù)據(jù)集而設計的庫。它基于窗口化或虛擬化的原則運行,這對于提高數(shù)據(jù)量大的 Web 應用程序的性能至關重要。
2. React-Window 原理
- 窗口化: React-Window 僅渲染用戶可視區(qū)域中當前可見的元素。這最小化了 DOM 元素的數(shù)量,減少內存使用并提升性能。
- DOM 元素的可重用性: 用戶滾動時,React-Window 重用現(xiàn)有的 DOM 元素來展示新項,進一步提升性能。
- 簡化的 API: 相比于 React-Virtualized,它提供了更簡單、更流暢的 API,使用起來更容易,同時功能強大。
3. 安裝
通過 npm 安裝 React-Window:
npm install react-window
4. 基本使用
一個基本的列表實現(xiàn):
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 自定義項目渲染器
自定義列表或網(wǎng)格中每個項目的渲染方式。
import { FixedSizeList as List } from 'react-window';
// 偶數(shù)和奇數(shù)項組件
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 動態(tài)加載
結合數(shù)據(jù)獲取實現(xiàn)用戶滾動時動態(tài)加載和渲染數(shù)據(jù)。
import { InfiniteLoader, List } from "react-window-infinite-loader";
const loadMoreItems = /* 加載更多項目的函數(shù) */
<InfiniteLoader
isItemLoaded={/* 檢查項目是否加載的函數(shù) */}
itemCount={1000}
loadMoreItems={loadMoreItems}
>
{({ onItemsRendered, ref }) => (
<List
onItemsRendered={onItemsRendered}
ref={ref}
{/* 其他屬性 */}
>
{/* 項目渲染器 */}
</List>
)}
</InfiniteLoader>
有關此示例的更多詳細信息,請查看下一章節(jié)。
5.3 性能優(yōu)化
演示減少渲染 DOM 元素的數(shù)量。
// 使用相同的 FixedSizeList 示例,但使用大量數(shù)據(jù)集
<List
height={150}
itemCount={100000}
itemSize={35}
width={300}
>
{({ index, style }) => <div style={style}>Item {index}</div>}
</List>
6. 詳細實現(xiàn)動態(tài)加載
為了展示如何在使用 Express 構建的后端中與 React-Window 結合實現(xiàn)動態(tài)加載,我們創(chuàng)建一個示例,前端從后端獲取數(shù)據(jù),用戶通過列表滾動時請求更多數(shù)據(jù)。后端將提供分頁數(shù)據(jù),前端在達到當前加載項的末尾時請求更多數(shù)據(jù)。
使用 Express 的后端設置
創(chuàng)建一個簡單的 Express 服務器:
首先,建立一個能夠提供分頁數(shù)據(jù)的 Express 服務器。
express = require('express');
const app = express();
const cors = require('cors');
const PORT = 3000;
app.use(cors());
// 模擬數(shù)據(jù)數(shù)組
const data = new Array(1000).fill(null).map((_, index) => ({ id: index, name: `Item ${index}` }));
// 獲取分頁數(shù)據(jù)的端點
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}`));
在這個設置中,創(chuàng)建了一個模擬數(shù)據(jù)數(shù)組,/data 端點根據(jù)請求的頁碼和限制提供部分數(shù)據(jù)。
使用 React-Window 和無限加載的前端設置
在前端實現(xiàn)無限加載:
使用 React 和 React-Window 實現(xiàn)無限加載特性。
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 組件中,使用 useState 和 useEffect 管理列表的狀態(tài),并在用戶滾動到已加載項目末尾附近時獲取新數(shù)據(jù)。FixedSizeList 的 onItemsRendered 函數(shù)檢查是否需要加載新數(shù)據(jù)。
總結
這個設置展示了在 React 應用程序中使用 React-Window 實現(xiàn)基本的動態(tài)加載和使用 Express 后端提供分頁數(shù)據(jù)的簡單實現(xiàn)。它有效地展示了如何通過根據(jù)需要逐步加載數(shù)據(jù)來處理大型數(shù)據(jù)集,改善性能和用戶體驗。
7. 結論
React-Window 對于解決 React 應用程序中渲染大型數(shù)據(jù)集相關的性能問題起著關鍵作用。它對虛擬化的方法,結合簡化的 API,使其成為開發(fā)者的首選。通過僅渲染可見內容并高效地重用 DOM 元素,React-Window 確保即使在數(shù)據(jù)量龐大的情況下,應用程序也能保持響應性和性能。
到此這篇關于使用React-Window實現(xiàn)虛擬滾動效果的示例代碼的文章就介紹到這了,更多相關React虛擬滾動內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript的React框架中的JSX語法學習入門教程
這篇文章主要介紹了JavaScript的React框架中的JSX語法學習入門教程,React是由Facebook開發(fā)并開源的高人氣js框架,需要的朋友可以參考下2016-03-03
再次談論React.js實現(xiàn)原生js拖拽效果引起的一系列問題
React 起源于 Facebook 的內部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網(wǎng)站.本文給大家介紹React.js實現(xiàn)原生js拖拽效果,需要的朋友一起學習吧2016-04-04
react+antd實現(xiàn)動態(tài)編輯表格數(shù)據(jù)
這篇文章主要為大家詳細介紹了react+antd實現(xiàn)動態(tài)編輯表格數(shù)據(jù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-08-08

