接下來幾篇文章將會針對 React 常見的 Hooks 的使用目的與場景 ,內容主要都是透過官方文件、一些大師影片以及自身開發經驗彙整出來的,如果有很不錯的學習資源我也會在文末留下來源供大家參考喔!
首篇就來一個最近開發中很常使用到的 useRef

認識一下吧 useRef
先讓我們來看看 React 官方文件的 useRef 定義:
useRefis a React Hook that lets you reference a value that’s not needed for rendering.
簡單來說有與 state 相似的功能都是暫存值,但最大的不同就是 useRef 裡的 ref object 就算變動了也不會造成畫面的 re-render,是完全隔絕於 component life cycle 外的狀態。
useRef 實用場景
1. Referencing a value with a ref(使用 ref 對照值)
這是 useRef 最基本的用法。可以用它來創建一個「可變」的 ref object,object 的 .current 屬性被初始化為傳遞給 useRef() 的參數,在後續的 re-render 中,useRef 將返回相同的 object。而且這個 object 可以更改其 current 屬性以存儲為新的值,就算值更新了也不會讓整個畫面  re-render。
接著舉兩個常見的使用案例:
🔎 ex1. 存取最新的值
若我們想要在若干秒數後取得某一個狀態的最新值,useRef 就可以派上用場了!!
1  | const [timeoutCount, setTimeoutCount] = useState(0);  | 
這邊為什麼使用 ref.current 存值,而不是用 state?
因為當 setTimeout 被建立時,它使用的是當時 count 的值,它依賴一個閉包(closure)來異步訪問 count。因此當組件重新渲染時,一個新的閉包會被創建,但這不會改變最初被封閉的值,所以如果用了 state,當 5 秒後你以為 count 已經變更了拿出來用,會發現該 state 還是初始的 0。
這就是 useRef 的一個實用情景可以避免上述的情形發生,我們透過將狀態值與 ref 的 current 屬性同步,並在 timeout 中讀取 current以取得我們想要的值。
🔎 ex2. 存取「前一個值」
呈上,我們當然也可以拿來存取前一個值。
1  | const [name, setName] = useState('');  | 
2. Manipulating the DOM with a ref(使用 ref 操作 DOM )
在 React 中我們可以使用 useRef 來直接操作 DOM 元素。通過將 ref 對象的 .current 屬性設置為一個 DOM 節點,可以直接讀取或修改這個節點。
🔎 ex1. 取用某一個 DOM 作進一步操作
最簡單常用的使用情境包含列印、操作特定的 DOM Scroll to view、監聽無限滾動的最後一個元素等等,這邊舉列印為例:
1  | const printRef = useRef<HTMLDivElement>(null);  | 
🔎 ex2. 父組件使用 useRef 調用子組件的方法
在 react 的父子層的關係,父層若要呼叫存在子層的函式通常會將函式放置在父層,並且將函式與相關的狀態一起傳入子層中做使用。也是之前分享過的文章【圖解】React 常見的父子傳值方法 Props(https://leewanhsuan.github.io/2022/04/25/01-props/)所提過的方法。
而下方改成以 useRef 的方式實踐,這段範例中使用 React.forwardRef 和 React.useImperativeHandle 來從父組件調用子組件的方法,這樣可以把方法保留在子層中,卻又能在父層中調用。
1  | import React, { useRef, useEffect } from 'react';  | 
3. Avoiding recreating the ref contents(避免不必要的重建 ref 內容)
使用 useRef 可以幫助你避免在重新渲染 component 時不必要地重建 ref 的內容,因為 ref 會在 re-render 中保持不變,例如一些資源很大的影音 component 就可以使用此方法,避免重複拿取資源、更新畫面。
1  | const Video = () => {  | 
以上就是 useRef 官方提供的三種使用情境以及對應的範例,在整理的過程中也讓我更加認識 useRef 了,希望也能幫助到你唷!
最後,請注意 useRef 使用事項
Web Dev Simplified 的講者在其 useRef 教學影片中特別強調,雖然 useRef 有多種用途,但它並不應該過度取代 useState。特別是在處理用戶交互,如值的更改(onChange Value)時,過度依賴 useRef 可能會讓程式碼變得過於複雜。也可能讓你失去 React Hook 的渲染生命週期(re-render life cycle)所帶來的優勢。
💬 參考資料: