React中localStorage无法保存todos数组最后一项的技术问题
Todo列表无法保存最后一项的问题解决
问题原因
React的setState(包括setTodos这类状态更新函数)是异步执行的。你在添加、编辑、删除或修改Todo状态后,立刻调用saveToLS(),此时组件内的todos状态还没完成更新,saveToLS里用到的todos还是更新前的旧值,导致每次保存的数组都少了最新的那一项。
解决方案
方案一:直接传递更新后的新数组到保存函数
修改saveToLS函数,让它接收一个新数组参数,直接保存最新的数组:
const saveToLS = (todosToSave) => { localStorage.setItem("todos", JSON.stringify(todosToSave)); console.log(todosToSave); }
然后修改各个处理函数,先创建更新后的新数组,再传给saveToLS:
修改handleAdd:
const handleAdd = () => { const newTodos = [...todos, { id: uuidv4(), todo, isCompleted: false }]; setTodos(newTodos); setTodo(""); saveToLS(newTodos); }
修改handleEdit:
const handleEdit = (e, id) => { const targetTodo = todos.filter(i => i.id === id)[0]; setTodo(targetTodo.todo); const newTodos = todos.filter(item => item.id !== id); setTodos(newTodos); saveToLS(newTodos); }
修改handleDelete:
const handleDelete = (e, id) => { const newTodos = todos.filter(item => item.id !== id); setTodos(newTodos); saveToLS(newTodos); }
修改handleCheckbox:
const handleCheckbox = (e) => { const id = e.target.name; const index = todos.findIndex(item => item.id === id); const newTodos = [...todos]; newTodos[index].isCompleted = !newTodos[index].isCompleted; setTodos(newTodos); saveToLS(newTodos); }
方案二:用useEffect监听todos变化自动保存
这种方式更贴合React状态管理逻辑,不用手动在每个处理函数里调用保存方法:
- 删掉所有处理函数里的
saveToLS()调用 - 移除原
saveToLS函数,添加以下useEffect:
useEffect(() => { localStorage.setItem("todos", JSON.stringify(todos)); console.log(todos); }, [todos]); // todos状态变化时自动执行保存
这个useEffect会在todos每次更新后自动触发,把最新的数组存入localStorage,彻底解决异步更新导致的保存延迟问题。
内容的提问来源于stack exchange,提问作者Jahnvi Saxena
相关产品推荐
相关产品推荐

