You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

React项目中react-DatePicker出现Uncaught RangeError: Invalid time value错误的解决求助

解决React DatePicker编辑时的Invalid time value错误

我一眼就看出问题出在日期类型的不一致性上——你存储的时候把原生Date对象转成了ISO字符串,编辑时又直接把这个字符串传给需要Date对象的DatePicker,自然会报错。下面是一步步的解决方案:

1. 去掉不必要的JSON转换,统一存储原生Date对象

你在添加新todo时用了JSON.parse(JSON.stringify(dueDate)),这完全是多余的,因为dueDate已经是通过moment(date).toDate()生成的原生Date对象了。直接存储这个对象即可:

修改Form组件里的onFormSubmit添加逻辑:

// 原代码
setTodos([...todos, {id: uuidv4(), dueDate: JSON.parse(JSON.stringify(dueDate)), completed: false}]);

// 修改后
setTodos([...todos, {id: uuidv4(), dueDate: dueDate, completed: false}]);

2. 表格渲染保持现有逻辑(moment可以直接处理Date对象)

你的formatDate函数不需要改动,moment能直接接收Date对象并格式化,不过注意把yyyy改成YYYY(moment里大写Y才是常规年份,小写y是周年份):

const formatDate = (cell, row) => {
  return moment(row.dueDate).format("YYYY-MM-DD");
}

3. 编辑时确保传递给DatePicker的是Date对象

现在因为存储的是原生Date对象,在useEffect里直接赋值就行。如果之后需要持久化到localStorage(会自动把Date转成字符串),可以加个类型判断兼容:

useEffect(() => {
  if(editTodo) {
    // 兼容可能的字符串格式(比如从localStorage读取的情况)
    const targetDate = typeof editTodo.dueDate === 'string' 
      ? new Date(editTodo.dueDate) 
      : editTodo.dueDate;
    setDueDate(targetDate);
  } else {
    setDueDate(new Date());
  }
}, [setDueDate, editTodo]);

4. 如果必须存ISO字符串(比如持久化需求)

如果因为某些原因必须把日期存成字符串,那就在读取todos的时候统一转成Date对象。比如从localStorage加载时:

const savedTodos = JSON.parse(localStorage.getItem('todos')) || [];
const normalizedTodos = savedTodos.map(todo => ({
  ...todo,
  dueDate: new Date(todo.dueDate) // 把字符串转回Date对象
}));
setTodos(normalizedTodos);

为什么原来的方法会出错?

JSON.stringify会把Date对象自动转成ISO格式的字符串(2021-08-19T21:34:24.000Z),而你编辑时直接把这个字符串传给DatePicker的selected属性——它只接受原生Date对象或者有效的moment对象,所以抛出了Invalid time value错误。

核心原则就是:全程保持日期类型一致,要么全用Date对象,要么全用ISO字符串,不要在中间随意切换类型,这样DatePicker和表格渲染就能正常协同工作了。

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

火山引擎 最新活动