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

在App.jsx中访问AuthDataContext报错,请求排查问题原因

问题分析与解决

问题描述

在App.jsx中尝试从AuthDataContext获取用户数据时,出现错误:

Uncaught TypeError: Cannot destructure property 'user' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is null

用户已用AuthContext包裹组件,但仍无法访问上下文。

核心原因

你的App组件是AuthContext的父级组件,而非子组件。React Context的规则是:只有被Provider包裹的子组件才能通过useContext获取到上下文数据。当前App组件在AuthContext.Provider的外层,自然拿不到上下文值,只能拿到createContext初始化的null。

另外,原AuthContext组件存在一个小问题:onAuthStateChanged直接写在组件顶层,会导致每次组件渲染都重复注册监听,引发不必要的重渲染和潜在内存泄漏。

解决方案

步骤1:修复AuthContext的监听逻辑

将onAuthStateChanged放入useEffect中,确保只注册一次监听,并在组件卸载时清理:

// Authentication Context
import { createContext, useState, useEffect } from "react";
import { getAuth, onAuthStateChanged } from "firebase/auth";

export const AuthDataContext = createContext(null);

export default function AuthContext({ children }) {
  const auth = getAuth();
  const [user, setUser] = useState(null);

  useEffect(() => {
    // 注册auth状态变更监听
    const unsubscribe = onAuthStateChanged(auth, (user) => {
      setUser(user ?? null);
    });

    // 组件卸载时取消监听,避免内存泄漏
    return unsubscribe;
  }, [auth]);

  return (
    <AuthDataContext.Provider value={{ user, setUser }}>
      {children}
    </AuthDataContext.Provider>
  );
}

步骤2:将AuthContext的包裹层级移到App外层

修改项目入口文件(通常是index.js),用AuthContext包裹整个App,让App成为Context的子组件:

// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import AuthContext from './context/Auth-Context';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <AuthContext>
      <App />
    </AuthContext>
  </React.StrictMode>
);

步骤3:调整App组件的结构

移除App组件内部的AuthContext包裹,现在App已处于Context的覆盖范围内,可以正常使用useContext:

// App.jsx
...other code
import ContextProviders from "./context/Context-Config";
import { AuthDataContext } from "./context/Auth-Context";
import { useContext } from 'react';

export default function App() {
  ...other code

  // 现在可以正常获取上下文数据
  const { user, setUser } = useContext(AuthDataContext);

  return (
    <ContextProviders
      configs={configs}
      genres={{
        genresMovie,
        genresTv,
      }}
      bookmarkShows={{
        bookmarkShows,
        setBookmarkShows,
        bookmarksTrace,
        setBookmarksTrace,
      }}
      movies={{
        trendingMovies,
        popularMovies,
        topRatedMovies,
        upcomingMovies,
        nowPlayingMovies,
      }}
      tv={{
        popularTv,
        topRatedTv,
        airingTodayTv,
        onTheAirTv,
      }}
    >
      <div className="App">
        <Navbar />
        <SearchBar />
        <Outlet />
      </div>
    </ContextProviders>
  );
}

替代方案

如果不想修改入口文件,也可以将需要使用user的逻辑移到App的子组件(比如Navbar、SearchBar)中,这些组件本来就在AuthContext的覆盖范围内,直接在子组件中使用useContext即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:46:19