深入淺出React Hooks – 以react-hooks/exhaustive-deps為中心

一、簡介

React Hooks是React 16.8推出的新特性,是一種更加優雅、簡潔的處理組件狀態和邏輯的方式,幹掉了原有的Class組件,讓函數組件具有了更加強大的能力。

react-hooks/exhaustive-deps是React Hooks中的一個重要概念,用於在useEffect Hook中控制副作用執行的依賴項,使代碼更加健壯、穩定。

二、為什麼需要控制副作用執行的依賴項

在使用useEffect Hook時,React會在DOM更新前執行useEffect副作用函數中的代碼,以保證頁面的正確性和流暢性。由於useEffect是基於函數式編程的思想實現,React並不能像Class組件中的生命周期函數一樣自動清理副作用代碼的引用,這就需要我們手動控制副作用執行的依賴項。

舉個例子:一個簡單的計數器函數組件,每點擊一次按鈕,計數器就會+1,並在useEffect中輸出計數器的值:

import React, { useState, useEffect } from 'react';
  
function Counter() {
  const [count, setCount] = useState(0)
  
  useEffect(() => {
    console.log('count:', count)
  })
  
  return (
    <div>
      <p>count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

但是,運行後我們發現,每點擊一次按鈕,控制台就會輸出當前的count值,即使count並沒有改變。這是因為,useEffect的執行是基於引用依賴,而每次點擊按鈕的時候,函數組件會被重新渲染,useEffect重新執行,此時的count依然是引用上一個count值的地址,所以console輸出的值並沒有改變。

這時候,就需要我們想辦法控制useEffect的依賴項,規避這種無用執行的問題。

三、如何控制副作用執行的依賴項

1. 不指定依賴項

當useEffect的依賴項傳空數組[]時,表明useEffect不依賴任何state或prop,僅在組件掛載和卸載時執行副作用代碼。

useEffect(() => {
  console.log('component did mount');
  
  // 清理操作
  return () => {
    console.log('component will unmount');
  }
}, []) // 傳空數組

這種方式適用於只需要在組件掛載和卸載時執行副作用代碼,而不需要根據state或prop的變化執行的場景。

2. 指定部分依賴項

當useEffect的依賴項為指定的state或prop時,每次state或prop發生變化時,useEffect都會執行副作用代碼。

useEffect(() => {
  console.log('count:', count)
}, [count]) // 指定count為依賴項

這種方式適用於只需要根據指定的state或prop變化來執行副作用代碼的場景。

3. 指定所有依賴項

當useEffect的依賴項為所有state或prop時,每次任意一個state或prop發生變化時,useEffect都會執行副作用代碼。在依賴項比較多的情況下,這種方式會造成性能問題,應當慎用。

useEffect(() => {
  console.log('effect:', count, size)
}, [count, size]) // 指定所有依賴項

四、控制依賴項出錯的問題

雖然指定依賴項可以避免掉無用執行的問題,但是如果指定的依賴項不全、不正確的話,依然會帶來錯誤和性能問題。

繼續看一個例子:一個定時器函數組件,每1秒鐘計數器+1,然後在useEffect中輸出計數器的值。當props.count發生變化的時候,就會清空計數器。

import React, { useState, useEffect } from 'react';

function Timer(props) {
const { count } = props;
const [num, setNum] = useState(0);
let timer = null;

useEffect(() => {
startTimer();
return () => clearInterval(timer);
}, []);

useEffect(() => {
console.log('num:', num);
if (count !== 0) {
setNum(0);
}
}, [count]);

function startTimer() {
timer = setInterval(() => {
setNum(num => num + 1);
}, 1000);
}

return (

num: {num}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/312650.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2025-01-06 09:47
下一篇 2025-01-06 09:47

相關推薦

  • @uiw/react-amap介紹

    本文將詳細闡述@uiw/react-amap的使用方法和參數配置,以及如何在React應用中集成高德地圖組件。 一、@uiw/react-amap簡介 @uiw/react-ama…

    編程 2025-04-29
  • ArcGIS更改標註位置為中心的方法

    本篇文章將從多個方面詳細闡述如何在ArcGIS中更改標註位置為中心。讓我們一步步來看。 一、禁止標註智能調整 在ArcMap中設置標註智能調整可以自動將標註位置調整到最佳顯示位置。…

    編程 2025-04-29
  • CPU爆滿怎麼解決 Java為中心

    在Java編程中,難免會遇到CPU佔用過高的情況,接下來從多個方面介紹如何解決CPU爆滿問題。 一、優化代碼 1、減少循環次數。循環體內不要放太多邏輯判斷和計算,可以把計算提取出來…

    編程 2025-04-29
  • CMD如何升級為中心?

    本文將詳細介紹在Windows操作系統下如何將CMD升級為中心,以及如何在升級後使用CMD中心進行操作。 一、下載Windows Terminal Windows Terminal…

    編程 2025-04-29
  • 如何使用GPU加速運行Python程序——以CSDN為中心

    GPU的強大性能是眾所周知的。而隨着深度學習和機器學習的發展,越來越多的Python開發者將GPU應用於深度學習模型的訓練過程中,提高了模型訓練效率。在本文中,我們將介紹如何使用G…

    編程 2025-04-29
  • 如何修改ant組件的動效為中心

    當我們使用Ant Design時,其默認的組件動效可能不一定符合我們的需求,這時我們需要修改Ant Design組件動效,使其更加符合我們的UI設計。本文將從多個方面詳細闡述如何修…

    編程 2025-04-29
  • 黑夜不迷途打一中藥名為中心

    中藥作為中華民族獨有的藥物療法,已經歷了千百年的歷史,在中醫中發揮着重要的作用。其中有一種藥物,以「黑夜不迷途」為謎底,是一種著名的中藥。下面將從藥物的組成、功效、用法等方面,進行…

    編程 2025-04-29
  • Python作為中心語言,在編程中取代C語言的優勢和挑戰

    Python一直以其簡單易懂的語法和高效的編碼環境而著名。然而,它最近的發展趨勢表明Python的使用範圍已經從腳本語言擴展到了從Web應用到機器學習等廣泛的開發領域。與此同時,C…

    編程 2025-04-28
  • 為什麼要除為中心進行平均分組

    平均分組是指將數據分為若干組,使得每組的數據之和儘可能相等,這樣可以更好地控制數據波動,減少誤差。然而,為什麼要除為中心進行平均分組呢?本文將從多個方面進行闡述。 一、分組方式的影…

    編程 2025-04-28
  • 全能編程開發工程師-以keysuper為中心

    keysuper,是一款能夠實現各種編程語言的關鍵字補全和智能選單功能的插件,它的便利性在開發中發揮了越來越大的作用。以下是本文將為您詳細介紹的內容: 一、keysuper為何具有…

    編程 2025-04-28

發表回復

登錄後才能評論