antd 组件部分API使用方法

Ant Design

Table组件: ant.design/components/...

一、Table

1.rowKey

rowKey 是Table组件的一个必选属性,用于唯一标识表格中的每一行数据。它可以是字符串也可以是一个函数。

作用

性能优化

React通过唯一key来识别组件的变化。当表格的数据更新时,Ant Design会根据rowKey来判断哪些行发生了变化,从而只重新渲染需要更新的行,而不是整个表格。这一点大大提高了渲染效率。

状态管理

在表格的各种交互场景中,像分页、排序、筛选、选择等,rowKey用于跟踪和维护每行数据的状态。 如:

  • 记住哪些行被选中(复选框/单选框)
  • 保持展开/折叠行的状态
  • 处理行内表单的状态
避免渲染错误

如果没有提供唯一的rowKey,antd会默认使用行索引(index)作为它的key,但是当数据排序、分页或删除时,索引(index)会发生变化,会导致React错误地敷用组件,从而引发渲染异常(状态丢失、DOM错位等)。

如何设置

使用数据中唯一字段

这也是最推荐的方法,即使用数据里已有的唯一ID字段:

js 复制代码
<Table 
    dataSource={data} 
    rowKey="id" 
    // 假设数据中有唯一的id字段 
    // 或使用函数形式: rowKey={record => record.id} 
/>
自定义生成rowKey

如果数据中没有合适的唯一字段,那么就可以通过组合,进行字段生成:

js 复制代码
<Table
    dataSource={data} 
    rowKey={record =>`${record.name}-${record.timestamp}`} 
    // 组合多个字段确保唯一性 
/>
唯一字段不止一个

比如有的人有身份证号,但有的人只有护照号,唯一字段不只有一个,那么就可以进行判断:

js 复制代码
<Table
    dataSource={data} 
    rowKey={record =>record?.idCard|| record?.passportId} 
    //确保两个字段不会同时存在,或者同时存在时它们的值相同
/>
注意事项
  • 必须保证唯一性:也就是同一个表格中不能有重复的rowKey值
  • 要避免使用行索引:除非页面是静态的,不会排序、分页、增删等
  • 保持稳定性:同一行的rowKey应始终保持不变,即使数据内容发生变化

2. onChange

onChange是antd提供的一个强大的回调函数,用于处理表格的分页、排序、筛选等交互事件。

触发时机

  • 分页:

    • 切换页码;
    • 调整每页显示数量(如果启用了showSizeChanger)
  • 排序:

    • 点击列表头进行排序
    • 切换排序方向(升/降/取消排序)
  • 筛选:

    • 使用列筛选器进行选择或取消排序
    • 清除筛选器
  • 树形表格
    • 展开/折叠属性表格的节点(树形表格的展开 / 折叠操作默认不会触发onChange回调。只有当树形表格的expandedRowKeys作为受控属性时onChange才会在展开 / 折叠时被触发。树形表格的展开 / 折叠需要通过专门的回调 处理,即onExpand

参数详解

onChange接受四个参数:

js 复制代码
onChange={(pagination, filters, sorter, extra) => {
  // 处理变化
}}
pagination 参数

包含当前分页状态的对象,常见属性有:

js 复制代码
{
  current: 1,         // 当前页码
  pageSize: 10,       // 每页显示数量
  total: 100,         // 数据总条数
  pageSizeOptions: ['10', '30', '50'], // 分页大小选项
  showSizeChanger: true, // 是否显示分页大小切换器
  showQuickJumper: true, // 是否显示快速跳转
  showTotal: (total) => `共 ${total} 条` // 显示总数信息
}
filters 参数

包含当前所有筛选条件的对象,格式为:

js 复制代码
{
  [columnKey]: value[]
}

如:

js 复制代码
{
  status: ['active', 'pending'], // 多选项筛选
  age: [20, 30],                 // 范围筛选
  gender: ['male']               // 单选项筛选
}
  • 注意:
  1. 筛选值始终是数组,即使是单选的筛选,所选的值也会被包装在数组中(如 ['male']
  2. 清除筛选后,对应的字段值会为undefined(如{ status: undefined }
sorter 参数

包含当前排序状态的对象,属性有:

js 复制代码
{
  field: 'age',        // 排序字段(对应列的dataIndex)
  order: 'descend',    // 排序顺序('ascend' 或 'descend')
  column: { ... },     // 排序的列配置对象
  columnKey: 'age'     // 列的唯一标识
}
  • 未排序状态{ field: undefined, order: undefined }
  • 自定义排序函数 :如果列配置中使用了自定义排序函数(如sorter: (a, b) => a.age - b.age),可以通过column.sorter访问
extra 参数(可选)

包含的是触发变化的额外信息,例如:

js 复制代码
{
  action: 'sort',            // 触发变化的操作类型('paginate', 'sort', 'filter')
  currentDataSource: [...],  // 当前表格的数据源
  trigger: 'click',          // 触发事件的方式(如'click')
  node: { ... }              // 树形表格中被操作的节点
}
注意事项
1. 受控与非受控模式
  • 受控模式 :提供pagination属性并通过onChange更新状态

    js 复制代码
    <Table
      pagination={pagination} // 受控模式
      onChange={onChange}
    />
  • 非受控模式 :不提供pagination属性,表格使用内部状态

    js 复制代码
    <Table
      onChange={onChange} // 非受控模式,仅监听变化
    />
2. sorter API VS onChange 中的 sorter

这两者是定义排序规则获取排序结果的关系:

sorter属性(定义排序规则)

在 Table 的列配置中使用,用于指定该列是否可排序及排序逻辑:

js 复制代码
const columns = [
  {
    title: '年龄',
    dataIndex: 'age',
    sorter: true, // 简单数字/字符串排序
    // 或自定义排序函数:
    sorter: (a, b) => a.age - b.age,
    // 或多列排序:
    sortDirections: ['ascend', 'descend'],
  },
];
onChange回调中的sorter参数(获取排序结果)

当用户点击列标题进行排序时,onChange会被触发,并携带当前的排序状态:

js 复制代码
<Table
  onChange={(pagination, filters, sorter) => {
    console.log('当前排序:', sorter);
    // 输出示例:
    // {
    //   field: 'age',
    //   order: 'descend',
    //   column: { ... }
    // }
  }}
/>
diff 复制代码
- 两者的关联
-   sorter属性定义了列的排序能力和规则
-   onChange回调获取用户实际操作后的排序结果
-   前端排序时,Ant Design 会根据sorter自动处理数据排序
-   后端排序时,需要将onChange中的sorter参数传递给 API

Form

自定义组件:为什么 Form.Item 嵌套子组件后,不更新表单值?

为什么 Form.Item 嵌套子组件后,不更新表单值?

Form.Item 在渲染时会注入 valueonChange 事件给子元素,当你的字段组件被包裹时属性将无法传递。所以以下代码是不会生效的:

js 复制代码
<Form.Item name="input">
  <div>
    <h3>I am a wrapped Input</h3>
    <Input />
  </div>
</Form.Item>

可以通过 HOC 自定义组件形式来解决这个问题:

js 复制代码
const MyInput = (props) => (
  <div>
    <h3>I am a wrapped Input</h3>
    <Input {...props} />
  </div>
);


<Form.Item name="input">
  <MyInput />
</Form.Item>;
相关推荐
程序视点2 小时前
IObit Uninstaller Pro专业卸载,免激活版本,卸载清理注册表,彻底告别软件残留
前端·windows·后端
前端程序媛-Tian2 小时前
【dropdown组件填坑指南】—怎么实现下拉框的位置计算
前端·javascript·vue
嘉琪0012 小时前
实现视频实时马赛克
linux·前端·javascript
烛阴3 小时前
Smoothstep
前端·webgl
若梦plus3 小时前
Eslint中微内核&插件化思想的应用
前端·eslint
爱分享的程序员3 小时前
前端面试专栏-前沿技术:30.跨端开发技术(React Native、Flutter)
前端·javascript·面试
超级土豆粉3 小时前
Taro 位置相关 API 介绍
前端·javascript·react.js·taro
若梦plus3 小时前
Webpack中微内核&插件化思想的应用
前端·webpack
若梦plus3 小时前
微内核&插件化设计思想
前端
柯北(jvxiao)3 小时前
搞前端还有出路吗?如果有,在哪里?
前端·程序人生