如何在 React 中正确地使用 useRef 钩子来访问动态生成的多个子组件的 DOM 节点?
如何在 React 中正确地使用 useRef 钩子来访问动态生成的多个子组件的 DOM 节点?
回答与解析:
在 React 中,若需要访问动态生成的多个子组件(或元素)的 DOM 节点,不能直接将同一个 useRef 对象赋给多个元素,因为 useRef 只能引用一个 DOM 节点。正确做法是使用一个 ref 数组,配合 useCallback 或自定义 ref 回调函数来动态收集每个元素的引用。
示例代码:
import { useRef, useCallback } from 'react';
function App() {
const itemRefs = useRef([]);
// 使用 useCallback 确保函数引用稳定
const setItemRef = useCallback((element, index) => {
itemRefs.current[index] = element;
}, []);
const items = ['A', 'B', 'C'];
const handleClick = (index) => {
// 聚焦对应项
itemRefs.current[index]?.focus?.();
};
return (
<div>
{items.map((item, index) => (
<input
key={index}
ref={(el) => setItemRef(el, index)}
defaultValue={item}
/>
))}
<button onClick={() => handleClick(1)}>聚焦第二项</button>
</div>
);
}
关键点解析:
- 不要直接写 ref={itemRefs[index]}:因为 itemRefs.current 是一个普通数组,不是由 useRef 创建的响应式对象,直接赋值无法在渲染时正确绑定。
- 使用回调 ref(callback ref):通过
(el) => setItemRef(el, index),每次元素挂载或卸载时会调用该函数,从而将 DOM 节点存入 ref 数组。 - useCallback 优化:避免每次渲染都创建新函数,保持 setItemRef 引用稳定,防止不必要的 ref 重置。
- 注意 key 的稳定性:动态列表应使用稳定且唯一的 key,否则 ref 可能错乱。
此方法适用于需要直接操作多个 DOM 元素(如聚焦、测量尺寸、动画等)的场景,是 React 官方推荐的处理多 ref 的方式。

发表评论 (审核通过后显示评论):