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
相关产品推荐
相关产品推荐

