如何在 React 中正确地使用 useRef 获取动态生成的多个子组件的 DOM 引用?
如何在 React 中正确地使用 useRef 获取动态生成的多个子组件的 DOM 引用?
在 React 中,若需为动态生成的多个子组件分别获取其 DOM 引用,不能直接将同一个 useRef 对象赋给多个元素,而应使用一个 Ref 数组或 Map 来管理多个引用。
正确做法如下:
import { useRef, useEffect } from 'react';
function MyComponent({ items }) {
const itemRefs = useRef([]);
// 确保数组长度与 items 一致,并为每个元素创建 ref
useEffect(() => {
itemRefs.current = itemRefs.current.slice(0, items.length);
}, [items.length]);
const focusItem = (index) => {
itemRefs.current[index]?.focus();
};
return (
<div>
{items.map((item, index) => (
<input
key={item.id}
ref={(el) => (itemRefs.current[index] = el)}
defaultValue={item.value}
/>
))}
<button onClick={() => focusItem(0)}>聚焦第一个输入框</button>
</div>
);
}
解析:
- useRef 返回一个可变的 ref 对象,其 .current 属性可被直接赋值。
- 对于动态列表,应使用 ref 回调函数(ref={el => refArray[index] = el})而非直接将 useRef() 赋给多个元素,否则所有元素会共享同一个引用。
- 需在 useEffect 中同步 ref 数组长度,防止因列表缩短导致访问已删除元素的引用。
- 此方法适用于函数组件;若使用类组件,可使用 createRef() 配合数组管理。
注意:避免在渲染过程中直接操作 ref 数组(如 push/pop),应在 useEffect 或事件处理函数中操作,以符合 React 的响应式原则。

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