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