Theo 本週製作了一個關於React hooks 不直觀行為的視頻,特別探索了一個名為usePrevious 的hook 的想法,以在當前渲染之前保留上次重新渲染的值版本一。一種對新舊狀態進行邏輯處理的方法。
如果您想了解如何實現它的想法,請查看視頻,在這篇文章中,我們的想法是探索像 usePrevious 這樣的鉤子的概念方面。
如你所見,我們在 React 中沒有這樣的原始鉤子。在 hooks 之前,在基於類別的時代,我們有一個名為 componentDidUpdate 的生命週期方法,我們將之前的所有狀態和 props 作為參數,為什麼他們不使用 hooks 來保留這種行為?
如果您正在閱讀本系列文章,可能會有點重複,但在這種情況下,我們需要討論範式轉移。
對於類,當某些狀態更新時,您沒有自動重新計算派生值的方法。如果你正在使用一些特定的 props 和 state 來計算一些新的值,你需要自己驗證其中一些是否發生了變化。
這樣,解決方案是在所有更新中呼叫回調,並將先前的值傳送給使用者。應用程式程式碼檢查差異並使用新結果更新計算狀態。這就是基於類別的元件的直接性,你完全控制資料的流向,並且需要手動控制計算。
我們來看看反應表達式。
您不必檢查並進行更改,而是編寫一個表達式、計算公式之類的。此計算需要使用目前狀態版本執行,而無需存取前一個狀態。
想像一個公式:
a = b + c b = 10 c = 20 a = 10 + 20 a = 30
如果我使用這個表達式 100 萬次,將 b 作為 10 傳遞,將 c 作為 20 傳遞,我將得到相同的結果。這是純粹的計算。 React 執行相同的原理。所有推導的計算都應該是純粹的。
但是為什麼它很重要?
在重新渲染中做出反應。每個週期都會產生 UI 的描述,並根據當前和下一週期之間的差異,將變更提交到 DOM。每個渲染都與上一個或下一個完全分離。
UI = fn(state)
因此,對於每個不同的狀態版本,我們都有不同的 UI 版本。如果我們在這裡添加以前的值,這會變得非常混亂。因為現在它不僅取決於狀態,還取決於之前的狀態。我可以擁有多個來源,也許更複雜的表達式來處理這些來源,並且結果是不一致且不可預測的 UI,而不是只有一個來源、一個表達式和一個結果。
每個渲染都會根據先前的狀態表現不同。由於 usePrevious 的一些可能實作依賴於 React 中的時間順序,這變得更加危險。
借助並發功能,React 可以在不警告渲染的情況下停止,以優先考慮其他操作。根據 useEffect 和 ref 可以讓您保留「上一個」渲染的過時版本,甚至是真正的上一個渲染。更多混亂需要推理。
用這樣的表達方式思考
a = b + c b = 10 c = 20 a = 10 + 20 a = 30
其中一部分是優先順序的,需要先計算一下,我們用javascript程式碼來思考一下:
UI = fn(state)
所以現在我們有兩個獨立的表達式,可以單獨計算,而且是完全純淨的。但如果b的值變化很大,cdResult的計算成本很高,我們該如何解決呢?牢牢記住!
a = b + (c - d)
現在如果 c 或 d 發生變化,cdResult 將被重新計算。
但是在上面的文字中我說沒有先前的值,但是一個渲染的計算如何可以在下一個渲染中使用?這不會破壞計算的純粹性嗎?
事實上,沒有。例如:
const cdResult = c - d; const a = b + cdResult;
假設我們處於渲染編號 1 中。 c 的值為 30,d 的值為 20,因此結果是 10。但是當我記住它時,React 將追蹤我添加的依賴項數組。如果其中一些發生變化,則會重新計算。
const cdResult = React.useMemo(() => c - d, [c, d]); const a = b + cdResult;
但他們沒有改變。如果我再次呼叫這個表達式,c 為 30,d 為 20,我將得到相同的 10 作為結果。即使我處於渲染編號 2 中且其他變數發生了變化,但我在本次計算中使用的依賴項並沒有改變。
我可以在每次渲染中再次計算它,這是React的預設行為,但我可以選擇跳過不必要的重新計算,這將返回相同的值,所以我保留了它。我們保持了純度並保持了渲染之間的分離
但是有一個很好的地方可以對先前的狀態、使用者操作進行邏輯處理。當然,在呼叫回調的那一刻,這將是當前狀態。但如果你有一些狀態需要根據某種邏輯進行更改,那就是這個地方。
當然,它可能有非常特殊的情況,您可能需要一個鉤子,例如 usePrevious,但要注意它可能導致的不一致,並嘗試添加保證以避免應用程式上的錯誤。
更重要的是,如果可能的話,避免它。
以上是usePrevious 和類似的面向時間的鉤子的問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!