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

JS使用useState合并新旧数组为一维数组及类型报错问题咨询

问题排查与解决方案

错误原因

  • 类型不匹配:你声明的start是Date[]类型的一维数组,而holidayDates本身就是Date[]类型,直接写[...start, holidayDates]会把整个holidayDates数组作为单个元素插入,最终得到的是混合了Date和Date数组的二维结构,和声明的Date[]类型冲突,所以触发TS报错。
  • 状态更新逻辑错误:循环内直接使用当前start值更新状态时,React的状态更新是批量异步的,多次调用setStart时拿到的start都是初始值,最终只会保留最后一次循环的更新结果,之前的合并结果会被覆盖。

实现方案

方案一:先计算完整数组再一次性更新(推荐)

先遍历所有节假日计算出所有日期,合并成一维数组后只执行一次状态更新,性能更高:

const [start, setStart] = useState<Date[]>([]);

useEffect(() => {
  if (!publicHoliday) return;
  // flatMap会自动把每个返回的数组合并为一维数组
  const allHolidayDates = publicHoliday.flatMap(holiday => {
    const eventStartDate = holiday.startDate;
    const eventEndDate = holiday.endDate;
    return enumerateDaysBetweenDates(eventStartDate, eventEndDate);
  });
  setStart(allHolidayDates);
}, [publicHoliday]);

方案二:循环内使用函数式更新

如果需要在循环中逐步更新状态,可以使用setState的函数式更新写法,每次更新都能拿到上一次的最新状态,同时要展开holidayDates保证数组是一维结构:

const [start, setStart] = useState<Date[]>([]);

useEffect(() => {
  publicHoliday?.forEach((holiday) => {
    const eventStartDate = holiday.startDate;
    const eventEndDate = holiday.endDate;
    const holidayDates = enumerateDaysBetweenDates(eventStartDate, eventEndDate);
    // 函数式更新拿到上一轮的最新状态,同时展开holidayDates打散元素
    setStart(prev => [...prev, ...holidayDates]);
  });
}, [publicHoliday]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:09:03