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

React中如何将嵌套对象存入state并持久化到localStorage

完整实现方案

1. 状态初始化与自动持久化逻辑

核心逻辑是两个环节:首次加载优先读取本地存储的进度数据,状态每次变更自动同步到localStorage,不需要手动处理快照保存。

import course from "./data/index";
import { useState, useEffect } from 'react';

// 统一本地存储的key,避免硬编码出错
const SCHEMA_STORAGE_KEY = 'course_progress_schema';

function YourComponent() {
  // 惰性初始化:优先读本地历史进度,读取失败/无数据时兜底用默认课程数据
  const [schema, setSchema] = useState(() => {
    const savedSchema = localStorage.getItem(SCHEMA_STORAGE_KEY);
    if (savedSchema) {
      try {
        return JSON.parse(savedSchema);
      } catch (e) {
        console.error('进度数据损坏,已重置为默认值', e);
        return course;
      }
    }
    return course;
  });

  // 监听schema变化,自动同步最新状态到localStorage
  useEffect(() => {
    localStorage.setItem(SCHEMA_STORAGE_KEY, JSON.stringify(schema));
  }, [schema]);

  // 你的其余组件逻辑
}

2. 嵌套对象更新注意事项

必须遵循React不可变更新原则,直接修改原嵌套对象的属性不会触发状态更新,也不会触发本地存储同步。以下是更新指定课时状态的示例代码:

// 示例:将对应模块下的对应课时标记为已完成
const updateLessonProgress = (moduleIndex, lessonIndex, isComplete, progress) => {
  setSchema(prev => {
    // 逐层展开生成全新对象,避免修改原状态
    return {
      ...prev,
      courseModules: prev.courseModules.map((module, mIdx) => {
        if (mIdx !== moduleIndex) return module;
        return {
          ...module,
          moduleLessons: module.moduleLessons.map((lesson, lIdx) => {
            if (lIdx !== lessonIndex) return lesson;
            return {
              ...lesson,
              isComplete,
              progress
            };
          })
        };
      })
    };
  });
};

补充说明

  • 如果lessonData字段包含函数、Symbol等无法被JSON序列化的内容,序列化时会丢失,建议这类非序列化资源单独存放,不要放到要持久化的schema里
  • 需要重置进度时直接调用setSchema(course)即可,会自动覆盖本地存储的旧数据
  • 后续如果要支持多课程进度存储,可以把存储key替换为对应课程的唯一标识,比如course_progress_${courseId}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:36:06