Antd6 为什么废弃 List 组件

127 阅读4分钟

升级 antd6 建议提前规划好,涉及现有项目 List 组件的重构

  • antd List
  • pro-components ProList
  • List 滚动加载
  • 长列表重构

废弃 List 组件是 Ant Design 走向更精简、更专注的架构的一部分,主流观点

  • 减少冗余:消除与原生 HTML 和 Table 组件的功能重叠。
  • 降低复杂度:简化组件库的 API 表面。
  • 提升灵活性:鼓励开发者使用更基础的构建块(如 div, Table, Card, Grid)来组合出自己需要的布局,这通常能带来更好、更个性化的结果。

antd6 废弃 List 的考量点

  1. 与 HTML 标准重复,价值有限
    • List 组件最基础的功能是渲染一组数据项。
    • 这个功能完全可以通过原生 HTML 的 <ul><ol> 结合 CSS 来实现,或者直接使用 map 函数遍历数组渲染 div
    • Ant Design 的 List 组件本质上是一个“带样式的 div 列表”,其核心附加值(样式、分割线、栅格布局)现在被认为不足以 justify 一个独立的组件。
  2. **功能与更强大的 **Table组件重叠
    • 很多使用 List 的场景是渲染一个简单的数据列表。但当需求变得复杂时(例如,需要排序、筛选、固定列等),开发者不得不从 List 迁移到 Table
    • Table 组件功能极其强大且完善,而 List 的功能则相对局限。维护两个功能有重叠的组件会增加 API 复杂性和维护成本。
  3. 维护成本和 API 一致性
    • 维持一个组件需要持续地处理 Bug、增加新特性、保证 API 的一致性。对于 List 这样一个功能相对简单的组件来说,其维护成本与它带来的价值相比,显得不那么划算。
    • 移除 List 可以简化 Ant Design 的组件库,让团队更专注于增强和维护像 TableCard 这样不可替代或功能更复杂的组件。
  4. 鼓励使用更合适的布局组件
    • 对于复杂的列表布局,特别是需要响应式的栅格布局,Row/Col 组件或 Space 组件通常是更灵活、更语义化的选择。
    • 对于一组相关的卡片式内容,Card 组件组合可能更合适。

废弃 List,意味着要自己实现 List 列表,List 原始代码兼容工作要实现。

从长远来看

  • List 需求变化太多,CSS Grid, Flex 已经能满足一些基础 List 列表
  • 长列表优化,有 react-window,和 @tanstack/react-virtual,需求变化不定,要根据实际业务来匹配技术栈

当前(v5, v6)应该怎么做?

  1. 不要慌:废弃计划是在 v7,在 v5 和 v6 中你仍然可以继续使用 List 组件,会正常工作,只是控制台有警告信息。 image.png
  2. 计划迁移重构:对于新项目,可以开始考虑是否真的需要 List 组件,或许上述的替代方案从一开始就是更好的选择。
  3. 审查现有代码:检查你的项目中所有使用 List 组件的地方。评估迁移的代价:
    • 如果只是简单使用,迁移到原生列表或 Space/Card 组合会非常容易。
    • 如果你重度使用了 Listgrid 属性,迁移到 Row/Col 是最直接的路径。
    • 如果你的列表有向复杂表格发展的趋势,直接迁移到 Table 组件是长远之计。
  4. 关注官方公告:密切关注 Ant Design v7 的正式发布公告和迁移指南,届时官方一定会提供更详细的替代方案和代码修改工具(如果可能的话)。

List 替代方案是什么

Listy 组件

官方计划推出新的替代组件叫做 Listy,相关进展可以关注

  • List 组件暂时还保留兼容性,但建议迁移到 ProList 或后续的 Listy
  • 目前推荐的替代方案是 ProComponents 中的 ProList,在原有 List 基础上扩展了多选、展开等功能,体验更接近 Table,适合后台数据展示场景。
  • ProList 文档见:ProList 官方文档

tailwind List 组件

tailwindcss.com/plus/ui-blo…

  1. HTML + tailwindcss@4 重构
    1. CSS Grid 实现 List,推荐
    2. CSS Flex 实现 List
  2. antd 组件代替 List
    1. 使用 Table 组件
    2. 使用 Flex 组件代替 List
    3. 使用 Card 组件组合
    4. 使用 Row,Col

简单 List

<ul className='border rounded-lg'>
  {data.map(item => (
    <li
      key={item.id}
      style={{
        padding: '12px 24px',
        borderBottom: '1px solid #f0f0f0'
      }}
    >
      {item.content}
    </li>
  ))}
</ul>

Table

<Table
  dataSource={data}
  columns={[
    {
      dataIndex: 'content',
      // 不设置 title 以隐藏表头
    },
  ]}
  pagination={false}
  showHeader={false} // 隐藏整个表头
/>

Card

<Space direction="vertical" size="middle" style={{ width: '100%' }}>
  {data.map(item => (
    <Card key={item.id} size="small">
      <p>{item.content}</p>
    </Card>
  ))}
</Space>

Row & Col

<Row gutter={16}>
  {data.map(item => (
    <Col span={6} key={item.id}>
      <div style={{ background: '#fafafa', padding: '16px' }}>
        {item.content}
      </div>
    </Col>
  ))}
</Row>

Flex

<Flex wrap="wrap" gap="middle">
  {data.map(item => (
    <div
      key={item.id}
      style={{
        width: '200px',
        background: '#fafafa',
        padding: '16px'
      }}
    >
      {item.content}
    </div>
  ))}
</Flex>