You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 01:39:00