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

React useContext钩子页面刷新时context变为null该如何解决

问题根因

  1. App组件中user的初始值为null,直接访问/profile路由或刷新页面时,用户信息尚未完成加载(无论从本地存储读取还是后端接口请求),Context传递的user值就是初始的null,此时Profile组件先渲染,执行initializeFields读取null下的属性自然会抛出错误。
  2. 你定义的Context默认值{user: {}}仅在组件没有被UserContext.Provider包裹时生效,当前你已经在外层包裹了Provider,因此实际生效的是Provider传递的null值,默认值不会生效。

修复方案

第一步:改造App.js,增加用户预加载逻辑与加载状态

在App组件挂载时就触发用户信息拉取,加载完成前渲染全局加载态,避免路由组件提前拿到未初始化的user值:

const App = (props) => {
  const [user, setUser] = useState(null);
  // 新增用户加载状态
  const [userLoading, setUserLoading] = useState(true);

  useEffect(() => {
    const loadCurrentUser = async () => {
      try {
        // 示例1:从localStorage读取已持久化的用户信息
        const savedUser = localStorage.getItem('currentUser');
        if (savedUser) {
          setUser(JSON.parse(savedUser));
        }
        // 示例2:从后端接口拉取当前登录用户信息(推荐)
        // const userRes = await api.getCurrentLoginUser();
        // setUser(userRes.data);
      } catch (err) {
        console.error('获取用户信息失败,可跳转登录页', err);
      } finally {
        setUserLoading(false);
      }
    };
    loadCurrentUser();
  }, []);

  // 加载未完成时渲染全局加载态,不渲染路由内容
  if (userLoading) return <div>加载中...</div>;

  return (
    <div className="app">
      <UserContext.Provider value={{ user, setUser }}>
        <Switch>
          <Route path="/profile" exact component={Profile} />
          {/* 其他路由 */}
        </Switch>      
      </UserContext.Provider>
    </div>
  );
};

第二步:改造Profile.js,增加防御判断与正确的依赖声明

给初始化逻辑加用户存在判断,同时给useEffect添加正确依赖,避免无效执行:

const DashboardProfileModal = (props) => {
  const userContext = useContext(UserContext);
  // 给状态加初始空值,避免undefined告警
  const [name, setName] = useState('');
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [address, setAddress] = useState('');

  // 仅当user存在时执行初始化,依赖绑定user对象
  useEffect(() => {
    if (userContext?.user) {
      initializeFields();
    }
  }, [userContext?.user]);

  const initializeFields = () => {
    // 加可选链兜底,避免属性不存在时报错
    setName(userContext.user?.name || '');
    setUsername(userContext.user?.username || '');
    setPassword(userContext.user?.password || '');
    setAddress(userContext.user?.address || '');
  };
  // 剩余表单渲染逻辑
};

额外优化建议

后续修改用户信息(登录、修改个人资料等场景)时,同步将用户信息持久化到localStorage,确保刷新时可以直接读取到最新数据:

// 示例:更新用户信息时的逻辑
const handleSaveUser = (newUserInfo) => {
  setUser(newUserInfo);
  localStorage.setItem('currentUser', JSON.stringify(newUserInfo));
}

内容的提问来源于stack exchange,提问作者demiglace

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:24:04