iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
JavaScript

React 觀念架構:從js 基礎到Hook 底層邏輯 系列 第 19 篇

Day 19 useRef 雙重用途:DOM 操作與跨 Render 狀態快照

  • 分享至 

  • xImage
  •  

今天我們要介紹 React 中看似簡單、實則極具彈性的 Hook:useRef。

很多初學者把 useRef 當成單純「抓取 DOM 元素」的工具,但它真正的底層本質是一個「在組件整個生命週期中持續存在、且變更時『不會』觸發 Re-render 的通用容器」。

一、 useRef 的底層本質:一個穩定的 JS 物件

useRef(initialValue) 呼叫後,會回傳一個結構如下的 Plain JS Object:

{ current: initialValue }

兩大關鍵特性:

  1. 參考穩定性 (Reference Stability):每次組件 Re-render,useRef 回傳的物件永遠指向同一個記憶體位址。

  2. 無聲變更 (Silent Mutation):手動修改 ref.current = newValue 時,完全不會觸發組件重新渲染 (No Re-render)。

二、 真實 DOM 節點控制 (DOM Node Access)

這是 useRef 最常見的用途。在 React 聲明式 UI 架構下,當我們需要進行瀏覽器原生操作(如 Focus、捲動、測量尺寸)時,必須透過 ref 取得 DOM:

import { useRef } from 'react';

function SearchBox() {
  const inputRef = useRef(null);

  const handleFocus = () => {
    // 透過 .current 存取真實 DOM 並呼叫原生 API
    inputRef.current?.focus();
  };

  return (
    <div>
      <input ref={inputRef} type="text" placeholder="搜尋..." />
      <button onClick={handleFocus}>聚焦輸入框</button>
    </div>
  );
}

三、 跨 Render 的「盒外」數據快照 (State-like Storage)

有些數據我們需要跨 Render 保存,但數據的變更並不需要反映在畫面上。如果將這些數據放在 useState 中,每次更新都會引發不必要的 Re-render;這時就是 useRef 大顯身手的時刻!

常見情境:

  • 保存 Timer ID(如 setInterval / setTimeout)

  • 記錄舊的 State 快照(比對 Previews State)

  • 計數器 / 防手震狀態 Flag(如防止重複發送 API 的 isSubmitting 旗標)

import { useState, useRef } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);
  // 使用 useRef 存放計時器 ID,避免觸發 Re-render
  const timerIdRef = useRef(null);

  const startTimer = () => {
    if (timerIdRef.current !== null) return;
    
    timerIdRef.current = setInterval(() => {
      setSeconds(prev => prev + 1);
    }, 1000);
  };

  const stopTimer = () => {
    clearInterval(timerIdRef.current);
    timerIdRef.current = null; // 清空 Ref
  };

  return (
    <div>
      <p>秒數:{seconds}</p>
      <button onClick={startTimer}>開始</button>
      <button onClick={stopTimer}>停止</button>
    </div>
  );
}

四、 useState vs. useRef vs. 普通變數 (Plain Variable)

https://ithelp.ithome.com.tw/upload/images/20261003/20178516JknajLWVRl.png


上一篇
Day 18 useMemo 與 useCallback:打破「盲目優化」的效能迷思
系列文
React 觀念架構:從js 基礎到Hook 底層邏輯 共 19 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言