跳转至

title: [ISSUE-0010] 拖动表格列宽后被自动重置 description: "字段拖动宽度会被自动重置" tags: [issue] created: 2026-05-26 updated: 2026-05-26 type: issue status: fixed severity: medium


[ISSUE-0010] 拖动表格列宽后被自动重置

相关源码src/sections/page/local-table.tsx

用户感知的现象

"字段拖动宽度会被自动重置"

用户拖动表格列宽 → 松手时变化生效 → 但数据 fetch / 刷新后列宽又回到默认值。

根因分析

实际查源码发现有 2 个 bug:

Bug 1:stale closure(use-table-columns-config.tsx:21

const updateWidth = (field, width) => {
  setColumnsWidth({ ...columnsWidth, [field]: width });  // closure 旧值
};

闭包捕获的是上一次 render 的 columnsWidth。React 18 自动 batch 下,连续拖动用旧值覆盖前一次写入,部分宽度会丢。

Bug 2:columns 数组引用每次 render 都变(client-data-table.tsx:131

const renderColumns = () => { ... return newColumns; };
// 调用处
<DataGridPremium columns={renderColumns()} ... />

每次 render 返回新数组 → DataGridPremium 看到 columns prop 引用变化 → 内部 width state 重置 → 用户拖动后下次 render 就回到 columns prop 里写的值(这个值是 closure 旧值,所以又错)。

两个 bug 互相放大,结果就是「拖完立即被重置」。

修复方案

// 1. useTableColumnsConfig.tsx — functional setState 修 closure
const updateWidth = (field, width) => {
  setColumnsWidth((prev) => ({ ...(prev || {}), [field]: width }));
};

// 2. client-data-table.tsx — useMemo 缓存 columns 引用
const memoColumns = useMemo(() => { ... }, [columnsList, columnsWidth, defaultColumns]);
const renderColumns = () => memoColumns;

改动文件

文件 改了什么
src/hooks/cache/use-table-columns-config.tsx updateWidth 改 functional setState
src/components/table/client-data-table.tsx renderColumns 用 useMemo 缓存

验证方式

  1. 拖动「商家」列宽 → 100px
  2. 切换 chip 触发刷新 → 列宽应保持 100px
  3. 关闭主面板再打开 → 列宽应仍 100px
  4. 测多个列同时调

如何避免再犯

  • 任何"用户调整的 UI 状态"必须持久化(列宽 / 排序 / 折叠 / 选项)
  • 数据 fetch 时不要重置 UI state,只 setState data 而不 setColumns

相关问题