最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文弄懂React的useEffect經(jīng)常執(zhí)行兩次

 更新時(shí)間:2026年07月21日 09:22:32   作者:阿橙的百寶箱  
在使用React開發(fā)應(yīng)用時(shí),許多開發(fā)者都會(huì)遇到一個(gè)看似奇怪的現(xiàn)象:鉤子在某些情況下會(huì)執(zhí)行兩次,本文就來詳細(xì)的介紹這個(gè)問題,感興趣的可以了解一下

引言

在使用React開發(fā)應(yīng)用時(shí),許多開發(fā)者都會(huì)遇到一個(gè)看似奇怪的現(xiàn)象:useEffect鉤子在某些情況下會(huì)執(zhí)行兩次。這種現(xiàn)象在開發(fā)模式下尤其常見,而在生產(chǎn)模式下則通常不會(huì)出現(xiàn)。對(duì)于初次接觸React或?qū)eact內(nèi)部機(jī)制理解不深的開發(fā)者來說,這可能會(huì)引發(fā)困惑甚至導(dǎo)致錯(cuò)誤的調(diào)試方向。本文將深入探討這一現(xiàn)象的根本原因,分析React的設(shè)計(jì)理念,并解釋為什么這種行為實(shí)際上是React團(tuán)隊(duì)有意為之的優(yōu)化策略。

主體

1. useEffect的基本行為

首先,我們需要明確useEffect的基本工作原理。useEffect是React Hooks中用于處理副作用的核心API,它的執(zhí)行時(shí)機(jī)是在組件渲染完成之后。根據(jù)依賴項(xiàng)的不同,useEffect的執(zhí)行可以分為以下幾種情況:

  • 無依賴數(shù)組:每次渲染后都會(huì)執(zhí)行
  • 空依賴數(shù)組:僅組件掛載時(shí)執(zhí)行一次
  • 有依賴項(xiàng):依賴項(xiàng)變化時(shí)執(zhí)行

然而,即便是在空依賴數(shù)組的情況下,開發(fā)者有時(shí)也會(huì)觀察到useEffect被執(zhí)行兩次,這與預(yù)期不符。這種現(xiàn)象主要發(fā)生在React 18及更高版本的開發(fā)模式下。

2. React 18的嚴(yán)格模式(Strict Mode)

React 18引入了一個(gè)重要的變化:在開發(fā)模式下默認(rèn)啟用了嚴(yán)格模式(Strict Mode)。嚴(yán)格模式會(huì)故意讓你的組件掛載兩次,以此來幫助發(fā)現(xiàn)潛在的問題。這種行為的目的是:

  • 檢測(cè)不純的渲染(如直接修改props或state)
  • 驗(yàn)證effect的清理函數(shù)是否正確實(shí)現(xiàn)
  • 發(fā)現(xiàn)意外的副作用

當(dāng)組件掛載兩次時(shí),相關(guān)的useEffect也會(huì)隨之執(zhí)行兩次。這是React團(tuán)隊(duì)故意設(shè)計(jì)的,目的是幫助開發(fā)者在早期發(fā)現(xiàn)并修復(fù)問題,而不是等到生產(chǎn)環(huán)境中才暴露出來。

3. 雙重渲染的深層機(jī)制

React 18的雙重渲染機(jī)制實(shí)際上是一種"mount → unmount → remount"的過程。具體來說:

  1. 首次渲染和掛載組件
  2. 執(zhí)行所有effect(第一次執(zhí)行)
  3. React立即卸載組件
  4. 執(zhí)行所有effect的cleanup函數(shù)
  5. 重新掛載組件(第二次執(zhí)行effect)

這種機(jī)制確保了你的組件能夠正確處理"掛載→卸載→重新掛載"的生命周期,這在現(xiàn)實(shí)應(yīng)用中是很常見的場(chǎng)景(如用戶在頁(yè)面間快速導(dǎo)航)。

4. 為什么只在開發(fā)模式下?

這種雙重渲染行為僅限于開發(fā)模式,原因如下:

  • 性能考量:雙重渲染會(huì)增加額外的計(jì)算開銷
  • 調(diào)試目的:生產(chǎn)環(huán)境不需要這種嚴(yán)格的檢查
  • 用戶體驗(yàn):不應(yīng)該影響最終用戶的體驗(yàn)

React團(tuán)隊(duì)通過這種方式在開發(fā)階段模擬了更嚴(yán)格的環(huán)境,幫助開發(fā)者提前發(fā)現(xiàn)潛在問題。

5. 實(shí)際案例分析

讓我們通過幾個(gè)具體例子來說明這種現(xiàn)象:

案例1:空依賴數(shù)組

useEffect(() => {
  console.log("Effect ran");
  return () => console.log("Cleanup ran");
}, []);

在開發(fā)模式下,你會(huì)看到以下輸出:

Effect ran
Cleanup ran
Effect ran

案例2:API調(diào)用

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

這種代碼在開發(fā)模式下會(huì)觸發(fā)兩次API調(diào)用,可能導(dǎo)致意外的副作用。正確的做法應(yīng)該是添加取消邏輯:

useEffect(() => {
  const controller = new AbortController();
  
  fetchData({ signal: controller.signal });
  
  return () => controller.abort();
}, []);

6. 如何正確處理雙重執(zhí)行

為了避免雙重執(zhí)行帶來的問題,開發(fā)者應(yīng)該:

  1. 確保effect有正確的清理函數(shù)
  2. 對(duì)于冪等操作(如日志記錄)可以忽略重復(fù)執(zhí)行
  3. 對(duì)于非冪等操作(如POST請(qǐng)求)應(yīng)該添加防護(hù)
  4. 使用refs來跟蹤effect是否已經(jīng)執(zhí)行過

7. 設(shè)計(jì)哲學(xué)探討

React團(tuán)隊(duì)選擇這種設(shè)計(jì)有幾個(gè)深層次的考慮:

  • 可恢復(fù)性:確保組件能在任何時(shí)刻被正確地重新掛載
  • 一致性:開發(fā)環(huán)境盡可能模擬生產(chǎn)環(huán)境的邊緣情況
  • 可預(yù)測(cè)性:通過嚴(yán)格模式暴露潛在問題,而不是隱藏它們

這種設(shè)計(jì)鼓勵(lì)開發(fā)者編寫更健壯的代碼,能夠處理各種邊界情況。

8. 性能優(yōu)化技巧

雖然雙重渲染在開發(fā)模式下是有意的行為,但我們?nèi)钥梢酝ㄟ^一些技巧來優(yōu)化性能:

  • 使用useMemouseCallback減少不必要的重新計(jì)算
  • 將大型effect拆分為多個(gè)小型effect
  • 合理設(shè)置依賴數(shù)組,避免過度觸發(fā)
  • 考慮使用useLayoutEffect處理必須同步執(zhí)行的副作用

9. 常見誤解澄清

關(guān)于useEffect的雙重執(zhí)行,有幾個(gè)常見的誤解需要澄清:

  1. 這不是bug:這是React團(tuán)隊(duì)有意為之的設(shè)計(jì)
  2. 不影響生產(chǎn)環(huán)境:生產(chǎn)構(gòu)建會(huì)自動(dòng)禁用這種行為
  3. 不是所有effect都會(huì)執(zhí)行兩次:只有某些特定情況下才會(huì)出現(xiàn)
  4. 不是React 18特有的:早期版本在某些配置下也有類似行為

10. 與其他框架的對(duì)比

對(duì)比其他主流框架的處理方式:

  • Vue:在開發(fā)模式下也有類似的警告機(jī)制,但不會(huì)強(qiáng)制雙重執(zhí)行
  • Angular:依賴變更檢測(cè)策略,開發(fā)模式下的行為差異較小
  • Svelte:編譯時(shí)優(yōu)化,較少出現(xiàn)運(yùn)行時(shí)意外行為

React的選擇體現(xiàn)了其"顯式優(yōu)于隱式"的設(shè)計(jì)哲學(xué)。

總結(jié)

useEffect在開發(fā)模式下的雙重執(zhí)行行為是React團(tuán)隊(duì)精心設(shè)計(jì)的功能,旨在幫助開發(fā)者提前發(fā)現(xiàn)并解決潛在的問題。理解這一行為背后的設(shè)計(jì)理念和實(shí)現(xiàn)機(jī)制,有助于我們編寫更健壯、更可靠的React組件。作為開發(fā)者,我們應(yīng)該:

  1. 接受并理解這種設(shè)計(jì)選擇
  2. 確保effect邏輯具備冪等性或正確的清理機(jī)制
  3. 利用嚴(yán)格模式提高代碼質(zhì)量
  4. 區(qū)分開發(fā)和生產(chǎn)環(huán)境的行為差異

通過這種方式,我們可以充分利用React提供的開發(fā)工具,構(gòu)建出更高質(zhì)量的應(yīng)用程序。記住,React的這些"看似奇怪"的行為背后,往往有著深思熟慮的設(shè)計(jì)考量。

到此這篇關(guān)于一文弄懂React的useEffect經(jīng)常執(zhí)行兩次的文章就介紹到這了,更多相關(guān)React useEffect執(zhí)行兩次內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React轉(zhuǎn)Vue3的避坑指南

    React轉(zhuǎn)Vue3的避坑指南

    從 React 轉(zhuǎn) Vue3,相信很多前端工程師都有過這個(gè)經(jīng)歷,本文專門針對(duì) React 開發(fā)者視角,對(duì)照講解 Vue3 的核心概念,幫助你快速建立 Vue3 思維模型,少走彎路,需要的朋友可以參考下
    2026-04-04
  • 基于Cloud?Studio構(gòu)建React完成點(diǎn)餐H5頁(yè)面(騰訊云?Cloud?Studio?實(shí)戰(zhàn)訓(xùn)練營(yíng))

    基于Cloud?Studio構(gòu)建React完成點(diǎn)餐H5頁(yè)面(騰訊云?Cloud?Studio?實(shí)戰(zhàn)訓(xùn)練營(yíng))

    最近也是有機(jī)會(huì)參與到了騰訊云舉辦的騰訊云Cloud Studio實(shí)戰(zhàn)訓(xùn)練營(yíng),借此了解了騰訊云Cloud?Studio產(chǎn)品,下面就來使用騰訊云Cloud?Studio做一個(gè)實(shí)戰(zhàn)案例來深入了解該產(chǎn)品的優(yōu)越性吧,感興趣的朋友跟隨小編一起看看吧
    2023-08-08
  • React虛擬列表的實(shí)現(xiàn)

    React虛擬列表的實(shí)現(xiàn)

    在開發(fā)過程中,總是遇到很多列表的顯示。當(dāng)上數(shù)量級(jí)別的列表渲染于瀏覽器,終會(huì)導(dǎo)致瀏覽器的性能下降,你可以選擇其他方式避免,本文就介紹了虛擬列表來解決這個(gè)問題
    2021-05-05
  • 詳解react-native WebView 返回處理(非回調(diào)方法可解決)

    詳解react-native WebView 返回處理(非回調(diào)方法可解決)

    這篇文章主要介紹了詳解react-native WebView 返回處理(非回調(diào)方法可解決),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-02-02
  • 速通React之Hooks的實(shí)現(xiàn)

    速通React之Hooks的實(shí)現(xiàn)

    本文系統(tǒng)梳理 React 中 8 個(gè)最常用的核心 Hooks:useState、useReducer、useContext、useEffect、useRef、useImperativeHandle、useMemo、useCallback,下面就一起來了解一下
    2026-06-06
  • 使用react-color實(shí)現(xiàn)前端取色器的方法

    使用react-color實(shí)現(xiàn)前端取色器的方法

    本文通過代碼給大家介紹了使用react-color實(shí)現(xiàn)前端取色器的方法,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-11-11
  • React虛擬渲染實(shí)現(xiàn)50個(gè)或者一百個(gè)圖表渲染

    React虛擬渲染實(shí)現(xiàn)50個(gè)或者一百個(gè)圖表渲染

    這篇文章主要為大家介紹了React虛擬渲染實(shí)現(xiàn)50個(gè)或者100個(gè)圖表渲染的實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • React實(shí)現(xiàn)菜單欄滾動(dòng)功能

    React實(shí)現(xiàn)菜單欄滾動(dòng)功能

    本文將會(huì)基于react實(shí)現(xiàn)滾動(dòng)菜單欄功能,點(diǎn)擊菜單,內(nèi)容區(qū)域會(huì)自動(dòng)滾動(dòng)到對(duì)應(yīng)卡片,內(nèi)容區(qū)域滑動(dòng),指定菜單欄會(huì)被選中,代碼簡(jiǎn)單易懂,感興趣的朋友一起看看吧
    2024-03-03
  • React通過hook實(shí)現(xiàn)封裝表格常用功能

    React通過hook實(shí)現(xiàn)封裝表格常用功能

    這篇文章主要為大家詳細(xì)介紹了React通過hook封裝表格常用功能的使用,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下
    2023-12-12
  • React?Hooks之useDeferredValue鉤子用法示例詳解

    React?Hooks之useDeferredValue鉤子用法示例詳解

    useDeferredValue鉤子的主要目的是在React的并發(fā)模式中提供更流暢的用戶體驗(yàn),特別是在有高優(yōu)先級(jí)和低優(yōu)先級(jí)更新的情況下,本文主要講解一些常見的使用場(chǎng)景及其示例
    2023-09-09

最新評(píng)論

明溪县| 锡林郭勒盟| 金华市| 长海县| 宜良县| 乐业县| 霍山县| 宽城| 宜宾县| 凤山县| 黎川县| 富锦市| 平遥县| 鹿邑县| 柳林县| 安泽县| 如东县| 容城县| 吉安县| 丹阳市| 宝山区| 黄浦区| 清水河县| 普格县| 永济市| 财经| 杭锦后旗| 绥滨县| 莱阳市| 高清| 尤溪县| 突泉县| 梁山县| 涞源县| 浦东新区| 古浪县| 潍坊市| 德保县| 怀安县| 铜鼓县| 黄龙县|