React+Django Todo应用:解决刷新后localStorage数据被覆盖问题
解决React+Django待办应用刷新时本地编辑被后端数据覆盖的问题
问题根源
你的代码存在两个核心问题:
taskEdits初始状态为空对象,组件挂载后第二个useEffect会立即将空对象写入localStorage,直接覆盖之前保存的编辑内容。- 合并后端数据与本地编辑的逻辑仅在组件首次挂载时执行,后续
taskEdits更新时没有同步更新tasks状态,导致页面显示和本地存储不一致。
修复方案
1. 从localStorage初始化taskEdits
将taskEdits的初始状态直接从localStorage读取,避免挂载时清空已有存储数据:
const [taskEdits, setTaskEdits] = useState(() => { return JSON.parse(localStorage.getItem("taskEdits")) || {}; });
2. 同步taskEdits与tasks状态
新增useEffect监听taskEdits和tasks的变化,实时合并后端数据与本地编辑,确保页面显示始终包含最新的本地修改:
const [tasks, setTasks] = useState([]); // 首次挂载获取后端原始任务数据 useEffect(() => { axios.get("/tasks/") .then((res) => { setTasks(res.data); }) .catch((err) => console.error("Error fetching tasks:", err)); }, []); // 合并后端数据与本地编辑,更新页面显示 useEffect(() => { const mergedTasks = tasks.map((task) => { if (taskEdits[task.id]) { return { ...task, title: taskEdits[task.id] }; } return task; }); setTasks(mergedTasks); }, [tasks, taskEdits]); // 实时同步taskEdits到localStorage useEffect(() => { localStorage.setItem("taskEdits", JSON.stringify(taskEdits)); }, [taskEdits]);
3. 编辑任务的逻辑示例
当用户修改任务标题时,只需更新taskEdits,即可自动同步到本地存储和页面:
const handleTaskEdit = (taskId, newTitle) => { setTaskEdits(prev => ({ ...prev, [taskId]: newTitle })); // 可选:点击保存时再同步到后端,减少请求次数 // axios.patch(`/tasks/${taskId}/`, { title: newTitle }) // .catch(err => console.error("Error updating task:", err)); };
额外优化建议
- 建议在用户主动触发保存操作(如点击「保存」按钮)时,再将本地编辑同步到后端,避免频繁发起请求。
- 可添加冲突处理逻辑:如果后端数据与本地编辑存在差异(如其他设备修改了同一条任务),提示用户选择保留哪份数据。
内容的提问来源于stack exchange,提问作者Naing
相关产品推荐
相关产品推荐

