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

如何在React中实现同级FormattedTable组件间的滚动跳转

解决方案

你遇到的问题根源是所有动态生成的表格共用了同一个ref变量,后渲染的表格会覆盖前面对ref的赋值,导致ref始终指向最后一个表格节点,该需求完全可以在现有逻辑基础上实现,改造步骤如下:


1. 改造Home.js,存储所有表格的ref引用

首先在Home中用ref对象存储每个表格对应的DOM节点,key用每个表格的唯一标识(建议用obj的唯一id,无唯一id时可暂时用index),同时封装通用的滚动方法:

import { useRef, useState } from 'react';

const Home = () => {
  // 存储所有表格的DOM引用,key为表格唯一标识
  const tableRefs = useRef({});
  const [selected, setSelected] = useState([]);

  // 通用滚动到指定表格的方法
  const scrollToTable = (targetKey) => {
    const targetDom = tableRefs.current[targetKey];
    if (targetDom) {
      // 支持平滑滚动,可根据需要调整参数
      targetDom.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
  };

  return (
    <div className="rightColumn" style={{flex: 4}}>
      {selected.length > 0 ? selected.map((obj, index) => {
        // 优先用obj的唯一id作为key,没有的话用index
        const tableKey = obj.id ?? index;
        return (
          <div 
            ref={(el) => (tableRefs.current[tableKey] = el)} 
            key={tableKey}
            style={{width: '60%'}}
          >
            <FormattedTable 
              data={data} 
              selected={selected} 
              obj={obj} 
              index={index} 
              onSelectedChange={setSelected} 
              triggerScroll={scrollToTable}
              // 把当前表格的key也传入,方便后续逻辑判断
              currentTableKey={tableKey}
            />
            &nbsp;
          </div>
        )
      })
      : null} 
    </div>
  )
}

2. 在FormattedTable.js中调用滚动方法

点击引用时按两种场景处理即可:

const FormattedTable = (props) => {
  const { selected, onSelectedChange, triggerScroll } = props;

  const handleRefClick = (targetTableObj) => {
    // 先判断目标表格是否已在展示列表中
    const existedIndex = selected.findIndex(item => item.id === targetTableObj.id);
    if (existedIndex > -1) {
      // 已存在,直接滚动到对应位置
      const targetKey = targetTableObj.id ?? existedIndex;
      triggerScroll(targetKey);
    } else {
      // 不存在,先添加到展示列表
      const newSelected = [...selected, targetTableObj];
      onSelectedChange(newSelected);
      // 等DOM更新完成后滚动到新增的末尾表格
      setTimeout(() => {
        const newTargetKey = targetTableObj.id ?? (newSelected.length - 1);
        triggerScroll(newTargetKey);
      }, 0);
    }
  };

  // 其余组件逻辑...
}

注意事项

如果你的selected数组支持中间插入/删除元素,不要用index作为tableKey,必须给每个obj分配唯一固定的id作为标识,避免index变化导致ref匹配错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 19:48:03