4.0 KiB
4.0 KiB
实现方案 — 2026-04-16-18-51-06
根因分析
ReportEditor.tsx 中使用了 stateRef.current 作为「草稿自动保存」的数据来源。组件卸载时,saveDraftToStorage() 会将 stateRef.current 写入 localStorage。
但在页面初始化(useEffect 和 useLayoutEffect)从已保存报告或 draft 恢复数据时,仅通过 setState 更新了 React state,没有同步更新 stateRef.current 中的 videos 和 capturedFrames 字段。
这导致:
- 用户首次进入
/report-editor时,数据从 localStorage 正确恢复; - 用户离开页面时,
stateRef.current仍保存着初始的空数组; - 组件卸载触发的
saveDraftToStorage()用空数组覆盖了 draft; - 用户再次返回
/report-editor时,系统优先读取被覆盖后的 draft,导致视频分析数据全部丢失。
修改文件清单
| 文件 | 修改类型 | 说明 |
|---|---|---|
src/pages/ReportEditor.tsx |
修改 | 在 4 处数据恢复逻辑后追加 stateRef.current 同步赋值 |
具体代码变更
修改点 1:初始化 useEffect — 从 draft 恢复已有报告(约第 128 行后)
在已有代码:
setLoadedTemplateId(draft.loadedTemplateId || '');
stateRef.current = { ...stateRef.current, loadedTemplateId: draft.loadedTemplateId || '' };
追加同步:
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
修改点 2:初始化 useEffect — 从已保存报告(found)恢复(约第 146 行后)
在设置完 contentLoadedRef.current = true; 之后,追加同步:
stateRef.current = {
...stateRef.current,
reportData: found,
videos: found.videos || [],
capturedFrames: found.capturedFrames || []
};
修改点 3:初始化 useEffect — 从 draft 恢复新建报告(约第 176 行后)
与修改点 1 类似,在 setLoadedTemplateId(draft.loadedTemplateId || ''); 之后,追加同步:
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
修改点 4:useLayoutEffect 安全网 — 从 draft 恢复已有报告(约第 677 行后)
在 setLoadedTemplateId(draft.loadedTemplateId || ''); 之后,追加同步:
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
修改点 5:useLayoutEffect 安全网 — 从已保存报告(found)恢复(约第 692 行后)
在 contentLoadedRef.current = true; 之后,追加同步:
stateRef.current = {
...stateRef.current,
reportData: found,
videos: found.videos || [],
capturedFrames: found.capturedFrames || []
};
修改点 6:useLayoutEffect 安全网 — 从 draft 恢复新建报告(约第 701 行后)
在 setLoadedTemplateId(draft.loadedTemplateId || ''); 之后,追加同步:
stateRef.current = {
...stateRef.current,
reportData: draft.reportData,
videos: draft.videos,
capturedFrames: draft.capturedFrames,
loadedTemplateId: draft.loadedTemplateId || ''
};
风险点
| 风险 | 级别 | 应对措施 |
|---|---|---|
stateRef 仍可能在其他未覆盖路径中不同步 |
低 | 已检查所有数据恢复入口(init effect + layout effect),后续若新增恢复逻辑需保持同步习惯 |
found.videos / found.capturedFrames 为 undefined |
低 | 代码中使用 ` |
回滚策略
本次修改仅增加 stateRef.current 的同步赋值语句,不涉及删除或重构现有逻辑。如出现异常,可直接 git revert 回滚。
⚠️ 请审核以上方案,确认无误后回复「确认」或提出修改意见,我将进入测试方案编写阶段。