簡體   English   中英

每次渲染時都將不同的 function 傳遞給 useEffect? - ReactJS 使用效果

[英]Different function gets passed to useEffect on every render? - ReactJS useEffect

我正在瀏覽 reactjs 文檔中的useEffect ,我在這里找到了這個聲明

經驗豐富的 JavaScript 開發人員可能會注意到,傳遞給 useEffect 的 function 在每次渲染時都會有所不同。

我們將 function 傳遞給 useEffect ,據說這個 function 對於每個渲染都是不同的。 useEffect 可以訪問 state 和道具,因為它位於 function 組件內,當其中任何一個更改時,我們可以看到 ZC1C425268E68385D1AB5074C17A94F14E 的更改。 這不清楚,因為在下一行文檔中

這是故意的。 事實上,這讓我們可以從效果內部讀取計數值,而不必擔心它會過時。

為了解決這個問題,假設我們有一個 function

function foo(n) {
    bar = () => {
        setTimeout(() => console.log({n}), 50);
        return n;
    }
    setTimeout(() => {n = 10}, 0);
    setTimeout(() => {n = 20}, 100);
    setTimeout(() => {n = 30}, 150);
    return bar;
}

baz = foo(1);
baz(); //prints 10
setTimeout(baz, 300); //prints 30

似乎當閉包值(n)發生變化時,我們可以看到 setTimeout 的回調發生了變化(並且這個回調不會隨着時間而改變)。 那么,useEffect 的 function 中的封閉值(狀態/道具)如何變得過時,如文檔中所述?

我在這里錯過了什么嗎? 我認為與 React 相比,它更像是一個 JS 問題,所以我舉了一個 JS 示例。

幾天前我找到了答案,正如上面評論中提到的@apokryfos (再次感謝你)。 程序執行過程現在變得更有意義了。 我想在這里總結一下我的學習。

首先,我考慮的代碼與React doc 語句的比較(用@apokryfos的話)不同,這是真的。 In case of static HTML + vanilla JS where the HTML button has an event-listener JS function, this function is declared only once and when the event occurs the same JS function is executed everytime.

我在問題中給出的代碼與此類似,因此在控制台或事件偵聽器中執行時只會聲明一次。

React (或任何基於 state 的 UI 庫/框架)的情況下,HTML 不是 static,它需要在狀態更改時更改 在執行方面(考慮React ),當我們調用它時(在JSX中)將創建組件,並且組件的函數/類將完全從上到下執行。 這表示

  • 從所有不處理state的事件處理程序、常量到useState 的被破壞元素useEffect的回調函數,一切都重新初始化。

  • 如果父級的 state 更改啟動其子級的渲染(在正常情況下),則子級將需要使用新道具和/或新 state 完全重新渲染自己以顯示更新的 UI

  • 考慮 React 文檔(鏈接)中的示例,在每次渲染后都會執行沒有依賴關系的useEffect ,這里它通過顯示當前的 state 值來更新 DOM。 除非回調 function 具有該 state 的最新值,否則它只會打印陳舊值。 所以在這里重新初始化函數是回調函數中沒有陳舊值的主要原因

     function Example() { const [count, setCount] = useState(0); useEffect(() => { document.title = 'You clicked ${count} times'; }); }

這有時是一種恩惠,也是一種詛咒。 假設如果我們將 useState 的setState function發送給孩子,並且在孩子中,我們有一個useEffect (進行網絡調用以獲取數據),它將這個 function 作為其依賴項。 現在,對於父項中的每個 state 更改,即使是否存在用例,useEffect 也會被觸發,因為此 function 依賴項發生更改(因為每次更新都會重新初始化函數)。 為了避免這種情況,我們可以在我們想要記住的函數上使用useCallback ,並且僅在某些參數發生更改時才更改,但不建議在useEffect的回調 function 上使用它,因為我們可能會以陳舊的值結束。

延伸閱讀:

  1. GeeksForGeeks 使用回調
  2. useEffect的源碼解釋
  3. useEffect的另一種SourceCode解釋

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM