如何在 TanStack Table 中根据行状态动态显示或隐藏操作按钮

本文介绍在 react 与 tanstack table(v8+)中,如何基于每行数据的 `status` 字段条件性渲染按钮(如“agenda”),无需全局状态,直接通过 `cell.row.original` 访问当前行数据实现精准控制。

在 TanStack Table 中,每个 cell 渲染函数都可获取完整的行上下文(cell.row),其中 cell.row.original 即为该行原始数据对象。因此,判断某列按钮是否显示,不应依赖组件级状态(如 isApproved)——该状态无法反映每行独立的 status 值,反而会导致所有行行为同步,违背需求。

正确做法是在 actions 列的 cell 渲染器中,直接读取当前行的 status 字段,并使用逻辑与运算符(&&)进行条件渲染。例如,仅当 status === "Approved" 时显示 “Agenda” 链接:

{
  accessorKey: "actions",
  header: () => Action,
  cell: (cell) => {
    const row = cell.row.original;
    return (
      
        Edit
        
        {row.status === "Approved" && (
          Agenda
        )}
      
    );
  },
  enableSorting: false,
  enableColumnFilter: false,
}

⚠️ 注意事项:

  • ✅ 使用 cell.row.original.status(而非 cell.getValue()),因为 status 是独立字段,getValue()

    在 accessorKey: "actions" 列下返回 undefined;
  • ✅ 字符串匹配需严格一致(如 "Approved" vs "approve" 或 "approved"),建议统一后端返回格式,或添加 .toLowerCase() 安全处理(如 row.status?.toLowerCase() === "approved");
  • ❌ 避免在 cell 中调用 useState 或副作用(如 console.log(isApproved)),这会破坏 Table 的纯渲染特性,引发性能问题或错误;
  • ? 若需支持多状态逻辑(如 "Approved" 和 "Published" 均显示 Agenda),可改用数组包含判断:["Approved", "Published"].includes(row.status)。

总结:TanStack Table 的单元格渲染本质是函数式、按行隔离的。善用 cell.row.original 可以简洁、高效、可预测地实现行级交互逻辑,是构建动态表格操作栏的核心实践。