You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Antd Form.List日期字段随输入实时保持排序?

Ant Design Form.List 日期排序不生效问题解决

问题场景

使用Ant Design的Form.List组件,需求是让表单项始终按日期值排序,且每一次输入按键触发时都维持排序状态,但直接对fields排序的写法未生效。

原代码:

<Form.List>
  {(fields) => (
    <div>
      {[...fields]
        .sort((a,b) => form.getFieldValue(a.name).getTime() > form.getFieldValue(b.name).getTime() ? 1 : -1)
        .map((field) => (
          <Form.Item {...field}>
            <Input />
          </Form.Item>
      ))}
    </div>
  )}
</Form.List>

问题原因

  1. 直接对fields排序后渲染,但Form.List的fields顺序由内部状态控制,输入后表单值更新未触发fields的重新排序渲染
  2. 未处理日期值的类型转换:若输入的是字符串格式日期,直接调用getTime()会报错,导致排序逻辑失效
  3. 缺少触发组件重新渲染的机制,输入按键后无法实时触发排序

解决方案

修正排序逻辑,处理日期类型转换,并确保输入后触发表单状态更新以重新排序:

<Form.List name="dateList">
  {(fields, { add, remove }) => (
    <div>
      {[...fields]
        .sort((a, b) => {
          // 将表单值转为Date对象,空值默认设为最小日期
          const dateA = form.getFieldValue(a.name) ? new Date(form.getFieldValue(a.name)) : new Date(0);
          const dateB = form.getFieldValue(b.name) ? new Date(form.getFieldValue(b.name)) : new Date(0);
          // 直接返回时间戳差值简化排序逻辑
          return dateA.getTime() - dateB.getTime();
        })
        .map((field) => (
          <Form.Item
            {...field}
            key={field.key}
            name={field.name}
            rules={[{ required: true, message: '请输入日期' }]}
          >
            {/* 使用date类型输入框保证格式正确,onChange触发表单更新以实时排序 */}
            <Input type="date" onChange={() => form.setFieldsValue(form.getFieldsValue())} />
          </Form.Item>
        ))}
      <Button type="dashed" onClick={() => add()}>添加日期项</Button>
    </div>
  )}
</Form.List>

关键调整点

  • 日期类型处理:排序前将表单值转为Date对象,避免字符串比较错误,同时处理空值场景
  • 实时触发渲染:通过Input的onChange手动触发表单状态更新,确保每次输入后组件重新执行排序逻辑
  • 稳定渲染标识:给Form.Item添加key={field.key}和明确的name属性,保证React渲染的稳定性

内容的提问来源于stack exchange,提问作者Exifers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:24:50