精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

從根上理解 React Hooks 的閉包陷阱(續集)

開發 前端
useRef 能解決閉包陷阱的原因是 useEffect 等 hook 里不直接引用 state,而是引用 ref.current,這樣后面只要修改了 ref 中的值,這里取出來的就是最新的。

??上篇文章??我們知道了什么是 hooks 的閉包陷阱,它的產生原因和解決方式,并通過一個案例做了演示。

其實那個案例的閉包陷阱的解決方式不夠完善,這篇文章我們再完善一下。

首先我們先來回顧下什么是閉包陷阱:

hooks 的閉包陷阱是指 useEffect 等 hook 中用到了某個 state,但是沒有把它加到 deps 數組里,導致 state 變了,但是執行的函數依然引用著之前的 state。

它的解決方式就是正確設置 deps 數組,把用到的 state 放到 deps 數組里,這樣每次 state 變了就能執行最新的函數,引用新的 state。同時要清理上次的定時器、事件監聽器等。

我們舉了這樣一個例子:

import { useEffect, useState } from 'react';
function Dong() {
const [count,setCount] = useState(0);
useEffect(() => {
setInterval(() => {
setCount(count + 1);
}, 500);
}, []);
useEffect(() => {
setInterval(() => {
console.log(count);
}, 500);
}, []);
return <div>guang</div>;
}
export default Dong;

每次打印都是 0 :

解決方式就是把 count 設置到 deps 里,并添加清理函數:

import { useEffect, useState } from 'react';
function Dong() {
const [count,setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1);
}, 500);
return () => clearInterval(timer);
}, [count]);
useEffect(() => {
const timer = setInterval(() => {
console.log(count);
}, 500);
return () => clearInterval(timer);
}, [count]);

return <div>guang</div>;
}
export default Dong;

這樣就能解決閉包陷阱:

但是這種解決閉包陷阱的方式用在定時器上不是很合適。

為什么呢?

因為現在每次 count 變了就會重置定時器,那之前的計時就重新計算,這樣就會導致計時不準。

所以,這種把依賴的 state 添加到 deps 里的方式是能解決閉包陷阱,但是定時器不能這樣做。

那還有什么方式能解決閉包陷阱呢?

useRef。

閉包陷阱產生的原因就是 useEffect 的函數里引用了某個 state,形成了閉包,那不直接引用不就行了?

useRef 是在 memorizedState 鏈表中放一個對象,current 保存某個值。

它的源碼是這樣的:

初始化的時候創建了一個對象放在 memorizedState 上,后面始終返回這個對象。

這樣通過 useRef 保存回調函數,然后在 useEffect 里從 ref.current 來取函數再調用,避免了直接調用,也就沒有閉包陷阱的問題了。

也就是這樣:

const fn = () => {
console.log(count);
};
const ref = useRef(fn);
useLayoutEffect(() => {
ref.current = fn;
});
useEffect(() => {
setInterval(() => ref.current(), 500);
}, []);

useEffect 里執行定時器,deps 設置為了 [],所以只會執行一次,回調函數用的是 ref.current,沒有直接依賴某個 state,所以不會有閉包陷阱。

用 useRef 創建個 ref 對象,初始值為打印 count 的回調函數,每次 render 都修改下其中的函數為新創建的函數,這個函數里引用的 count 就是最新的。

這里用了 useLayoutEffect 而不是 useEffect 是因為 useLayoutEffect 是在 render 前同步執行的,useEffect 是在 render 后異步執行的,所以用 useLayoutEffect 能保證在 useEffect 之前被調用。

這種方式避免了 useEffect 里直接對 state 的引用,從而避免了閉包問題。

另外,修改 count 的地方,可以用 setCount(count => count + 1) 代替 setCount(count + 1),這樣也就避免了閉包問題:

useEffect(() => {
setInterval(() => {
setCount(count => count + 1);
}, 500);
}, []);

現在組件的代碼是這樣的:

import { useEffect, useLayoutEffect, useState, useRef } from 'react';
function Dong() {
const [count, setCount] = useState(0);
useEffect(() => {
setInterval(() => {
setCount(count => count + 1);
}, 500);
}, []);
const fn = () => {
console.log(count);
};
const ref = useRef(fn);
useLayoutEffect(() => {
ref.current = fn;
});
useEffect(() => {
setInterval(() => ref.current(), 500);
}, []);
return <div>guang</div>;
}
export default Dong;

測試下:

確實,打印也是正常的,這就是解決閉包陷阱的第二種方式,通過 useRef 避免直接對 state 的引用,從而避免閉包問題。

這段邏輯用到了多個 hook,可以封裝成個自定義 hook:

function useInterval(fn, time) {
const ref = useRef(fn);
useLayoutEffect(() => {
ref.current = fn;
});
useEffect(() => {
setInterval(() => ref.current(), time);
}, []);
}

然后組件代碼就可以簡化了:

function Dong() {
const [count, setCount] = useState(0);
useInterval(() => {
setCount(count + 1);
}, 500);
useInterval(() => {
console.log(count);
}, 500);
return <div>guang</div>;
}

這樣我們就用 useRef 的方式解決了閉包陷阱問題。

總結

上篇文章我們通過把依賴的 state 添加到 deps 數組中的方式,使得每次 state 變了就執行新的函數,引用新的 state,從而解決了閉包陷阱問題。

這種方式用在定時器上是不合適的,因為定時器一旦被重置和重新計時,那計時就不準確了。

所以我們才用了避免閉包陷阱的第二種方式:使用 useRef。

useRef 能解決閉包陷阱的原因是 useEffect 等 hook 里不直接引用 state,而是引用 ref.current,這樣后面只要修改了 ref 中的值,這里取出來的就是最新的。

然后我們把這段邏輯封裝成了個自定義 hook,這樣可以方便復用。

解決 hooks 的閉包陷阱有兩種方式:

  • 設置依賴的 state 到 deps 數組中并添加清理函數。
  • 不直接引用 state,把 state 放到 useRef 創建的 ref 對象中再引用。

處理定時器的時候,為保證計時的準確,最好使用 useRef 的方式,其余情況兩種都可以。

責任編輯:姜華 來源: 神光的編程秘籍
相關推薦

2022-05-04 10:38:58

React閉包組件

2024-01-08 08:35:28

閉包陷阱ReactHooks

2021-02-24 07:40:38

React Hooks閉包

2021-05-11 08:48:23

React Hooks前端

2022-08-21 09:41:42

ReactVue3前端

2016-10-27 19:26:47

Javascript閉包

2016-09-18 20:53:16

JavaScript閉包前端

2022-10-24 08:08:27

閉包編譯器

2011-03-02 12:33:00

JavaScript

2025-10-24 10:19:35

2019-08-20 15:16:26

Reacthooks前端

2022-06-08 08:01:20

useEffect數組函數

2017-05-22 16:08:30

前端開發javascript閉包

2023-11-06 08:00:00

ReactJavaScript開發

2020-07-29 10:10:37

HTTP緩存前端

2020-10-28 09:12:48

React架構Hooks

2020-04-27 09:40:13

Reacthooks前端

2021-03-18 08:00:55

組件Hooks React

2022-05-06 16:18:00

Block和 C++OC 類lambda

2010-07-26 11:27:58

Perl閉包
點贊
收藏

51CTO技術棧公眾號

性欧美疯狂xxxxbbbb| 久久99精品国产.久久久久久| 亚洲成人av在线| 农村妇女精品一二区| 啊v在线视频| 成人一二三区视频| 日本韩国欧美精品大片卡二| 国产人与禽zoz0性伦| 91精品国产乱码久久久竹菊| 色综合久久66| 肉大捧一出免费观看网站在线播放| 日本黄色一区二区三区| 秋霞电影一区二区| 久久免费精品日本久久中文字幕| 国产一二三四区在线| 在这里有精品| 欧美日韩激情一区二区三区| 激情伊人五月天| 国产在线观看免费麻豆| 久久亚洲欧美国产精品乐播| 亚洲自拍偷拍色片视频| 亚洲天堂男人av| 欧美体内she精视频在线观看| 亚洲女人被黑人巨大进入al| 久久久无码人妻精品无码| 电影一区二区| 狠狠躁18三区二区一区| 国产精品视频一二三四区| 成人av一区| 91视频91自| 国产精品久久精品国产| 国产精品久久久久久久成人午夜| 久久久成人网| 91av视频在线播放| 久久一区二区三| 亚洲午夜精品一区二区国产| 国产亚洲欧洲在线| 最新中文字幕视频| 欧美黑人做爰爽爽爽| 日韩一二三区不卡| 日韩av自拍偷拍| 成人av色网站| 欧美午夜精品久久久久久人妖| 国产免费裸体视频| 91网在线看| 亚洲婷婷在线视频| 超碰免费在线公开| 久久99精品久久| 中文字幕亚洲欧美在线不卡| 亚洲欧美国产一区二区| 国产高清视频免费最新在线| 国产日产欧美精品一区二区三区| 奇米视频888战线精品播放| 天堂在线资源库| 99精品久久久久久| 麻豆av一区| 青青草在线视频免费观看| 91碰在线视频| 日韩精品第一页| 成年人在线看| 国产精品久久久久久久久快鸭| 日韩一区国产在线观看| porn亚洲| 亚洲丝袜制服诱惑| 特大黑人娇小亚洲女mp4| 性欧美video高清bbw| 亚洲自拍偷拍麻豆| 精品人妻少妇一区二区| 日本а中文在线天堂| 亚洲国产中文在线二区三区免| 色综合一区二区三区| 欧美一级片中文字幕| 日韩欧美一区二区三区在线观看| 在线免费观看一区| 视频在线观看免费高清| www.欧美| 亚洲国产精品999| 亚洲av片不卡无码久久| 国产一区二区三区不卡视频网站| 中文字幕av一区二区| 暗呦丨小u女国产精品| 欧美在线观看天堂一区二区三区| 欧美精品videosex极品1| 尤物视频在线观看国产| 日韩av中文在线观看| 成人做爽爽免费视频| 亚洲av综合色区无码一二三区 | 亚洲精品福利网站| 99综合电影在线视频| 青青影院一区二区三区四区| 欧美成人三区| 香蕉加勒比综合久久| 欧美 日韩 国产 激情| 9999精品视频| 亚洲精品天天看| 国产老头老太做爰视频| 99re国产精品| 91久久国产精品| 天天操天天操天天干| 欧美国产精品专区| 亚洲 欧美 综合 另类 中字| 欧美中文字幕精在线不卡| 欧美久久久久免费| 亚洲天堂成人av| 日韩免费视频| 91高潮在线观看| 国产女人高潮毛片| 不卡影院免费观看| 中文字幕超清在线免费观看| 伊人久久av| 日韩一二三区视频| 欧美波霸videosex极品| 亚洲电影成人| 亚洲mm色国产网站| 国产系列在线观看| 亚洲成av人片| 91欧美一区二区三区| 少妇精品久久久一区二区| 美女少妇精品视频| 最近中文在线观看| 2014亚洲片线观看视频免费| 国产成人亚洲综合无码| 欧洲精品久久久久毛片完整版| 日韩高清免费在线| 无码人妻精品一区二区三区夜夜嗨| 石原莉奈一区二区三区在线观看| 国产成人女人毛片视频在线| 成人午夜在线影视| 欧美日韩一区二区三区四区五区 | 97婷婷涩涩精品一区| 国产麻豆一精品一男同| 日本一区二区三区在线观看| 韩国日本在线视频| 啪啪国产精品| 97国产精品视频人人做人人爱| 国产肥老妇视频| 亚洲欧洲精品一区二区三区不卡| 亚洲国产精品三区| 亚洲最大在线| 68精品久久久久久欧美| 色婷婷激情五月| 亚洲国产va精品久久久不卡综合 | 欧美国产一级片| 99re这里只有精品首页| 日韩av高清在线看片| 在线视频亚洲欧美中文| 欧美激情性做爰免费视频| www.色亚洲| 一级日本不卡的影视| 99国产精品免费视频| 综合国产在线| 亚洲综合在线播放| 黄网站在线观| 亚洲电影天堂av| 中文字幕在线观看视频网站| ww亚洲ww在线观看国产| 日本三级免费观看| 色综合中文网| 成人黄色影片在线| av在线免费网站| 精品国产伦一区二区三区观看体验 | 国产精品高潮呻吟久久| 国产一伦一伦一伦| 亚洲免费二区| 国产视频不卡| 中文字幕不卡三区视频| 永久免费精品影视网站| 国产又粗又猛又爽又黄的| 亚洲精品亚洲人成人网在线播放| www.四虎精品| 性一交一乱一区二区洋洋av| 日本免费一区二区三区| 国产 日韩 欧美| 欧美丰满老妇厨房牲生活| 婷婷丁香花五月天| 欧洲一区二区三区免费视频| 中日韩一级黄色片| 成人精品视频一区二区三区 | 亚洲精品成a人在线观看| 久久亚洲天堂网| 国产精品伦理在线| 丰满人妻一区二区三区53视频| 国产精品亚洲欧美| 亚洲一区3d动漫同人无遮挡| 日韩精品视频中文字幕| 69av成年福利视频| 国产美女性感在线观看懂色av| 精品久久久久久亚洲精品| 中文字幕精品久久久| 日本欧美一区二区三区乱码| 超级碰在线观看| 国产日韩欧美一区二区三区| 亚洲综合色激情五月| 肉色欧美久久久久久久免费看| 欧美美最猛性xxxxxx| 巨骚激情综合| 日韩欧美一区二区免费| 午夜一区二区三区四区| 一区二区在线观看av| 男人舔女人下部高潮全视频| 国产99久久久国产精品免费看 | 日韩免费不卡视频| 国产精品欧美一区喷水| 91超薄肉色丝袜交足高跟凉鞋| 日本不卡一二三区黄网| 久久亚洲a v| 日韩久久综合| 日本精品一区二区三区高清 久久 日本精品一区二区三区不卡无字幕 | xxxx视频在线观看| 日韩一区欧美二区| 免费拍拍拍网站| 欧美一区亚洲| 综合一区中文字幕| 国产精品亚洲二区| 国产激情一区二区三区在线观看 | 精品国内二区三区| 亚洲视频一区二区三区四区| 丰满岳妇乱一区二区三区| 欧洲第一无人区观看| 国产精品二三区| 中国美女乱淫免费看视频| 成人av先锋影音| 超碰在线超碰在线| 精品一区二区三区在线播放视频| 日韩av播放器| 国产日韩综合| 成人毛片一区二区| 欧美日韩国产免费观看| 成年人黄色在线观看| 精品日本12videosex| 免费亚洲精品视频| 欧美有码在线| 精品久久蜜桃| 久久精品66| 黄色99视频| 国产精品网址| 精品国产_亚洲人成在线| 日韩精品一区二区三区免费视频| 91免费看国产| 国内不卡的一区二区三区中文字幕| 国产精品视频在线播放| av激情成人网| 国产精品久久久久久久久粉嫩av| 亚洲高清黄色| 国产精品扒开腿做| 亚洲第一会所| 国产热re99久久6国产精品| 国产精品久久久久久久久免费高清| 国产91色在线| 国精品产品一区| 成人福利在线观看| 精品99re| 国产欧美日韩视频一区二区三区| 国产毛片久久久| 精品久久sese| 精品国产乱码久久久久久果冻传媒 | 日本久久黄色| 大地资源第二页在线观看高清版| 91精品婷婷色在线观看| 色哟哟免费网站| 激情综合久久| 国产真实乱子伦| 久久一二三四| 99re6在线观看| 国产不卡视频在线播放| 日韩无码精品一区二区| 久久亚洲精华国产精华液| 欧美激情视频二区| 综合激情成人伊人| 国产亚洲精品av| 欧美性高潮在线| 中文字幕在线观看精品| 欧美一区二区三区婷婷月色| 日日夜夜精品免费| 国产一区二区三区视频| 国产精品刘玥久久一区| 国内精品久久久久久久| 免费观看一级欧美片| 国产精品视频资源| jazzjazz国产精品久久| 日本精品免费| 国产精品s色| 国产情侣av自拍| 国产一区在线不卡| 性色av蜜臀av色欲av| 中文字幕一区二区三| 日韩欧美不卡视频| 欧美日韩国产天堂| 无码国产伦一区二区三区视频| 一区二区三区四区在线观看视频| 91小视频xxxx网站在线| 日本精品免费观看| 精品中文字幕一区二区三区四区 | 精品国产中文字幕第一页| 亚洲精品日韩成人| 亚洲国产日本| 中文字幕久久av| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 又骚又黄的视频| 亚洲国内高清视频| 黄色在线免费看| 国产精品久久久久久久9999| 9999久久久久| 99热这里只有精品7| 国产精品呻吟| 国产午夜在线一区二区三区| 日本一区二区高清| 四虎成人精品永久免费av| 欧美群妇大交群中文字幕| 亚洲三区在线播放| 欧美疯狂做受xxxx高潮| 久久夜夜久久| 欧美一进一出视频| 精品成人国产| 国产人妻精品久久久久野外| 久久久久久亚洲综合| 日本一区二区不卡在线| 欧美一级爆毛片| av在线第一页| 2020久久国产精品| 北条麻妃一区二区三区在线观看| 中文字幕一区二区中文字幕| 日韩精品免费专区| 屁屁影院国产第一页| 亚洲高清一区二区三区| 国产日韩欧美中文字幕| 色妞色视频一区二区三区四区| 欧美7777| 麻豆蜜桃91| 国产精品社区| 国产二级一片内射视频播放| 一区二区理论电影在线观看| 国产日韩精品suv| 美女精品视频一区| 麻豆精品一区| 日本精品福利视频| 国产精品一区二区黑丝 | 欧美午夜无遮挡| 日韩欧美亚洲系列| 日本sm极度另类视频| 婷婷亚洲精品| 久久国产乱子伦免费精品| 91蝌蚪porny| 在线观看日本网站| 亚洲三级黄色在线观看| 成人美女黄网站| 任我爽在线视频精品一| 首页国产欧美日韩丝袜| 亚洲天堂岛国片| 欧美日韩专区在线| 黄色免费网站在线| 亚洲va欧美va国产综合久久| 欧美a级片一区| 亚洲视频天天射| 欧美日韩在线视频观看| 精品乱码一区二区三四区视频| 国产精品夫妻激情| 99精品全国免费观看视频软件| 国产又黄又猛的视频| 亚洲精品国产高清久久伦理二区| 精品人妻午夜一区二区三区四区 | 99精品视频一区二区三区| 一级片中文字幕| 国产一区二区三区中文 | 精品欧美一区二区三区久久久| 国产日本精品| 欧美午夜激情影院| 日韩视频免费观看高清完整版| 丁香花在线观看完整版电影| 精品久久久久久一区| 日本va欧美va精品| 日本黄色片免费观看| 亚洲丁香婷深爱综合| 成人亚洲欧美| 成人手机视频在线| 国产69精品久久777的优势| 伊人手机在线视频| 中文字幕亚洲专区| 99久久免费精品国产72精品九九| 黄色一级一级片| 亚洲欧美成人一区二区三区| 婷婷五月综合久久中文字幕| 国产精品美女久久久久久免费| 综合激情婷婷| www.av天天| 日韩欧美一级二级三级| 综合久久2023| 黄色网在线视频| 中文字幕高清一区| 婷婷伊人综合中文字幕| 成人精品一区二区三区电影免费 | 无套内谢大学处破女www小说| 欧美在线观看禁18| 毛片网站在线看| 亚洲精品中文字幕在线| 成人毛片在线观看| 一级黄色免费片| 热99久久精品| 亚洲午夜黄色| 顶级黑人搡bbw搡bbbb搡|