React/Next.js Context Provider状态首次加载/刷新无法访问,修改状态后正常问题排查
问题修复说明
根因定位
- 未执行初始化数据同步:
useTodos中定义的getTodos方法仅作为公开方法暴露,没有在Hook初始化阶段读取localStorage中的数据同步到useState的状态中,首次加载时todos状态始终为初始空数组,所以totalTodos()返回值为0。只有调用saveTodos触发setTodos更新状态后,数值才会正常显示。 - 代码语法错误:
- 布局文件中解构
useTodos返回值时遗漏了saveTodos,导致Provider传递的saveTodos为未定义变量 - Context.Provider的
value属性未正确传入对象,当前写法value={ todos, totalTodos, getTodos, saveTodos }不符合JSX语法,需用双层花括号包裹为对象格式
- 布局文件中解构
修复代码
修改useTodos.js
添加初始化逻辑,挂载时自动读取本地存储数据同步到状态:
//useTodos.js import { useState, useEffect } from 'react'; export default function useTodos(){ const [todos, setTodos] = useState([]); // 新增:初始化时同步本地存储数据 useEffect(() => { const storedTodos = getTodos(); setTodos(storedTodos); }, []); const totalTodos = () => { return todos.length; } const getTodos = () => { if (typeof window === 'undefined') return []; const raw = localStorage.getItem('todos'); return raw ? JSON.parse(raw) : []; } const saveTodos = (newTodos) => { if (typeof window !== 'undefined') { localStorage.setItem('todos', JSON.stringify(newTodos)); } setTodos(newTodos); } return { todos, totalTodos, getTodos, saveTodos } }
修改布局文件代码
修正解构和Provider传值语法:
const { todos, totalTodos, getTodos, saveTodos } = useTodos(); // ... return ( <TodosContext.Provider value={{ todos, totalTodos, getTodos, saveTodos }}> <div>Todo count: {totalTodos()}</div> {children} </TodosContext.Provider> )
内容的提问来源于stack exchange,提问作者Avi
相关产品推荐
相关产品推荐

