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

react解決 Hooks 閉包陷阱的問題

 更新時間:2026年05月29日 09:13:10   作者:光影少年  
本文主要介紹了react解決 Hooks 閉包陷阱的問題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

React Hooks 的“閉包陷阱(stale closure)”本質(zhì)是:函數(shù)拿到的是創(chuàng)建時那一刻的 state/props,而不是最新值。常見出現(xiàn)在 setTimeout、setInterval、事件監(jiān)聽、異步請求、useEffect 中。

例如:

import { useState } from 'react';
export default function Demo() {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setTimeout(() => {
      console.log(count); // 永遠打印點擊時的 count
    }, 3000);
  };
  return (
    <>
      <button onClick={() => setCount(count + 1)}>
        +1
      </button>
      <button onClick={handleClick}>
        延遲打印
      </button>
    </>
  );
}

假設(shè):

count = 0
點擊延遲打印
馬上點擊 +1 -> count=1
3秒后輸出:0

因為 setTimeout 閉包保存的是舊 count。

解決方案1:函數(shù)式更新(推薦處理 state 更新)

適合依賴舊值計算新值。

錯誤:

setCount(count + 1);
setCount(count + 1);
console.log(count); // +1

正確:

setCount(prev => prev + 1);
setCount(prev => prev + 1);
console.log(count); // +2

React 會拿最新狀態(tài):

setInterval(() => {
   setCount(prev => prev + 1);
},1000);

避免:

setCount(count + 1); // count 永遠舊 

解決方案2:useRef 保存最新值(最常見)

適合:

  • setTimeout
  • setInterval
  • websocket
  • 原生事件
  • 防抖節(jié)流

例子:

import { useRef, useState, useEffect } from 'react';
export default function Demo() {
  const [count, setCount] = useState(0);
  const countRef = useRef(count);
  useEffect(() => {
    countRef.current = count;
  }, [count]);
  const handleClick = () => {
    setTimeout(() => {
      console.log(countRef.current);
    }, 3000);
  };
  return (
      <>
          <button onClick={() => setCount(count+1)}>
             +1
          </button>
          <button onClick={handleClick}>
             打印
          </button>
      </>
  );
}

始終輸出最新值。

原理:

閉包 -> 拿不到最新 state
ref.current -> 永遠最新

很多庫(例如防抖 hooks)都這么做。

解決方案3:正確維護 useEffect 依賴

錯誤:

useEffect(() => {
   getData(id);
}, []);

即使 id 變化也不會重新執(zhí)行。

應(yīng)寫:

useEffect(() => {
   getData(id);
}, [id]);

遵守 eslint:

react-hooks/exhaustive-deps 

不要隨便關(guān):

// eslint-disable-next-line 

很多閉包問題來自錯誤依賴。

解決方案4:useCallback + 依賴更新

錯誤:

const getUser = useCallback(() => {
    console.log(id);
}, []);

id 永遠舊。

正確:

const getUser = useCallback(() => {
    console.log(id);
}, [id]);

解決方案5:抽離自定義 Hook(推薦業(yè)務(wù)場景)

比如輪詢:

錯誤:

useEffect(() => {
   const timer=setInterval(()=>{
      fetchData(page);
   },1000)
   return ()=>clearInterval(timer)
},[])

page 永遠舊。

改:

function useLatest(value){
   const ref=useRef(value);
   useEffect(()=>{
      ref.current=value;
   },[value])
   return ref;
}

使用:

const pageRef = useLatest(page);
useEffect(() => {
   const timer = setInterval(() => {
      fetchData(pageRef.current);
   },1000);
   return ()=>clearInterval(timer);
},[])

解決方案6:React 19 的useEffectEvent(未來推薦)

React 提供了解決閉包問題的新方案:

const onVisit = useEffectEvent(() => {
   console.log(count);
});
useEffect(()=>{
   window.addEventListener('click',onVisit)
   return ()=>{
      window.removeEventListener('click',onVisit)
   }
},[])

事件始終讀取最新 state。

適合:

  • 訂閱
  • 監(jiān)聽器
  • effect 內(nèi)回調(diào)

前端開發(fā)里可以記一個經(jīng)驗:

需要最新狀態(tài):
→ 用 ref
 
依賴舊狀態(tài)更新:
→ 用函數(shù)式 setState
 
effect/callback 使用變量:
→ 補全依賴數(shù)組
 
長生命周期回調(diào):
→ useLatest / useRef
 
React19:
→ useEffectEvent

像你做性能平臺、輪詢二維碼狀態(tài)、下載任務(wù)進度這些場景,setInterval + useRef 基本是閉包問題高發(fā)區(qū)。

到此這篇關(guān)于react解決 Hooks 閉包陷阱的問題的文章就介紹到這了,更多相關(guān)react Hooks 閉包陷阱內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • react-native 實現(xiàn)購物車滑動刪除效果的示例代碼

    react-native 實現(xiàn)購物車滑動刪除效果的示例代碼

    這篇文章主要介紹了react-native 實現(xiàn)購物車滑動刪除效果的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • React中的Hooks路由跳轉(zhuǎn)問題

    React中的Hooks路由跳轉(zhuǎn)問題

    這篇文章主要介紹了React中的Hooks路由跳轉(zhuǎn)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • React Component存在的幾種形式詳解

    React Component存在的幾種形式詳解

    這篇文章主要給大家介紹了關(guān)于React Component存在的幾種形式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • react反向代理使用http-proxy-middleware問題

    react反向代理使用http-proxy-middleware問題

    這篇文章主要介紹了react反向代理使用http-proxy-middleware問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 詳解如何使用Jest測試React組件

    詳解如何使用Jest測試React組件

    在本文中,我們將了解如何使用Jest(Facebook 維護的一個測試框架)來測試我們的React組件,我們將首先了解如何在純 JavaScript 函數(shù)上使用 Jest,然后再了解它提供的一些開箱即用的功能,這些功能專門用于使測試 React 應(yīng)用程序變得更容易,需要的朋友可以參考下
    2023-10-10
  • react hooks入門詳細教程

    react hooks入門詳細教程

    這篇文章主要介紹了react hooks入門詳細教程,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • redux的原理、工作流程及其應(yīng)用方式

    redux的原理、工作流程及其應(yīng)用方式

    這篇文章主要介紹了redux的原理、工作流程及其應(yīng)用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • react如何使用useRef模仿抖音標題里面添加標簽內(nèi)容

    react如何使用useRef模仿抖音標題里面添加標簽內(nèi)容

    本文介紹了如何模仿抖音發(fā)布頁面,使用div元素作為輸入框,并利用CSS樣式和JavaScript動態(tài)操作DOM,實現(xiàn)類似于input輸入框的功能,感興趣的朋友跟隨小編一起看看吧
    2024-10-10
  • React+Router多級導(dǎo)航切換路由方式

    React+Router多級導(dǎo)航切換路由方式

    這篇文章主要介紹了React+Router多級導(dǎo)航切換路由方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 工程級?React?注冊登錄全棧級流程分析

    工程級?React?注冊登錄全棧級流程分析

    這篇文章主要介紹了工程級?React?注冊登錄全棧級流程,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02

最新評論

沂南县| 石门县| 忻城县| 淅川县| 河东区| 湘潭县| 东丽区| 林芝县| 且末县| 永和县| 临泽县| 神木县| 黔西| 涿鹿县| 乌审旗| 巴楚县| 裕民县| 高阳县| 合江县| 确山县| 临安市| 玛沁县| 泰兴市| 兰州市| 镇康县| 武鸣县| 东明县| 穆棱市| 自贡市| 乐亭县| 彝良县| 乌兰浩特市| 陕西省| 昌都县| 从江县| 临武县| 眉山市| 伊宁市| 柏乡县| 肇源县| 成武县|