跳至主要内容

useRef:掌握 React 的「儲物櫃」與 DOM 操控

什麼是 useRef?

useRef 回傳一個帶有 current 屬性的物件。它有兩個最主要的用途:

  1. 存取 DOM 元素:直接抓取網頁上的 HTML 標籤(例如讓輸入框聚焦)。
  2. 儲存「不需要渲染」的資料:存放在裡面的資料改變時,不會觸發組件重新渲染。

核心觀念:

  • 如果您希望改了某個值,畫面要跟著變,請用 useState
  • 如果您只是想偷偷記住一個值,或是要直接控制 HTML 標籤,請用 useRef

語法拆解

const myRef = useRef(initialValue);

// 取值或改值
console.log(myRef.current);
myRef.current = "新資料";

您可以把 useRef 想像成一個**「掛在組件身上的儲物櫃」**。

1. 為什麼是 .current

當您執行 const myRef = useRef(0); 時,React 實際上是幫您建立了一個像這樣的物件:

{
current: 0 // 這是您傳進去的 initialValue
}

為什麼非要包成物件?因為在 JavaScript 中,物件是傳址(Pass by Reference)。這能保證 React 在多次重新渲染組件時,手上拿到的始終是同一個「儲物櫃」,所以裡面的 current 才能一直保存著。

2. 取值與修改

  • 取值myRef.current (單純讀取,不會觸發渲染)
  • 改值myRef.current = "新資料" (靜悄悄地換掉內容,React 不會被驚動)

使用 useRef 的常見情境

  • 管理焦點、文字選取或媒體播放
  • 整合第三方 DOM 函式庫 (如 D3.js 或 jQuery)
  • 儲存「前一個狀態」 (Previous State)

範例:直接操控 DOM

我們常希望使用者點開頁面時,游標自動停在「訂單編號」輸入框。 codepen 範例

const { useState, useEffect, useRef } = React;

function OrderSystem() {
const [orderId, setOrderId] = useState("");
const inputRef = useRef(null);

useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, []);

return (
<div style={{ padding: '20px' }}>
<h2>ERP 訂單系統</h2>
<label>訂單編號:</label>
<input
ref={inputRef}
type="text"
value={orderId}
onChange={(e) => setOrderId(e.target.value)}
placeholder="例如:2026021001"
/>
<button onClick={() => alert(`正處理訂單:${orderId}`)}>處理訂單</button>
</div>
);
}

範例:儲存不觸發渲染的變數

假設您要記錄使用者「點擊了幾次按鈕」,但不希望每次點擊都重新渲染。 codepen 範例

const { useState, useRef } = React;

function SilentCounter() {
const countRef = useRef(0);
const [renderCount, setRenderCount] = useState(0);

const handleClick = () => {
countRef.current += 1;
console.log("偷偷記錄點擊次數:", countRef.current);
};

return (
<div style={{ padding: '20px', border: '1px solid #ccc' }}>
<h3>useRef:偷偷計數 (Console)</h3>
<button onClick={handleClick}>點擊 (不更新畫面)</button>
<button onClick={() => setRenderCount(renderCount + 1)}>
更新畫面 (目前渲染第 {renderCount})
</button>
</div>
);
}

useRef vs useState

特性useStateuseRef
改變值時觸發渲染
非同步更新否 (立即生效)
用途驅動畫面的資料存取 DOM 或私有變數