Ant Design Table传入新列值时未触发重渲染问题求助
Ant Design Table列重排后不触发重渲染问题
问题表现
开发表格列按需重排功能时,点击列顺序调整按钮后,绑定的列配置状态orderedColumn的JSON序列化值已经同步更新,但Ant Design Table组件的列展示顺序没有同步变化。
问题核心代码
export default ({ columnOrder, data }: IProps) => { const [orderedColumn, setOrderedColumn] = useState<ColumnsType<ISomeTableColumns>>(columns); useEffect(() => { console.log('columnOrder', columnOrder); const sortArray = columns.sort((a, b) => { return ( columnOrder.findIndex((x) => x.text === a.title) - columnOrder.findIndex((x) => x.text === b.title) ); }); if (sortArray) { setOrderedColumn(sortArray); } }, [columnOrder]); return <> <Table columns={orderedColumn} dataSource={data} bordered size="middle" scroll={{ x: 'calc(700px + 50%)' }} /> <h2>Value Of ordered Columns</h2> <div>{JSON.stringify(orderedColumn)}</div> </> };
问题根因
Array.prototype.sort()是原地排序方法,会直接修改原数组本身,返回值就是原数组的引用。代码中直接对外部定义的columns原数组调用sort,没有生成新的数组引用。- React状态更新、Ant Design Table内部的props变更检测都依赖浅比较逻辑:由于排序后得到的
sortArray和原columns是同一个内存引用,浅比较会判定props没有发生变化,不会触发Table组件的列重渲染。 - 代码中
if (sortArray)判断属于无效逻辑:sort方法永远返回数组对象,不存在返回falsy值的场景。
修复方案
排序前先对原列配置数组做浅拷贝,生成全新的数组引用后再执行排序操作,保证每次传入状态的列配置都是新的引用,能被浅比较逻辑正确识别到变更。
修正后代码如下:
export default ({ columnOrder, data }: IProps) => { const [orderedColumn, setOrderedColumn] = useState<ColumnsType<ISomeTableColumns>>(columns); useEffect(() => { console.log('columnOrder', columnOrder); // 先通过展开运算符浅拷贝原数组,生成新引用后再排序 const sortArray = [...columns].sort((a, b) => { return ( columnOrder.findIndex((x) => x.text === a.title) - columnOrder.findIndex((x) => x.text === b.title) ); }); setOrderedColumn(sortArray); }, [columnOrder]); return <> <Table columns={orderedColumn} dataSource={data} bordered size="middle" scroll={{ x: 'calc(700px + 50%)' }} /> <h2>Value Of ordered Columns</h2> <div>{JSON.stringify(orderedColumn)}</div> </> };
如果后续需要动态修改列的内部属性(比如列宽、固定状态等),建议根据实际需求对列配置做深拷贝,避免嵌套对象引用一致导致的更新不触发问题。
内容的提问来源于stack exchange,提问作者LuxuryWaffles
相关产品推荐
相关产品推荐

