😩这次遇到一个需求,要求页面上垂直并列的三个表格,滚动其中一个,另外两个也能跟着一起滚动。
项目使用的是antd table,table组件没有暴露onScroll接口,也不能直接使用ref(好像最近有修复,但还没有release)。
废话不多说,直接上粗暴实现方法
const Table: React.FC = (p) => {
const { metaData, rawData } = p;
const numTable = Object.keys(metaData).length;
const [elRefs, setElRefs] = React.useState([]); //用一个list来包所有的ref
React.useEffect(() => {
// add or remove refs
setElRefs(elRefs => (
Array(numTable).fill(undefined).map((_, i) => elRefs[i] || createRef())
)); //根据生成表格的数量来生成refs
}, [numTable]);
// 主要逻辑代码,很粗糙直接,但也能应付产品,如果有更好的改进方法,请不吝赐教
const handleOnScrollCapture = (e, index) => {
if (elRefs[index]?.current) {
const scrolledTable = elRefs[index]?.current.querySelector(".ant-table-body");
elRefs.forEach((el, i) => {
if (i !== index) {
const otherTable = el.current.querySelector(".ant-table-body");
otherTable.scrollTop = scrolledTable.scrollTop;
otherTable.scrollLeft = scrolledTable.scrollLeft;
}
})
}
}
//没啥好说的,就是一个动态渲染多个表格,因为antd table不能直接加ref,就又包了一层div
const render = Object.keys(metaData).map((key, index) => {
if (metaData[key].length > 0) {
return (
<div
key={index}
ref={elRefs[index]}
onScrollCapture={(e) => handleOnScrollCapture(e, index)}
>
<Table
...省略了啊
/>
</div>
);
}
});
return <div>{render}</div>;
};
因为otherTable.scrollTop = scrolledTable.scrollTop;
语句本身就是对dom进行操作,已经是指令式操作,所以就没有用声明式写法。