簡體   English   中英

useState、UseRef 或 useMemo,我應該更喜歡哪個

[英]useState, UseRef, or useMemo, what should I prefer

我有一個場景,我需要在整個組件生命周期中存儲 function 的 output(這個值永遠不會改變)。

考慮下面的例子

const UniqueIdView = () => {
    const [uniqueIdState1] = useState(() => uniqueId('prefix_'))
    const [uniqueIdState2] = useState(uniqueId('prefix_'))
    const uniqueIdRef = useRef(uniqueId('prefix_'))
    const uniqueIdMemo = useMemo(() => uniqueId('prefix_'), [])
    return (
        <div>
            {uniqueIdState1}
            {uniqueIdState2}
            {uniqueIdRef.current}
            {uniqueIdMemo}
       </div>
    )
}

上面提到的 4 種方法中哪一種是理想的?

我的理解:

useState應該用於存儲值的變化應該觸發重新渲染的值。

如果我想記住計算,應該使用useMemo ,並且 memoization 總是有相關的成本。

所以,我認為useRef是合適的。

但是,我有一個困惑:

useRef將在每次重新渲染時一次又一次地觸發我的 function,而使用帶有useState的回調方法只會觸發我的 function 一次。

但是再一次,如果我必須考慮一次又一次調用 function 的成本,我應該使用useMemo (但在這種情況下,function 並不復雜,我們是否應該增加記憶開銷)?

更新

我想達到什么目標?

我想創建一個自定義鈎子,它應該返回在重新渲染時不應該改變的uniqueId

const UniqueId = () {
    const uniqueId = useStableUniqueId('prefix__')
    return <div>{uniqueId}<div>
}

所以無論 UniqueId 重新渲染多少次,該值都不應該改變。

傳遞給useRef的值只是初始值,但如果它是 function 調用,它實際上會在每次渲染時調用。 不太確定您的問題的 rest。 每個鈎子都是為了特定目的而存在的。 選擇滿足您需求的那個。

我有一個場景,我需要在整個組件生命周期中存儲 function 的 output。

對我來說,明確的選擇是使用useMemo掛鈎來記憶可能昂貴的 function 調用的結果值。

沒有定期更新,因此useState不適合。 如果您決定將其存儲在 state 中並且需要對其進行更新,您將需要一個具有依賴關系的useEffect掛鈎並重新計算新值並調用 state 更新程序 ZC1C425268E68385D14AB5074C17A。 這本質上是useMemo鈎子。

如果您決定將其存儲在 React ref 中,那么您將再次需要將其與具有依賴關系的useEffect配對,以更新ref.current值以使其保持更新,而這又一次為您提供了useMemo鈎子。

更新

由於您確實希望優化自定義鈎子,該鈎子為組件的生命周期提供 static 唯一 ID:

  1. 使用useMemo

     const useUniqueId = (prefix = 'prefix_') => { return useMemo(() => uniqueId(prefix), []); };
  2. 使用useState

     const useUniqueId = (prefix = 'prefix_') => { const [uniqueId] = useState(() => uniqueId(prefix)); return uniqueId; };

首先簡短的回答:如果我必須決定使用哪種機制,我會 go 用於useMemo

const uniqueId = useMemo(() => getUniqueId('prefix_'), []);

它完成了我們在這里想要的所有事情: getId function 只被調用一次,因為依賴數組為空,返回值穩定,成本效益高。 useMemo沒有相關的魔法成本,計算是重還是輕量級都沒有關系。 正如德魯所說的那樣簡潔。 自定義掛鈎如下所示:

export const useUniqueId = () => {
  const uniqueId = useMemo(() => getUniqueId('prefix_'), []);
  return uniqueId;
}

更長的答案:通常,如果您想要一個不以任何方式連接到渲染周期並且在組件的生命周期內穩定的值,我會 go 用於useRef 但是useRef不像useState或 useMemo 那樣支持初始化器useMemo 我不想在每個渲染上調用getUniqueID ,因此將被迫將它與useEffect結合起來以初始化 ref。 這在這里真的有點麻煩,所以我認為useMemo在這里完成了這項工作。

const uniqueId = useRef();
useEffect(() => { uniqueId.current = getUniqueId('prefix_') }, []);

請注意,使用 useEffect 的解決方案將僅在渲染 function 運行完成后提供值,如果您立即需要 uniqueID,例如在某些元素上設置 HTML 屬性 ID,這將導致麻煩。

暫無
暫無

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

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