如何在React应用中使用useEffect操作localStorage实现待办数据持久化
React TodoList localStorage持久化实现方案
你当前的存储逻辑已经完成了「数据变更时写入localStorage」的部分,缺少初始化读取本地存储的逻辑,同时存在状态突变的问题,按以下步骤修改即可:
核心改动点
- 修正任务列表状态更新逻辑:避免直接修改原数组,返回新数组触发React重渲染,同时唤醒useEffect的存储逻辑
- 为待办列表状态添加初始化读取逻辑,从localStorage拉取上次存储的数据
- 补充异常容错,避免非法本地数据导致页面崩溃
完整修改后代码
import React, { useState, useEffect } from 'react'; import trashIcon from './trash.svg'; function App() { const [taskInput, updateTaskInput] = useState(''); // 改动1:初始化时从localStorage读取存储的待办列表 const [toDolist, updateToDoList] = useState(() => { try { const savedLists = localStorage.getItem('lists'); return savedLists ? JSON.parse(savedLists) : []; } catch (err) { console.warn('本地待办数据损坏,已重置', err); return []; } }); const inputKeyDown = (event) => { if (event.keyCode === 13) addNote(); }; // 改动2:修正状态更新方式,不直接修改原数组 const addNote = () => { if (!taskInput.trim()) return; // 新增空任务拦截 const newTodoList = [...toDolist, { description: taskInput, isComplete: false }]; updateToDoList(newTodoList); updateTaskInput(''); }; // 补充缺失的标记完成/删除任务逻辑,同样采用新数组更新 const mark = (index) => { const newTodoList = toDolist.map((item, i) => i === index ? {...item, isComplete: !item.isComplete} : item ); updateToDoList(newTodoList); }; const deleteTask = (index) => { const newTodoList = toDolist.filter((_, i) => i !== index); updateToDoList(newTodoList); }; // 该存储逻辑无需修改,依赖toDolist变更自动写入本地 useEffect(() => { localStorage.setItem('lists', JSON.stringify(toDolist)); }, [toDolist]); return ( <div className='app-background'> <p className=' heading-text'> To do List</p> <div className='task-container'> <div> <input className='text-input' value={taskInput} onKeyDown={inputKeyDown} onChange={(event) => updateTaskInput(event.target.value)} /> <button className='add-button' onClick={addNote}> ADD </button> </div> {toDolist?.length ? ( toDolist.map((toDoObject, index) => ( <ListItem key={index} index={index} itemData={toDoObject} deleteTask={deleteTask} mark={mark} /> )) ) : ( <p className='no-item-text'>📌 No Task added</p> )} </div> <p className='footer-text'>Sabar_I ❤️</p> </div> ); } function ListItem(props) { return ( <div className='list-item row jc-space-between'> <span className={props.itemData.isComplete ? 'task-complete' : ''} onClick={() => props.mark(props.index)} > {props.itemData.isComplete ? `✅ ` : ''} {props.itemData?.description} </span> <img src={trashIcon} className='delete-icon' onClick={() => props.deleteTask(props.index)} alt='/' /> </div> ); } export default App;
验证方式
添加测试任务后刷新页面,已添加的任务不会消失即代表本地存储逻辑生效。
内容的提问来源于stack exchange,提问作者K S Sabarinathan
相关产品推荐
相关产品推荐

