React中使用useReducer时如何从localStorage获取text数据?
问题修复与解答
错误原因分析
- Uncaught TypeError: init is not a function:
useReducer的第三个参数要求是初始化函数,但你传入的是initialTasks对象,不符合API规范。 - localStorage读取后显示空数组:你的
tasksReducer处理的是数组类型的状态,但组件中useReducer的初始值设为了{ tasks: [] }(对象类型),状态结构不匹配,导致读取localStorage后无法正确映射到组件状态。
代码修改方案
1. 修改ReducerPractice.js
... import tasksReducer from "./tasksReducer"; // 定义初始化函数,从localStorage读取任务数组 const getInitialTasks = () => { const storedTasks = localStorage.getItem("tasks"); return storedTasks ? JSON.parse(storedTasks) : []; }; export default function ReducerPrac() { // 状态直接为任务数组,与reducer处理的结构保持一致 const [tasks, dispatch] = useReducer( tasksReducer, [], getInitialTasks // 传入初始化函数 ); const tasksId = useRef(0); function handleAddTask(text) { tasksId.current += 1; // 修正id递增逻辑,避免重复 dispatch({ type: "added", id: tasksId.current, text: text, }); } function handleChangeTask(updatedTask) { dispatch({ type: "changed", task: updatedTask, // 调整action字段名,逻辑更清晰 }); } function handleDeleteTask(taskId) { dispatch({ type: "deleted", id: taskId, }); } useEffect(() => { localStorage.setItem("tasks", JSON.stringify(tasks)); }, [tasks]); return ( <> <h3>Reducer todo</h3> <AddTask onAddTask={handleAddTask} /> <br /> <TaskList tasks={tasks} onChangeTask={handleChangeTask} onDeleteTask={handleDeleteTask} /> </> ); }
2. 修改tasksReducer.js
export default function tasksReducer(tasks, action) { switch (action.type) { case "added": { return [ ...tasks, { id: action.id, text: action.text, done: false }, ]; } case "changed": { // 对应修改后的action字段,用action.task获取更新后的任务 return tasks.map((t) => { if (t.id === action.task.id) { return action.task; } else { return t; } }); } case "deleted": { return tasks.filter((t) => t.id !== action.id); } default: { throw new Error("Unknown dispatched action: " + action.type); } } }
关于useContext的问题
在React中结合useReducer和localStorage时,不是必须搭配useContext:
- 如果只有单个组件或少数几层子组件需要访问任务状态和dispatch方法,直接通过props传递即可。
- 当多个不相关的组件(跨多层组件树)需要共享状态和dispatch时,才需要用
useContext封装reducer的状态和方法,避免props层层传递的繁琐。
内容的提问来源于stack exchange,提问作者nuser137
相关产品推荐
相关产品推荐

