亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

前端 React實(shí)現(xiàn)數(shù)據(jù)懶加載和滾動(dòng)觸底加載數(shù)據(jù)的過程

 更新時(shí)間:2025年08月23日 09:59:37   作者:新時(shí)代農(nóng)民工Top  
本文給大家介紹前端React實(shí)現(xiàn)數(shù)據(jù)懶加載和滾動(dòng)觸底加載數(shù)據(jù)的過程,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

什么是React的懶加載(Lazy Loading),如何實(shí)現(xiàn)?

在現(xiàn)代前端開發(fā)中,性能是一個(gè)至關(guān)重要的指標(biāo)。隨著應(yīng)用程序日益增長(zhǎng)和復(fù)雜,如何有效地管理資源和優(yōu)化加載時(shí)間成為了每位開發(fā)者必須面對(duì)的挑戰(zhàn)。為此,React 提供了懶加載(Lazy Loading)這一強(qiáng)大功能,幫助開發(fā)者按需加載組件,提高應(yīng)用架構(gòu)的靈活性和性能。

懶加載的概念
懶加載是一種設(shè)計(jì)模式,只有在需要的時(shí)候才加載某個(gè)資源或組件,而不是在應(yīng)用啟動(dòng)時(shí)一次性加載所有資源。在 React 中,懶加載通常用于組件的按需加載。通過懶加載,用戶可以避免在早期階段加載不必要的組件,實(shí)現(xiàn)流暢的用戶體驗(yàn),同時(shí)減少初始下載的大小。

為什么要使用懶加載

  • 提升性能:通過只加載用戶需要的部分,減少了初始加載時(shí)間和數(shù)據(jù)傳輸?shù)拇笮?,從而提升?yīng)用的性能。
  • 優(yōu)化用戶體驗(yàn):提高頁面響應(yīng)速度,使用戶能更快地查看和使用應(yīng)用的核心功能。
  • 代碼分割:懶加載有助于實(shí)現(xiàn)代碼分割,將大文件拆分成多個(gè)小塊,用戶只有在交互需要時(shí)才會(huì)請(qǐng)求相應(yīng)的代碼。

在 React 中使用 Intersection Observer API 實(shí)現(xiàn)觸底加載分頁(無限滾動(dòng))

1.基本實(shí)現(xiàn)思路

  • 在列表底部放置一個(gè) 哨兵元素(Sentinel)(如 <div>)。
  • 使用 IntersectionObserver 監(jiān)聽該元素是否進(jìn)入視口(即觸底)。
  • 觸底時(shí)加載下一頁數(shù)據(jù),并更新列表。

2.完整代碼實(shí)例

import { useState, useEffect, useRef } from 'react';
function InfiniteScrollList() {
  const [data, setData] = useState([]); // 當(dāng)前數(shù)據(jù)
  const [page, setPage] = useState(1);  // 當(dāng)前頁碼
  const [loading, setLoading] = useState(false); // 加載狀態(tài)
  const [hasMore, setHasMore] = useState(true);  // 是否還有更多數(shù)據(jù)
  const sentinelRef = useRef(null); // 哨兵元素的 ref
  // 模擬異步加載數(shù)據(jù)
  const fetchData = async () => {
    if (loading || !hasMore) return;
    setLoading(true);
    // 模擬 API 請(qǐng)求(替換為實(shí)際接口)
    const mockData = Array.from({ length: 10 }, (_, i) => 
      `Item ${(page - 1) * 10 + i + 1}`
    );
    // 模擬延遲
    await new Promise(resolve => setTimeout(resolve, 1000));
    setData(prev => [...prev, ...mockData]);
    setPage(prev => prev + 1);
    setLoading(false);
    // 假設(shè)第 5 頁后無數(shù)據(jù)
    if (page >= 5) setHasMore(false);
  };
  // 初始化 IntersectionObserver
  useEffect(() => {
    if (!sentinelRef.current || !hasMore) return;
    const observer = new IntersectionObserver(
      (entries) => {
        const [entry] = entries;
        if (entry.isIntersecting) {
          fetchData(); // 觸底時(shí)加載數(shù)據(jù)
        }
      },
      { threshold: 1.0 } // 當(dāng)哨兵元素完全進(jìn)入視口時(shí)觸發(fā)
    );
    observer.observe(sentinelRef.current);
    return () => {
      if (sentinelRef.current) observer.unobserve(sentinelRef.current);
    };
  }, [page, hasMore, loading]); // 依賴項(xiàng)
  return (
    <div style={{ maxHeight: '400px', overflow: 'auto' }}>
      <h2>無限滾動(dòng)列表</h2>
      <ul>
        {data.map((item, index) => (
          <li key={index} style={{ padding: '10px', borderBottom: '1px solid #eee' }}>
            {item}
          </li>
        ))}
      </ul>
      {/* 哨兵元素:用于檢測(cè)觸底 */}
      <div ref={sentinelRef} style={{ height: '20px' }}>
        {loading && <p>加載中...</p>}
        {!hasMore && <p>沒有更多數(shù)據(jù)了</p>}
      </div>
    </div>
  );
}
export default InfiniteScrollList;

3.關(guān)鍵點(diǎn)說明

  • 哨兵元素(Sentinel)
    • 一個(gè)隱藏的 <div> 作為觸底標(biāo)記,通過 ref 綁定到 IntersectionObserver。
  • IntersectionObserver 配置
    • threshold: 1.0:當(dāng)哨兵元素 100% 進(jìn)入視口時(shí)觸發(fā)回調(diào)。
    • useEffect 中初始化并清理觀察器,避免內(nèi)存泄漏。
  • 加載控制邏輯
    • loading 防止重復(fù)請(qǐng)求。
    • hasMore 標(biāo)記數(shù)據(jù)是否全部加載完畢。
  • 性能優(yōu)化
    • 使用 useCallback 包裹 fetchData(如果函數(shù)邏輯復(fù)雜)。
    • 實(shí)際項(xiàng)目中,結(jié)合分頁接口的 total 字段判斷是否還有數(shù)據(jù)。

4.實(shí)際項(xiàng)目適配

  • 替換 fetchData 中的模擬請(qǐng)求為真實(shí) API 調(diào)用(如 axios 或 fetch)。
  • 可加入防抖(Debounce)優(yōu)化頻繁觸發(fā)問題(如快速滾動(dòng)時(shí))。

簡(jiǎn)易封裝觸底自動(dòng)加載數(shù)據(jù)組件 InfiniteScroll.jsx

import { useEffect, useRef } from 'react'
const InfiniteScroll = (props) => {
  // children 可以設(shè)置觸底時(shí)顯示的提示文字,加載狀態(tài)等
  // loadMore 加載數(shù)據(jù)的接口方法
  // hasMore 檢查數(shù)據(jù)是否全部加載完畢,分頁加載之后還有下一頁數(shù)據(jù)保持 true 不變,確保后續(xù)不會(huì)再有數(shù)據(jù)則為 false
  // rootElement 瀏覽器可視窗口或者自定義滾動(dòng)視口
  const { children, loadMore, hasMore, rootElement = null } = props
  const sentinelRef = useRef(null)
  useEffect(() => {
    if (!sentinelRef.current || !hasMore) return;
    const observer = new window.IntersectionObserver(
      ([{isIntersecting}]) => {
        if (isIntersecting) {
          // 加載數(shù)據(jù)接口調(diào)用,當(dāng)該組件進(jìn)入瀏覽器視口時(shí)就會(huì)觸發(fā)
          loadMore()
        }
      },
      { threshold: 1.0, root: rootElement }
    );
    observer.observe(sentinelRef.current);
    return () => {
      if (sentinelRef.current) observer.unobserve(sentinelRef.current);
    };
  }, [hasMore])
  return (
  	// 哨兵容器,目標(biāo)元素,用來監(jiān)聽是否加載數(shù)據(jù),目標(biāo)元素與視口交叉 isIntersecting 值就會(huì)變化
    <div ref={sentinelRef} style={{ minHeight: '2px', textAlign: 'center' }}>
      {children}
    </div>
  )
}
export default InfiniteScroll

使用示例

const CustomComponent = () => {
  // 加載數(shù)據(jù)函數(shù)
  const loadMore = () => {
    // ...
  }
  return (
    <>
      // ...
      // 循環(huán)數(shù)據(jù),將組件放置在循環(huán)數(shù)據(jù)的底部即可
      <InfiniteScroll loadMore={loadMore} hasMore={hasMore}>
        {hasMore && <Spin indicator={<LoadingOutlined spin />} size="large" />}
      </InfiniteScroll>
      // ...
    </>
  )
}

到此這篇關(guān)于前端 React實(shí)現(xiàn)數(shù)據(jù)懶加載和滾動(dòng)觸底加載數(shù)據(jù)的過程的文章就介紹到這了,更多相關(guān)React懶加載和滾動(dòng)觸底加載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 基于react項(xiàng)目打包c(diǎn)ss引用路徑錯(cuò)誤解決方案

    基于react項(xiàng)目打包c(diǎn)ss引用路徑錯(cuò)誤解決方案

    這篇文章主要介紹了基于react項(xiàng)目打包c(diǎn)ss引用路徑錯(cuò)誤解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • React?Hooks項(xiàng)目實(shí)戰(zhàn)

    React?Hooks項(xiàng)目實(shí)戰(zhàn)

    React?Hooks是React?16.8版本引入的新特性,它使得在函數(shù)組件中也能夠使用狀態(tài)(state)和其他React特性,本文就來詳細(xì)介紹一下React?Hooks項(xiàng)目實(shí)戰(zhàn),感興趣的可以了解一下
    2023-11-11
  • react-router-dom6(對(duì)比?router5)快速入門指南

    react-router-dom6(對(duì)比?router5)快速入門指南

    這篇文章主要介紹了快速上手react-router-dom6(對(duì)比?router5),通過本文學(xué)習(xí)最新的react-router-dom?v6版本的路由知識(shí),并且會(huì)與v5老版本進(jìn)行一些對(duì)比,需要的朋友可以參考下
    2022-08-08
  • react-rnd靠右顯示的實(shí)現(xiàn)方式

    react-rnd靠右顯示的實(shí)現(xiàn)方式

    這篇文章主要介紹了react-rnd靠右顯示的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • React 狀態(tài)的不變性實(shí)例詳解

    React 狀態(tài)的不變性實(shí)例詳解

    這篇文章主要為大家介紹了React 狀態(tài)的不變性實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • react調(diào)試和測(cè)試代碼的小技巧

    react調(diào)試和測(cè)試代碼的小技巧

    在開發(fā)React應(yīng)用時(shí),嚴(yán)格模式StrictMode可以幫助開發(fā)者捕捉到組件中的錯(cuò)誤和潛在問題,安裝React Developer Tools瀏覽器擴(kuò)展檢查組件的props和狀態(tài),直接修改以及分析性能,@testing-library/react和Cypress或Playwright等工具可以有效地測(cè)試React組件和執(zhí)行端到端測(cè)試
    2024-10-10
  • 深入理解React調(diào)度(Scheduler)原理

    深入理解React調(diào)度(Scheduler)原理

    本文主要介紹了深入理解React調(diào)度(Scheduler)原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 淺談react性能優(yōu)化的方法

    淺談react性能優(yōu)化的方法

    這篇文章主要介紹了淺談react性能優(yōu)化的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • 如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器

    如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器

    這篇文章主要介紹了如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器,在vue及react中經(jīng)常會(huì)遇到,今天通過實(shí)例代碼給大家講解,需要的朋友可以參考下
    2018-11-11
  • 快速創(chuàng)建React項(xiàng)目并配置webpack

    快速創(chuàng)建React項(xiàng)目并配置webpack

    這篇文章主要介紹了創(chuàng)建React項(xiàng)目并配置webpack,在這里需要注意,Create?React?App?requires?Node?14?or?higher.需要安裝高版本的node,本文給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2022-01-01

最新評(píng)論