React项目中react-DatePicker出现Uncaught RangeError: 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




