文章目錄
- 前言
- 一 useRef 的核心原理
- 1.1 為什么需要 useRef?
- 1.2 基本語法
- 二、React 19 中 useRef 的常見用法
- 2.1 訪問 DOM 元素
- 2.2 保存跨渲染的數據
- 三、React 19 中的改進
- ref 作為一個屬性
- 案例演示(觸發子組件焦點事件)
- 注意
- 總結
前言
在 React 的世界里,useRef
是一個既簡單又強大的 Hook,它常常被用于訪問 DOM 元素、保存不可變數據或管理組件的生命周期行為。隨著 React 19 的發布,useRef
的使用場景和最佳實踐也得到了進一步強化。本文將結合 React 19 的特性,深入探討 useRef
的核心用法、常見誤區以及實戰技巧。
一 useRef 的核心原理
useRef
是 React 提供的一個內置 Hook,用于創建一個可變的 ref
對象。其返回值是一個包含 current
屬性的對象,該屬性在整個組件的生命周期中保持不變。
1.1 為什么需要 useRef?
- 訪問 DOM 元素:在函數組件中,
useRef
是獲取 DOM 節點的標準方式。 - 保存跨渲染的數據:
useRef
的current
屬性不會因組件的重新渲染而改變,適合存儲不需要觸發重渲染的數據。 - 管理副作用:結合
useEffect
,useRef
可以用于控制副作用的執行時機。
1.2 基本語法
import { useRef } from 'react';function MyComponent() {const myRef = useRef(initialValue);// 使用 myRef.current 訪問或修改值return <div ref={myRef}>Hello, World!</div>;}
二、React 19 中 useRef 的常見用法
2.1 訪問 DOM 元素
這是 useRef
最經典的用法。通過將 ref
屬性綁定到 DOM 元素上,可以直接操作該元素。
示例:聚焦輸入框
import { useRef } from 'react';function FocusInput() {const inputRef = useRef(null);const handleFocus = () => {inputRef.current?.focus();};return (<div><input ref={inputRef} type="text" placeholder="Type something..." /><button onClick={handleFocus}>Focus Input</button></div>);}
2.2 保存跨渲染的數據
useRef
的 current
屬性不會因組件的重新渲染而改變,因此可以用來存儲一些不需要觸發重渲染的數據,比如計時器 ID 或事件監聽器。
示例:記錄按鈕點擊次數
import { useRef } from 'react';function ClickCounter() {const clickCountRef = useRef(0);const handleClick = () => {clickCountRef.current += 1;console.log(`Button clicked ${clickCountRef.current} times`);};return <button onClick={handleClick}>Click Me</button>;}
三、React 19 中的改進
之前我們在18版本的時候你要傳遞ref給外部,需要借助forwardRef,現在到了react 19不需要了,你直接以屬性的方式進行傳遞。
ref 作為一個屬性
從 React 19 開始,你現在可以在函數組件中將 ref
作為 prop 進行訪問:
function MyInput({placeholder, ref}) {return <input placeholder={placeholder} ref={ref} />
}//...<MyInput ref={ref} />
新的函數組件將不再需要 forwardRef
,我們將發布一個 codemod 來自動更新你的組件以使用新的 ref
prop。在未來的版本中,我們將棄用并移除 forwardRef
。
案例演示(觸發子組件焦點事件)
import { useRef } from "react";
const Child = ({ ref }: { ref: React.Ref<HTMLInputElement> }) => {return (<div><input type="text" ref={ref} /></div>);
};
const App = () => {const childRef = useRef<HTMLInputElement>(null);const handler = () => {childRef.current?.focus();};return (<div><button onClick={() => handler()}>點擊</button><Child ref={childRef} /></div>);
};export default App;
注意
- 在類組件中,
ref
不作為 props 傳遞,因為它們引用的是組件實例。這意味著,如果你在類組件中需要訪問ref
,你需要使用React.forwardRef
或者React.createRef
。 - useRef的值不能作為useEffect等其他hooks的依賴項,因為它并不是一個響應式狀態
- 組件在重新渲染的時候,useRef的值不會被重新初始化。
總結
useRef 是 React 中一個簡單卻強大的 Hook,它在 React 19 中依然保持著其核心價值。通過掌握 useRef 的基本用法、高級技巧以及最佳實踐,你可以更高效地開發 React 應用,避免常見的性能問題和代碼混亂。