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

React Hook中useState更新延遲問(wèn)題及解決

 更新時(shí)間:2022年08月05日 12:18:49   作者:CahierX  
這篇文章主要介紹了React Hook中useState更新延遲問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

React Hook中useState更新延遲

方法一:去掉useEffect的第二個(gè)參數(shù)

例如以下代碼 錯(cuò)誤實(shí)例

const[zoom, setZoom] = useState(0);
useEffect(() = >{
? ? document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
},[]);
function scrollFunc(e) {
? ? setZoom(zoom + 5)
}

會(huì)出現(xiàn)zoom永遠(yuǎn)等于 0+5, 而不是所謂的5, 10 ,15 為什么會(huì)這樣呢? 因?yàn)閡seEffect執(zhí)行時(shí),會(huì)創(chuàng)建一個(gè)閉包,在每次監(jiān)聽(tīng)到mousewheel運(yùn)行時(shí) 閉包內(nèi)部保存了zoom的初始化值 每次調(diào)用的時(shí)候都是取的初始化值0 所有會(huì)一直為0+5

怎么解決呢?

解決方案: 去掉useEffect中的空數(shù)組即可

const[zoom, setZoom] = useState(0);
useEffect(() = >{
? ? document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
? ? return () = >document.getElementById('workspace-content').removeEventListener("mousewheel", scrollFunc); // 記得解綁事件
});
function scrollFunc(e) {
? ? setZoom(zoom + 5)
}

方法二:將改變函數(shù)移入useEffect并將第二個(gè)參數(shù)設(shè)置為state

依舊用上面的例子

解決方法:正確示例

useEffect(() = >{
? ? document.getElementById('workspace-content').addEventListener('mousewheel', scrollFunc);
? ? return () = >document.getElementById('workspace-content').removeEventListener("mousewheel", scrollFunc);
? ? function scrollFunc(e) {
? ? ? ? setZoom(zoom + 5) e.preventDefault()
? ? }
},[zoom]);

方法三:使用Ref, 在useEffect內(nèi)監(jiān)聽(tīng)此ref, 并實(shí)時(shí)跟useState同步

例如下面的代碼 錯(cuò)誤示例

const [currentIndex, setCurrentIndex] = useState(0)
? const handleLeft = () => {
? ? ?setCurrentIndex(currentIndex+ 1)
? ? ?console.log(currentIndex)
? }

初始化currentIndex為0 每次執(zhí)行handleLeft函 數(shù)是讓currentIndex加1, 之后立即獲取currentIndex的值發(fā)現(xiàn) 第一次執(zhí)行currentIndex = 0

第二次執(zhí)行currentIndex = 1 每次都跟實(shí)際情況差一個(gè)  查閱資料發(fā)現(xiàn)useState必須要執(zhí)行完react整個(gè)生命周期才會(huì)獲取最新值

解決方案:用useRef中轉(zhuǎn),并實(shí)時(shí)同步給useState 

const [currentIndex, setCurrentIndex] = useState(0)
const currentIndexRef = useRef(0);
? const handleLeft = () => {
? ? ?currentIndexRef.current += 1
? ? ?console.log(currentIndexRef.current)
? }
useEffect(()=>{
? ? setCurrentIndex(currentIndexRef.current)
},[currentIndexRef.current])

React Hook useState連續(xù)更新對(duì)象問(wèn)題

react hook 的useState更新是異步的,所以在連續(xù)更新出發(fā)useState時(shí)會(huì)出現(xiàn)問(wèn)題

eg: 

import React, {useState} from 'react';
?
export default () => {
? ? const [obj, setObj] = useState({
? ? ? ? a: 1,
? ? ? ? b: 2
? ? ? })
?
? ? const changeObj = () => {
? ? ? ? // 連續(xù)觸發(fā)2次setObj(實(shí)際項(xiàng)目不會(huì)這樣寫,我這樣寫只是為了模擬連續(xù)觸發(fā)2次setObj帶來(lái)的問(wèn)題)
? ? ? ? setObj({...obj, a: 2})
? ? ? ? setObj({...obj, b: 3})?
? ? }
? ?return (<div onClick={changeObj}>
? ? ? ? ? // 此時(shí)頁(yè)面上顯示的值為 {a: 1, b: 3}, 出現(xiàn)該問(wèn)題的原因是因?yàn)閡seState是異步的,在第二次觸發(fā)setObj時(shí),obj還是沒(méi)更新a之前的obj,所以出現(xiàn)該結(jié)果
? ? ? ? ? ? {JSON.stringify(obj)}
? ? ? ? ? ?</div>)
}

解決此情況的方式,就是在第二次觸發(fā)時(shí)使用setObj((data) => ({...data, b: 3})) 這樣的方式

import React, {useState} from 'react';
?
export default () => {
? ? const [obj, setObj] = useState({
? ? ? ? a: 1,
? ? ? ? b: 2
? ? ? })
?
? ? const changeObj = () => {
? ? ? ? // 連續(xù)觸發(fā)2次setObj(實(shí)際項(xiàng)目不會(huì)這樣寫,為了模擬情況)
? ? ? ? setObj({...obj, a: 2})
? ? ? ? // data標(biāo)識(shí)存儲(chǔ)的是更新a后的對(duì)象,用這樣的方式可以解決連續(xù)觸發(fā)2次帶來(lái)的問(wèn)題
? ? ? ? setObj((data) => ({...data, b: 3}))?
? ? }
? ?return (<div onClick={changeObj}>
? ? ? ? ? // 此時(shí)頁(yè)面上顯示的值為 {a: 2, b: 3}
? ? ? ? ? ? {JSON.stringify(obj)}
? ? ? ? ? ?</div>)
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Remix如何支持原生?CSS方法詳解

    Remix如何支持原生?CSS方法詳解

    這篇文章主要為大家介紹了Remix如何支持原生CSS的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • react?card?slider實(shí)現(xiàn)滑動(dòng)卡片教程示例

    react?card?slider實(shí)現(xiàn)滑動(dòng)卡片教程示例

    這篇文章主要為大家介紹了react?card?slider實(shí)現(xiàn)滑動(dòng)卡片教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • React?diff算法超詳細(xì)講解

    React?diff算法超詳細(xì)講解

    渲染真實(shí)DOM的開(kāi)銷很大,有時(shí)候我們修改了某個(gè)數(shù)據(jù),直接渲染到真實(shí)dom上會(huì)引起整個(gè)dom樹的重繪和重排。我們希望只更新我們修改的那一小塊dom,而不是整個(gè)dom,diff算法就幫我們實(shí)現(xiàn)了這點(diǎn)。diff算法的本質(zhì)就是:找出兩個(gè)對(duì)象之間的差異,目的是盡可能做到節(jié)點(diǎn)復(fù)用
    2022-11-11
  • react使用axios實(shí)現(xiàn)上傳下載功能

    react使用axios實(shí)現(xiàn)上傳下載功能

    這篇文章主要為大家詳細(xì)介紹了react使用axios實(shí)現(xiàn)上傳下載功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • React?如何向url中添加參數(shù)

    React?如何向url中添加參數(shù)

    這篇文章主要介紹了React?如何向url中添加參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • React useCallback鉤子的作用方法demo

    React useCallback鉤子的作用方法demo

    這篇文章主要為大家介紹了React useCallback鉤子的作用方法demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • React報(bào)錯(cuò)map()?is?not?a?function詳析

    React報(bào)錯(cuò)map()?is?not?a?function詳析

    這篇文章主要介紹了React報(bào)錯(cuò)map()?is?not?a?function詳析,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • React實(shí)時(shí)預(yù)覽react-live源碼解析

    React實(shí)時(shí)預(yù)覽react-live源碼解析

    這篇文章主要為大家介紹了React實(shí)時(shí)預(yù)覽react-live源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • 深入研究React中setState源碼

    深入研究React中setState源碼

    這篇文章主要介紹了深入研究React中setState源碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • React八大常見(jiàn)錯(cuò)誤及其解決方案

    React八大常見(jiàn)錯(cuò)誤及其解決方案

    這篇文章主要介紹了React八大常見(jiàn)錯(cuò)誤及其解決方案,并通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)react有一定的幫助,感興趣的朋友可以參考下
    2024-03-03

最新評(píng)論

民权县| 铜鼓县| 五峰| 永川市| 东阿县| 武威市| 寻乌县| 方山县| 苍梧县| 大邑县| 宝清县| 咸丰县| 姚安县| 赤壁市| 寻乌县| 城口县| 克东县| 呼伦贝尔市| 灵璧县| 浮山县| 乌海市| 化德县| 南投市| 北票市| 安岳县| 温州市| 南华县| 胶州市| 偏关县| 依安县| 宣汉县| 阳东县| 钟祥市| 新建县| 武山县| 德江县| 太仆寺旗| 通江县| 左贡县| 孝感市| 鹿泉市|