You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React中通过refs获取多个元素并实现遍历?

修复React Refs获取多个元素的问题

这个问题很典型——你现在的写法之所以失效,是因为单个React.createRef()创建的ref对象只能绑定到一个元素上,当你把它赋值给多个<span>时,每个元素挂载都会覆盖this.tabs.current的值,最后只会保留最后一个元素的引用。另外还要注意,JSX里的类名应该用className而不是class,这是React的规范要求。

下面是两种符合React规范的修复方案,优先推荐第一种(完全适配你当前使用的React 15.1.0):

方案一:使用回调Ref收集多个元素(推荐)

思路是初始化一个数组来存储所有tab的引用,通过回调函数把每个元素的ref添加到数组中。这种方式是React官方推荐的多元素ref收集方案,适用于所有React版本。

修改后的完整代码:

class Comp extends React.Component {
  constructor(props) {
    super(props);
    // 初始化数组存储所有tab的refs
    this.tabs = [];
  }

  componentDidMount() {
    console.log(this.tabs); // 现在会包含三个<span>元素的引用
    // 遍历操作示例:打印每个tab的文本内容
    this.tabs.forEach(tab => {
      console.log(tab.textContent);
    });
  }

  // 可选:组件卸载时清空数组,避免内存泄漏
  componentWillUnmount() {
    this.tabs = [];
  }

  render() {
    return (
      <div>
        <span className="tab" ref={el => this.tabs.push(el)}>One</span>
        <span className="tab" ref={el => this.tabs.push(el)}>Two</span>
        <span className="tab" ref={el => this.tabs.push(el)}>Three</span>
      </div>
    );
  }
}

ReactDOM.render(
  <Comp />,
  document.getElementById('app')
);

注意事项:

  • 如果组件存在更新逻辑(比如tabs动态增减),建议在回调ref里做去重处理,避免重复添加元素:
    ref={el => {
      if (el && !this.tabs.includes(el)) {
        this.tabs.push(el);
      }
    }}
    
  • 始终用className替代class来定义JSX元素的类名,这是JSX的语法规范。

方案二:React 16.3+ 专用:使用createRef结合数组(可选)

如果你后续升级到React 16.3及以上版本,也可以预先创建多个ref对象存储在数组中,再分别绑定到元素上:

class Comp extends React.Component {
  constructor(props) {
    super(props);
    // 预先创建三个ref对象存入数组
    this.tabs = [React.createRef(), React.createRef(), React.createRef()];
  }

  componentDidMount() {
    // 通过current属性获取每个元素的引用
    console.log(this.tabs.map(ref => ref.current));
    this.tabs.forEach(ref => {
      console.log(ref.current.textContent);
    });
  }

  render() {
    return (
      <div>
        <span className="tab" ref={this.tabs[0]}>One</span>
        <span className="tab" ref={this.tabs[1]}>Two</span>
        <span className="tab" ref={this.tabs[2]}>Three</span>
      </div>
    );
  }
}

这种方式适合tabs数量固定的场景,但灵活性不如回调ref,所以更推荐方案一。

为什么不推荐document.querySelectorAll?

直接使用document.querySelectorAll会绕过React的DOM管理机制,当React重新渲染时,你获取的DOM元素可能已经过时或者被替换,容易引发不一致的问题。通过React refs管理DOM元素,能保证你拿到的始终是当前组件渲染后的最新元素引用。

内容的提问来源于stack exchange,提问作者Rami Chasygov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:39:10