React状态日期异常:自定义值自动变为Date.now()格式
React中自定义日期状态异常混乱的问题解决
问题场景
在React项目中,通过useEffect监听产品数据,尝试将服务器返回的自定义起止日期转为YYYY-MM-DD格式的字符串存入状态,但运行后日期数值和格式混乱,表现出类似自动调用Date.now()的异常情况。相关代码如下:
if (CoutureRentalState.reservasDelProducto != initialCoutureRental.reservasDelProducto) { invalid = [] CoutureRentalState.reservasDelProducto.forEach(reserva => { invalid.push({ start: `${reserva.inicioReserva[0]}-${reserva.inicioReserva[1]}-${reserva.inicioReserva[2]}`, end: `${reserva.finReserva[0]}-${reserva.finReserva[1]}-${reserva.finReserva[2]}` }) }); console.log("Invalidas"); console.log(invalid); setFechasInvalidas(invalid) console.log("State"); console.log(fechasInvalidas); }
问题原因
- 数组比较逻辑错误:数组属于引用类型,直接用
!=比较两个数组时,实际对比的是内存地址而非内容,导致这段代码会在每次组件渲染时都执行,重复修改状态引发数据混乱。 - 日期格式化不规范:若服务器返回的月份/日期是个位数(如3月仅传
3而非03),拼接后的字符串为YYYY-M-D格式,后续解析时可能被识别为错误日期。 - setState异步特性误解:调用
setFechasInvalidas后立即打印fechasInvalidas,此时状态尚未完成更新,打印的是旧值,容易造成判断误差。 - 日期数组顺序不符预期:若服务器返回的
inicioReserva/finReserva数组顺序不是[年,月,日](如[日,月,年]),拼接出的字符串完全不符合日期格式规范,会被解析成错误数值。
解决方案
1. 修复数组变化判断逻辑
改用深比较判断数组内容是否真的变化,可选择JSON.stringify(适合小数组):
const hasReservasChanged = JSON.stringify(CoutureRentalState.reservasDelProducto) !== JSON.stringify(initialCoutureRental.reservasDelProducto); if (hasReservasChanged) { // 原有处理逻辑 }
或使用lodash的isEqual方法(需先安装lodash):
import { isEqual } from 'lodash'; // ... if (!isEqual(CoutureRentalState.reservasDelProducto, initialCoutureRental.reservasDelProducto)) { // 原有处理逻辑 }
2. 规范日期字符串格式化
通过padStart(2, '0')为个位数的月份/日期补零,确保生成标准的YYYY-MM-DD格式:
invalid.push({ start: `${reserva.inicioReserva[0]}-${String(reserva.inicioReserva[1]).padStart(2, '0')}-${String(reserva.inicioReserva[2]).padStart(2, '0')}`, end: `${reserva.finReserva[0]}-${String(reserva.finReserva[1]).padStart(2, '0')}-${String(reserva.finReserva[2]).padStart(2, '0')}` })
3. 正确查看更新后的状态
不要在setState后立即打印状态,改用useEffect监听状态变化:
useEffect(() => { console.log("更新后的状态:", fechasInvalidas); }, [fechasInvalidas]);
4. 确认并修正日期数组顺序
检查服务器返回的日期数组元素顺序,若顺序不是[年,月,日],调整拼接顺序,比如假设返回顺序是[日,月,年]:
start: `${reserva.inicioReserva[2]}-${String(reserva.inicioReserva[1]).padStart(2, '0')}-${String(reserva.inicioReserva[0]).padStart(2, '0')}`
内容的提问来源于stack exchange,提问作者Marcos Caride
相关产品推荐
相关产品推荐

