日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

React?Hook中useState更新延遲問題及解決_React

作者:CahierX ? 更新時間: 2022-10-01 編程語言

React Hook中useState更新延遲

方法一:去掉useEffect的第二個參數

例如以下代碼 錯誤實例

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

會出現zoom永遠等于 0+5, 而不是所謂的5, 10 ,15 為什么會這樣呢? 因為useEffect執行時,會創建一個閉包,在每次監聽到mousewheel運行時 閉包內部保存了zoom的初始化值 每次調用的時候都是取的初始化值0 所有會一直為0+5

怎么解決呢?

解決方案: 去掉useEffect中的空數組即可

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)
}

方法二:將改變函數移入useEffect并將第二個參數設置為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內監聽此ref, 并實時跟useState同步

例如下面的代碼 錯誤示例

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

初始化currentIndex為0 每次執行handleLeft函 數是讓currentIndex加1, 之后立即獲取currentIndex的值發現 第一次執行currentIndex = 0

第二次執行currentIndex = 1 每次都跟實際情況差一個 ?查閱資料發現useState必須要執行完react整個生命周期才會獲取最新值

解決方案:用useRef中轉,并實時同步給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連續更新對象問題

react hook 的useState更新是異步的,所以在連續更新出發useState時會出現問題

eg:?

import React, {useState} from 'react';
?
export default () => {
? ? const [obj, setObj] = useState({
? ? ? ? a: 1,
? ? ? ? b: 2
? ? ? })
?
? ? const changeObj = () => {
? ? ? ? // 連續觸發2次setObj(實際項目不會這樣寫,我這樣寫只是為了模擬連續觸發2次setObj帶來的問題)
? ? ? ? setObj({...obj, a: 2})
? ? ? ? setObj({...obj, b: 3})?
? ? }
? ?return (<div onClick={changeObj}>
? ? ? ? ? // 此時頁面上顯示的值為 {a: 1, b: 3}, 出現該問題的原因是因為useState是異步的,在第二次觸發setObj時,obj還是沒更新a之前的obj,所以出現該結果
? ? ? ? ? ? {JSON.stringify(obj)}
? ? ? ? ? ?</div>)
}

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

import React, {useState} from 'react';
?
export default () => {
? ? const [obj, setObj] = useState({
? ? ? ? a: 1,
? ? ? ? b: 2
? ? ? })
?
? ? const changeObj = () => {
? ? ? ? // 連續觸發2次setObj(實際項目不會這樣寫,為了模擬情況)
? ? ? ? setObj({...obj, a: 2})
? ? ? ? // data標識存儲的是更新a后的對象,用這樣的方式可以解決連續觸發2次帶來的問題
? ? ? ? setObj((data) => ({...data, b: 3}))?
? ? }
? ?return (<div onClick={changeObj}>
? ? ? ? ? // 此時頁面上顯示的值為 {a: 2, b: 3}
? ? ? ? ? ? {JSON.stringify(obj)}
? ? ? ? ? ?</div>)
}

原文鏈接:https://blog.csdn.net/qq_35493664/article/details/105195549

欄目分類
最近更新