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

如何在React中更新深度嵌套state:修改指定日期的isCompleted属性

如何更新嵌套的日历State

处理这种嵌套结构的state更新,核心要遵循React的不可变原则——不能直接修改原state,必须创建新的副本修改后再更新。下面是具体实现步骤:

1. 给点击事件传递定位信息

点击日期时,需要把该日期对应的year、month、day作为参数传给处理函数,这样才能精准找到要修改的对象。

2. 编写更新逻辑

使用数组的map方法逐层遍历,创建新的数组/对象副本,只修改目标日期的isCompleted属性:

// 假设你用的是函数组件,已通过useState初始化calendarData
const handleDayClick = (targetYear, targetMonth, targetDay) => {
  // 生成新的日历数组副本
  const updatedCalendar = calendarData.map(monthEntry => {
    // 匹配目标年月
    if (monthEntry.year === targetYear && monthEntry.month === targetMonth) {
      // 生成新的日期数组副本
      const updatedDays = monthEntry.days.map(dayEntry => {
        // 匹配目标日期,返回修改后的新对象
        if (dayEntry.day === targetDay) {
          return { ...dayEntry, isCompleted: true };
        }
        // 非目标日期直接返回原对象
        return dayEntry;
      });
      // 返回修改后的年月对象
      return { ...monthEntry, days: updatedDays };
    }
    // 非目标年月直接返回原对象
    return monthEntry;
  });

  // 更新state
  setCalendarData(updatedCalendar);
};

3. 渲染时绑定点击事件

在渲染每个日期按钮时,把对应的年、月、日传给点击函数:

return (
  <div className="calendar">
    {calendarData.map(month => (
      <div key={`${month.year}-${month.month}`} className="month-container">
        <h2>{month.year} · {month.month}</h2>
        <div className="days-grid">
          {month.days.map(day => (
            <button
              key={day.day}
              onClick={() => handleDayClick(month.year, month.month, day.day)}
              className={day.isCompleted ? 'completed-day' : 'normal-day'}
            >
              {day.day}
            </button>
          ))}
        </div>
      </div>
    ))}
  </div>
);

关键注意点

  • 必须用map生成新数组,而不是直接修改原数组,React依赖state的引用变化来触发重新渲染。
  • 用展开运算符...创建对象副本,避免直接修改原state中的对象,保证不可变性。
  • 只修改需要更新的层级,其他层级直接返回原对象,减少不必要的内存开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:15:08