精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

欧美日韩一区成人| 久久奇米777| 欧美激情xxxx| 超碰97人人干| 国产精品igao视频网网址不卡日韩| 一区二区三区在线免费观看| 久久国产精品精品国产色婷婷| 亚洲精品无码久久久久| 欧美另类亚洲| 在线观看久久av| 免费不卡的av| 久久久久毛片| 天天综合网 天天综合色| 日本黄网免费一区二区精品| 国产露脸无套对白在线播放| 午夜在线一区| 九九久久久久久久久激情| 亚洲综合网在线观看| 欧美国产中文高清| 欧美羞羞免费网站| 欧美极品欧美精品欧美| 黄色网页在线播放| 国产三级精品三级| 成人午夜影院在线观看| 中文字幕无线码一区| 99热精品在线| 欧美黑人视频一区| 日本一级片免费| 啪啪亚洲精品| 精品性高朝久久久久久久| 国产成人av免费观看| 69堂免费精品视频在线播放| 亚洲国产日日夜夜| 欧美做受777cos| 在线看的av网站| 国产偷国产偷亚洲高清人白洁| 国内精品视频免费| 国 产 黄 色 大 片| 紧缚奴在线一区二区三区| 欧美最近摘花xxxx摘花| 日韩免费不卡视频| 欧美在线二区| 久久av在线看| 欧美日韩精品一区二区三区视频播放| 欧美成人milf| 日韩在线视频观看| 一二三四在线观看视频| 神马久久一区二区三区| 亚洲日本aⅴ片在线观看香蕉| 中国黄色片视频| 成人激情自拍| 亚洲国产精品资源| 日韩aaaaa| 日韩高清影视在线观看| 日韩av一区在线| 菠萝菠萝蜜网站| 农村少妇一区二区三区四区五区| 精品国产123| 欧产日产国产精品98| 给我免费播放日韩视频| 精品成人a区在线观看| 国产综合内射日韩久| 加勒比久久高清| 日韩黄色高清视频| b站大片免费直播| 成人看的羞羞网站| 日韩中文在线中文网在线观看| 极品蜜桃臀肥臀-x88av| 久久亚洲影视| 欧美大片va欧美在线播放| 久草视频免费在线播放| 夜夜夜久久久| 国产精品h在线观看| 一本色道久久综合精品婷婷| 国产在线精品不卡| 懂色一区二区三区av片| 香蕉视频黄在线观看| 久久精品人人做人人爽97| 水蜜桃一区二区| 成人在线视频亚洲| 亚洲综合男人的天堂| 国产伦精品一区二区三区四区视频_| 爱啪啪综合导航| 欧美丝袜丝nylons| 伊人久久久久久久久| 亚欧日韩另类中文欧美| 日韩中文字幕在线播放| 久久综合久久鬼| 欧美综合二区| 2020国产精品久久精品不卡| 无码精品一区二区三区在线| 国产日本一区二区| 欧美xxxx吸乳| 最新日韩三级| 日韩视频免费观看高清完整版在线观看 | 又大又长粗又爽又黄少妇视频| 精品伊人久久久| 中文字幕亚洲自拍| 日韩精品一区二区在线播放| 免费在线看成人av| 国产精品免费一区二区| www.亚洲资源| 亚洲成人动漫精品| 三上悠亚在线一区二区| 精品三级av| 久久久精品欧美| 欧美精品亚洲精品日韩精品| 捆绑变态av一区二区三区| 精品国产一区二区三| 免费黄色网页在线观看| 欧美性猛交xxxx乱大交极品| 日本美女久久久| 国产va免费精品观看精品视频| 麻豆乱码国产一区二区三区| 亚洲欧美综合自拍| 成人精品鲁一区一区二区| 亚洲精品在线视频观看| 蜜桃视频动漫在线播放| 欧美一级日韩不卡播放免费| 国产亚洲精品熟女国产成人| 亚洲国产高清视频| 国产精品小说在线| 欧美69xxxxx| 亚洲福利视频一区二区| 欧洲美女亚洲激情| 久久中文字幕av一区二区不卡| 欧美一级电影久久| 日本精品一二区| 一区二区三区加勒比av| 亚洲va综合va国产va中文| 你懂的一区二区三区| 26uuu国产精品视频| 高h放荡受浪受bl| 一区二区在线免费观看| 做a视频在线观看| 日韩欧美一区二区三区免费看| 日本一区二区三区在线播放| 午夜国产在线视频| 姬川优奈aav一区二区| 动漫美女无遮挡免费| 在线精品国产| 亚洲一区二区三区乱码aⅴ蜜桃女| 91av资源在线| 欧美日韩性生活| 女教师淫辱の教室蜜臀av软件| 日韩av一区二区三区四区| 日本免费高清不卡| 日韩电影免费观| 在线精品高清中文字幕| 国产精华7777777| 中文子幕无线码一区tr| 在线观看av日韩| 色琪琪久久se色| 91中文在线视频| 2024短剧网剧在线观看| 日韩视频一区在线观看| 日本熟女一区二区| 99九九99九九九视频精品| 国产肥臀一区二区福利视频| 免费欧美视频| 国产噜噜噜噜久久久久久久久| 天堂аⅴ在线地址8| 欧美久久久久免费| 欧美黄色免费看| 不卡视频一二三| 成年人观看网站| 波多野结衣在线播放一区| 国产日韩在线看| 在线播放免费av| 亚洲国产精品久久久| 国产伦精品一区二区三区视频网站| 久久网这里都是精品| 激情 小说 亚洲 图片: 伦| 天天做天天爱天天综合网| 99免费在线观看视频| 91探花在线观看| 亚洲欧美激情一区| 国产又黄又大又粗的视频| 一区二区三区欧美| 素人fc2av清纯18岁| 日本美女一区二区三区| 水蜜桃在线免费观看| 日韩美女毛片| 国产区精品视频| brazzers在线观看| 国产亚洲xxx| 亚洲第一天堂网| 91国产精品成人| 欧美被狂躁喷白浆精品| 91麻豆福利精品推荐| 亚洲精品免费一区亚洲精品免费精品一区 | 免费中文字幕在线观看| 久久久久国产精品厨房| aaaaaaaa毛片| 久久久久久久尹人综合网亚洲| 9999在线观看| 亚洲品质自拍| 91福利视频导航| 国产亚洲一区二区手机在线观看| 不卡av日日日| 狠狠狠综合7777久夜色撩人| 日韩精品一区二区三区视频 | 久久99导航| 国产精品99久久免费| 全亚洲最色的网站在线观看| 黄色在线免费| 在线视频欧美性高潮| 黄色片网站免费在线观看| 欧美猛男超大videosgay| 亚洲日本视频在线观看| 伊人性伊人情综合网| 国产大屁股喷水视频在线观看| 成人免费三级在线| 午夜激情影院在线观看| 日韩精品三区四区| 免费看黄在线看| 欧美在线不卡| 日本一区二区免费高清视频| 久久99国内| 精品国产乱码久久久久久蜜柚 | 91精品国产麻豆国产自产在线| 精品国产一区二区三区四| 一区二区三区毛片| 亚洲国产精品免费在线观看| 国产婷婷色一区二区三区在线| 成人性生活免费看| 高潮精品一区videoshd| 无码人妻少妇色欲av一区二区| 日本亚洲视频在线| 日本在线视频www| 亚洲最黄网站| 毛片在线视频播放| 欧美亚洲不卡| 欧美黄色免费网址| 欧美国产综合| 日韩欧美一级在线| 婷婷综合久久| 亚洲第一页在线视频| 欧美大人香蕉在线| 亚洲欧洲精品一区二区三区波多野1战4| 婷婷成人影院| 欧美精品一区在线| 亚洲+小说+欧美+激情+另类 | 日本午夜在线视频| 日韩成人在线观看| 日本五码在线| 伊人久久免费视频| 在线a人片免费观看视频| 最近中文字幕2019免费| 日本中文字幕在线2020| 日韩在线观看视频免费| 蜜桃视频在线观看免费视频网站www| 色黄久久久久久| 国产激情在线| 欧美激情视频在线观看| 国产99re66在线视频| 国产91成人video| 色8久久影院午夜场| 国产极品jizzhd欧美| 狂野欧美性猛交xxxx| 91热福利电影| 国产精品久久久久av蜜臀| 国产午夜精品一区| 久久99性xxx老妇胖精品| 日本欧美色综合网站免费| 人人狠狠综合久久亚洲婷| 一区二区三区久久网| 1024精品久久久久久久久| 超级碰在线观看| 9色精品在线| 污片在线免费看| 国产精一品亚洲二区在线视频| 深夜视频在线观看| 99久久精品99国产精品| 91社区视频在线观看| 亚洲欧美日韩一区| 久久精品一二区| 欧美人xxxx| 欧美视频xxx| 亚洲午夜精品视频| 最新国产露脸在线观看| 91国语精品自产拍在线观看性色 | 国产伦精品一区二区三区四区视频 | 国产精品二区一区二区aⅴ| 精品日本美女福利在线观看| 超碰在线97观看| 欧美大胆一级视频| 国产美女性感在线观看懂色av| 精品精品国产国产自在线| 99热99re6国产在线播放| 国产91精品网站| 欧美国产亚洲精品| 日韩欧美一区二区视频在线播放| 欧美在线网址| 日本熟妇人妻xxxxx| 国产一区91精品张津瑜| 亚洲第一香蕉网| 亚洲制服丝袜一区| 波多野结衣一本一道| 日韩美女在线视频| 国产精品四虎| 97超视频免费观看| 国产欧美88| 天堂√在线观看一区二区| 亚洲一级一区| 涩涩网站在线看| 久久久精品影视| 国产精品23p| 69av一区二区三区| 黄色在线网站| 57pao成人国产永久免费| 欧美9999| 天天综合五月天| 日韩不卡一区二区三区| 在线天堂www在线国语对白| 亚洲欧洲高清| 亚洲婷婷综合色高清在线| 成人精品一二三区| 欧美日韩中文字幕在线| 国产福利第一页| 中日韩美女免费视频网址在线观看 | 日本福利视频在线观看| 美洲天堂一区二卡三卡四卡视频| 北岛玲一区二区| 亚洲午夜电影在线观看| 国产日韩在线观看一区| 最近2019年手机中文字幕 | 狠狠88综合久久久久综合网| 中文字幕视频三区| 国产丝袜在线精品| 六月丁香婷婷综合| 亚洲精品av在线| 波多一区二区| 成人欧美一区二区三区在线观看| 外国成人激情视频| 五月婷婷丁香综合网| 久久免费看少妇高潮| 日韩av黄色片| 亚洲国产日韩欧美在线动漫| 50度灰在线| 91国产在线免费观看| 91免费精品| 少妇一级淫免费播放| 欧美国产日韩a欧美在线观看| 国产suv精品一区二区33| 精品偷拍一区二区三区在线看 | 欧美粗暴jizz性欧美20| 夜夜爽久久精品91| 夜夜揉揉日日人人青青一国产精品| 精品国产区一区二| 欧美老女人性视频| 国产成人精品亚洲线观看| 国产精品无码人妻一区二区在线| 成人午夜伦理影院| 国产特黄大片aaaa毛片| 国产视频精品一区二区三区| 色老太综合网| 亚洲精品自在在线观看| 久久成人18免费观看| 黑鬼狂亚洲人videos| 精品黑人一区二区三区久久 | 亚洲国产日韩a在线播放| 亚洲精品久久久久久久久久| 久久久综合av| 香蕉国产成人午夜av影院| 九九九在线观看视频| 中文字幕在线观看一区二区| 精品久久久中文字幕人妻| 欧美激情一区二区三区成人| 米奇精品关键词| 超碰av在线免费观看| 亚洲女人****多毛耸耸8| 囯产精品一品二区三区| 日本中文字幕不卡免费| 欧美电影免费| 在线免费看黄色片| 在线亚洲一区观看| 国产高清一区二区三区视频 | 成人中文在线| 日本高清免费观看| 欧美日韩中文在线观看| 日本在线人成| 国产在线观看一区| 免费观看成人av| 久久久久久久九九九九| 亚洲人成电影网站色xx| 国产视频一区二| 97国产精东麻豆人妻电影 | 午夜偷拍福利视频| 亚洲亚裔videos黑人hd| 欧美欧美在线| 福利在线一区二区三区| 亚洲精品videosex极品| 欧美伦理影视网| 亚洲影视九九影院在线观看| 亚洲影院一区| 福利所第一导航| 国产亚洲精品91在线| jazzjazz国产精品久久| 一区二区成人网|