React Use Context报错:无法解构undefined的token属性及问题排查
解决React Context路由校验报错:Cannot destructure property 'token' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined
问题描述
尝试将token和用户信息存储在React Context中,从已有的cookie中获取数据并设置到状态后,校验用户权限以控制路由访问。但访问路由时触发报错:
Cannot destructure property 'token' of '(0 , react__WEBPACK_IMPORTED_MODULE_0__.useContext)(...)' as it is undefined
相关代码
authProvider.js
import React, { createContext, useEffect, useState } from "react"; import { useCookies } from "react-cookie"; import { useNavigate } from "react-router-dom"; export const AuthContext = createContext(); export const AuthProvider = ({ children }) => { const [token, setToken] = useState(null); const [userInfo, setUserInfo] = useState(null); const [cookies] = useCookies(["userToken", "userInfo"]); const navigate = useNavigate(); useEffect(() => { console.log(cookies.userInfo); console.log(cookies.userToken); setToken(cookies.userToken); setUserInfo(cookies.userInfo); }, [cookies]); return ( <AuthContext.Provider value={{ token, userInfo, setToken, setUserInfo, }} > {children} </AuthContext.Provider> ); };
index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from 'react-router-dom'; import App from './App'; import {AuthProvider} from './context/authProvider'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <BrowserRouter> <AuthProvider> <App /> </AuthProvider> </BrowserRouter> </React.StrictMode> );
AppRoutes.js
import { Route, Routes } from "react-router-dom"; import React from "react"; import Login from "./Login/Login"; // import Home from "./Home/Home" import Register from "./Register/Register"; // import Cookies from "js-cookie"; import Dashboard from "./Dashboard/Dashboard"; import Tasks from "./Tasks/Tasks"; import Schedule from "./Schedule/Schedule"; import PomodoroPage from "./Pomodoro/PomodoroPage"; import Goals from "./Goals/Goals"; import Journals from "./Journals/Journals"; import AppLayout from "../Components/AppLayout/AppLayout"; import Logout from "./Logout/Logout"; import { Toaster } from "react-hot-toast"; import PrivateRoutes from "./PrivateRoutes/PrivateRoutes"; function AppRoutes() { return ( <div className="appRoutes"> <Routes> <Route path="/login" element={<Login />} /> <Route path="/register" element={<Register />} /> <Route element={<PrivateRoutes />}> <Route path="/logout" element={<Logout />} /> <Route path="/app" element={<AppLayout />}> <Route index element={<Dashboard />} /> <Route path="tasks" element={<Tasks />} /> <Route path="schedule" element={<Schedule />} /> <Route path="pomodoro" element={<PomodoroPage />} /> <Route path="goals" element={<Goals />} /> <Route path="journals" element={<Journals />} /> </Route> </Route> </Routes> <Toaster /> </div> ); } export default AppRoutes;
PrivateRoutes.jsx(错误版本)
import { Outlet, useNavigate } from "react-router-dom"; import { useContext, useEffect } from "react"; import {AuthProvider} from "../../context/authProvider"; const PrivateRoutes = () => { const navigate = useNavigate(); const { token, userInfo } = useContext(AuthProvider); console.log(token); useEffect(() => { if (!token || !userInfo) { navigate('/login'); } }, [token, userInfo, navigate]); return <Outlet />; } export default PrivateRoutes
错误原因
在PrivateRoutes.jsx中,调用useContext时传入了组件提供者AuthProvider,而非上下文对象AuthContext。useContext需要接收通过createContext()创建的上下文对象才能获取对应的值,传入组件会导致返回undefined,进而解构token时触发报错。
修正方案
修改PrivateRoutes.jsx中的导入和useContext参数,替换为AuthContext:
修正后的PrivateRoutes.jsx
import { Outlet, useNavigate } from "react-router-dom"; import { useContext, useEffect } from "react"; // 导入AuthContext而非AuthProvider import { AuthContext } from "../../context/authProvider"; const PrivateRoutes = () => { const navigate = useNavigate(); const { token, userInfo } = useContext(AuthContext); console.log(token); useEffect(() => { if (!token || !userInfo) { navigate('/login'); } }, [token, userInfo, navigate]); return <Outlet />; } export default PrivateRoutes
修正后,useContext可以正确从AuthContext中获取token和userInfo,路由权限校验逻辑即可正常执行。
内容的提问来源于stack exchange,提问作者abdelrahman-assoum
相关产品推荐
相关产品推荐

