<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
React的useEffect Hook
可以讓使用者處理應用程式的副作用
。例如:
從網路獲取資料
:應用程式通常在第一次載入時獲取並填充資料。這可以通過useEffect
函數實現操作UI
:應用程式應該響應按鈕點選事件(例如,開啟一個選單)設定或結束計時器
:如果某個變數達到預定義值,則內建計時器應自行停止或啟動儘管useEffect Hook在React生態系統中很常見,但它需要時間來掌握。因此,許多新手開發人員在設定他們的useEffect函數時,會導致無限迴圈問題。在本文中,您將瞭解不同場景下帶來的無限迴圈問題以及如何解決它們。
這是我們今天要學習的內容:
是什麼導致無限迴圈以及如何解決它們:
在依賴項陣列中不傳遞依賴項
如果您的useEffect函數不包含任何依賴項,則會出現一個無限迴圈。
例如,看看下面的程式碼:
function App() { const [count, setCount] = useState(0); //初始化值 useEffect(() => { setCount((count) => count + 1); }); //無依賴項 return ( <div className="App"> <p> value of count: {count} </p> </div> ); }
如果沒有依賴關係,則預設在每個更新週期上觸發useEffect。因此,這裡的應用程式將在每次渲染時執行setCount函數。因此,這會導致一個無限迴圈:
是什麼導致了這個問題?讓我們一步一步來分析這個問題:
count
的值。在這裡,由於count為0,程式執行useEffect函數useEffect在每個呈現週期中執行
,它將重新呼叫setCount函數
為了緩解這個問題,我們必須使用依賴陣列,告訴React只有在特定值更新時才呼叫useEffect。
下一步,像這樣附加一個空白陣列作為依賴項:
useEffect(() => { setCount((count) => count + 1); }, []); //empty array as second argument.
這告訴React在第一次裝載時執行setCount
函數。
如果你把一個方法傳入你的useEffect
依賴陣列,React會丟擲一個錯誤,表明你有一個無限迴圈:
function App() { const [count, setCount] = useState(0); function logResult() { return 2 + 2; } useEffect(() => { setCount((count) => count + 1); }, [logResult]); // 函數作為依賴項 return ( <div className="App"> <p> value of count: {count} </p> </div> ); }
在這段程式碼中,我們將logResult
方法傳遞給useEffect
陣列。理論上,React只需要在第一次渲染時增加count
的值。
是什麼導致了這個問題?
如何解決這個問題
一個解決方案是使用useCallback
勾點。這允許開發人員記住他們的函數,從而確保參照值保持不變。由於這個參考值是穩定的,React不應該無限地重新渲染UI:
const logResult = useCallback(() => { return 2 + 2; }, []); // logResult是快取的 useEffect(()=> { setCount((count)=> count+1); },[logResult]); //沒有無限迴圈錯誤,因為logResult參照保持不變。
結果:
將陣列變數傳遞給依賴項也會執行一個無限迴圈。考慮下面的程式碼範例:
const [count, setCount] = useState(0); //初始值為0。 const myArray = ["one", "two", "three"]; useEffect(() => { setCount((count) => count + 1); // 和前面一樣,增加Count的值 }, [myArray]); // 將陣列變數傳遞給依賴項
在這個塊中,我們將myArray變數傳入依賴引數。
是什麼導致了這個問題?
既然myArray的值在整個程式中都沒有改變,為什麼我們的程式碼會多次觸發useEffect ?
如何解決這個問題
為了解決這個問題,我們可以使用useRefHook。這將返回一個可變物件,確保參照不會改變:
const [count, setCount] = useState(0); //提取「current」屬性並給它賦值 const { current: myArray } = useRef(["one", "two", "three"]); useEffect(() => { setCount((count) => count + 1); }, [myArray]); //依賴值是穩定的,所以沒有無限迴圈
在useEffect依賴陣列中使用物件也會導致無限迴圈問題。
考慮下面的程式碼:
const [count, setCount] = useState(0); const person = { name: "Rue", age: 17 }; //建立一個物件 useEffect(() => { // 每次增加count的值 // person的值發生了變化 setCount((count) => count + 1); }, [person]); // 依賴項陣列包含一個物件作為引數 return ( <div className="App"> <p> Value of {count} </p> </div> );
控制檯的結果表明程式是無限迴圈的:
是什麼導致了這個問題?
如何解決這個問題
那麼我們如何解決這個問題呢?
這就是usemmo
的用武之地。**當依賴關係發生變化時,這個勾點會計算一個記憶的值。**除此之外,因為我們記住了一個變數,這確保了狀態的參照值在每次渲染期間不會改變:
// 使用usemo建立一個物件 const person = useMemo( () => ({ name: "Rue", age: 17 }), [] //沒有依賴關係,所以值不會改變 ); useEffect(() => { setCount((count) => count + 1); }, [person]);
如果將錯誤的變數傳遞給useEffect函數,React將丟擲一個錯誤。
下面是一個簡單的例子:
const [count, setCount] = useState(0); useEffect(() => { setCount((count) => count + 1); }, [count]); //注意,我們將count傳遞給了這個陣列。 return ( <div className="App"> <button onClick={() => setCount((count) => count + 1)}>+</button> <p> Value of count{count} </p> </div> );
是什麼導致了這個問題?
如何解決這個問題
要擺脫無限迴圈,只需像這樣使用一個空的依賴陣列:
const [count, setCount] = useState(0); // 只有在元件首次掛載時才更新'count'的值 useEffect(() => { setCount((count) => count + 1); }, []);
這將告訴React在第一次渲染時執行useEffect。
儘管React Hooks是一個簡單的概念,但是在將它們整合到專案中時,仍然需要記住許多規則。這將確保您的應用程式保持穩定,優化,並在生產過程中不丟擲錯誤。
此外,最近釋出的Create React App CLI
也會在執行時檢測和報告無限迴圈錯誤。這有助於開發人員在這些問題出現在生產伺服器上之前發現並解決這些問題。
到此這篇關於如何解決React useEffect勾點帶來的無限迴圈問題的文章就介紹到這了,更多相關React useEffect勾點無限迴圈內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45