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

Antd TimePicker RangePicker设置初始值后无法修改/检测值的问题

Antd TimePicker.RangePicker 表单修改异常问题修复

问题场景

我基于Antd实现了一个带时间范围选择的编辑表单,代码如下:

组件导入

import { TimePicker } from 'antd';
const { RangePicker } = TimePicker;

状态与表单初始化

const [editForm] = Form.useForm();
const formValues = Form.useWatch([], editForm);  
const [editBoxVisible, setEditBoxVisible] = useState(false);
const [editingMealTimeName, setEditingMealTimeName] = useState(null);
const [editingMealTime, setEditingMealTime] = useState(null);

编辑触发与初始值填充

<Button 
     type="link" 
     size="medium" 
     icon={<EditOutlined />} 
     onClick={() => handleEdit(record.name,  record.time)}
/>

const handleEdit = (name, timePeriod) => {
    setEditingMealTimeName(name);
    setEditingMealTime(timePeriod);
    setEditBoxVisible(true);

    editForm.setFieldsValue({
      name: name || "",
      timePeriod: timePeriod ? [moment(timePeriod[0], "HH:mm"), moment(timePeriod[1], "HH:mm")] : []
    });
};

模态框与表单结构

<Modal
   title="编辑自定义用餐时间"
   open={editBoxVisible}
   onCancel={handleEditCancel}
   maskClosable={false}
   footer={null}
>
   <Form 
      form={editForm} 
      onFinish={handleEditSubmit}        
   >
       <Form.Item 
          label="名称" 
          name="name" 
          rules={[{ required: true }]} 
         >            
            <Input style={{width:"70%"}} />
        </Form.Item>
        <Form.Item
          label="时间段"
          name="timePeriod"
          rules={[{ required: true }]}
         >
          <RangePicker format="HH:mm" style={{ width: "70%" }} />
        </Form.Item>
        <Form.Item>
          <Button type="primary" htmlType="submit">保存</Button>
        </Form.Item>
    </Form>
</Modal>

异常现象

初始值能正常显示,但修改时间时出现问题:

  • 首次修改“开始时间”,确认后无法保存修改,或出现无规律的随机值
  • 修改“结束时间”时,会错误记录之前的“开始时间”或更早的随机时间
  • 只有清空RangePicker后重新选择,才能正常显示和保存

修复方案

1. 调整表单赋值时机,确保Modal渲染完成后再赋值

setEditBoxVisible(true)后Modal不会立刻渲染,此时直接调用setFieldsValue会因为字段未初始化导致状态异常。改用useEffect监听Modal显示状态,打开后再赋值:

import { useEffect } from 'react';

// 移除handleEdit中的setFieldsValue,只更新状态
const handleEdit = (name, timePeriod) => {
    setEditingMealTimeName(name);
    setEditingMealTime(timePeriod);
    setEditBoxVisible(true);
};

// 监听Modal显示状态,完成渲染后赋值表单
useEffect(() => {
  if (editBoxVisible && editingMealTime) {
    editForm.setFieldsValue({
      name: editingMealTimeName || "",
      timePeriod: [moment(editingMealTime[0], "HH:mm"), moment(editingMealTime[1], "HH:mm")]
    });
  }
}, [editBoxVisible, editingMealTime, editingMealTimeName, editForm]);

2. 为RangePicker指定valueFormat,避免moment对象引用问题

默认情况下RangePicker会返回moment对象,容易因为引用问题导致状态混乱。添加valueFormat="HH:mm"让表单直接存储字符串:

<RangePicker 
  format="HH:mm" 
  valueFormat="HH:mm" 
  style={{ width: "70%" }} 
/>

这时表单赋值也可以简化,直接传入原始字符串数组:

// useEffect中的赋值改为
editForm.setFieldsValue({
  name: editingMealTimeName || "",
  timePeriod: editingMealTime
});

3. 关闭Modal时清空表单状态(可选)

避免下次打开Modal时残留旧状态,在关闭时重置表单:

const handleEditCancel = () => {
  setEditBoxVisible(false);
  editForm.resetFields();
  setEditingMealTimeName(null);
  setEditingMealTime(null);
};

核心原因

  • 表单赋值时机过早,Modal未完成渲染,表单字段未初始化导致赋值失效
  • 未指定valueFormat时,RangePicker依赖moment对象引用管理状态,外部传入的moment对象可能破坏内部状态同步

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:33:24