如何在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} /> </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
相关产品推荐
相关产品推荐

