如何在 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 的响应式原则。

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

昵称:
邮箱:
内容: