React useAuth钩子返回null致私有路由无法访问问题排查
问题描述
我创建了useAuth钩子用于授权用户访问私有路由,授权Cookie已正确存储,但useAuth钩子却返回null。尝试打印setUser的值时,setUser(res.data.currentUser)后的日志未输出,而此前的日志能正常打印出正确的Cookie信息。手动访问私有路由时,useAuth返回的setUser为null,导致无法访问该路由。本项目采用React作为前端框架,Node.js+Express作为后端,我已尝试通过日志排查、使用useEffect调用相关函数,但仍未解决问题。
相关代码
useAuth钩子代码
import { useState, useContext, useEffect } from "react"; import { UserContext } from "./UserContext"; import axios from "axios"; export default function useAuth() { const { setUser } = useContext(UserContext); const [error, setError] = useState(null); useEffect(() => { console.log("USE effect"); setUserContext(); }); //set user in context and push them home const setUserContext = async () => { console.log("In here"); return await axios .get("auth/checkAuth") .then((res) => { console.log("RES>DATA = ", res.data.currentUser); // PRINTS THE CORRECT COOKIE VALUES setUser(res.data.currentUser); // THIS SEEMS TO BE NULL????? console.log("SET USER + ", setUser); // THIS DOES NOT PRINT }) .catch((err) => { setError(err); }); }; return { setUser, }; }
私有路由代码
import React, { useContext } from 'react'; import {Route, Redirect, Navigate} from 'react-router-dom'; import { UserContext } from '../hooks/UserContext'; import useAuth from '../hooks/useAuth'; export default function PrivateRoute({children}) { const auth = useAuth(); console.log("aUTH in priv = ", auth); return auth ? children : <Navigate to="/"/> }
App.js代码
import "./App.css"; import { Redirect, Route, Routes, Switch } from "react-router-dom"; import useFetch from "./useFetch"; import { useEffect, useState, useRef } from "react"; import axios from "axios"; import Activities from "./components/Activities"; import HomePage from "./components/Home"; import Map from "./components/Map"; import checkUser from "./hooks/checkUser"; import { UserContext } from "./hooks/UserContext"; import useFindUser from "./hooks/checkUser"; import PrivateRoute from "./components/PrivateRoute"; function App() { const [auth, setAuth] = useState(false); const [activities, setActivities] = useState([]); const notInitialRender = useRef(false); const { user, setUser, isLoading } = useFindUser(); // works as expected return ( <div className="App"> <UserContext.Provider value={{ user, setUser, isLoading }}> <Routes> <Route path="/" element={<HomePage />}></Route> <Route path="/Activities" element={<Activities />} /> <Route path="/Private" element={ <PrivateRoute> <Map /> </PrivateRoute> } /> </Routes> </UserContext.Provider> </div> ); } export default App;
Express的auth/checkAuth路由代码
export const checkAuth = (req, res) => { let currentUser; console.log("res.cookies = ", req); if (req.cookies.currentUser) { // res.send(200); currentUser = req.cookies.currentUser; // set to user object in cookies console.log("current user = ", currentUser); // return 200 status code } else { currentUser = null; } //res.json(currentUser); res.status(200).send({ currentUser }); };
Map私有组件代码
import react from 'react'; function Map() { <div> <p style={{color:'red'}}>You have access to the private route</p> </div> } export default Map;
UserContext代码
import { createContext } from "react"; export const UserContext = createContext("null");
问题分析与修复方案
核心问题点
useAuth返回值逻辑错误:当前返回的是{setUser}函数对象,而非用户授权状态(是否存在有效用户),导致私有路由判断依据错误。setUser调用后日志未执行:大概率是setUser为undefined,调用时抛出错误,但catch块未打印错误信息,无法定位问题。useEffect无依赖数组:导致组件每次渲染都重复调用setUserContext,引发无限循环。- 私有路由判断逻辑错误:用
setUser对象存在性作为授权依据,而非用户是否存在。 - Map组件语法错误:缺少
return语句,无法渲染内容。
修复步骤
1. 重构useAuth钩子,返回正确的授权状态
import { useState, useContext, useEffect } from "react"; import { UserContext } from "./UserContext"; import axios from "axios"; export default function useAuth() { const { user, setUser } = useContext(UserContext); const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(true); // 仅组件挂载时执行一次授权检查 useEffect(() => { const fetchAuthStatus = async () => { try { // 跨域场景需添加withCredentials: true确保Cookie被携带 const res = await axios.get("auth/checkAuth", { withCredentials: true }); console.log("RES>DATA = ", res.data.currentUser); if (res.data.currentUser) { setUser(res.data.currentUser); } console.log("SET USER 执行完成"); } catch (err) { setError(err); console.error("授权检查错误:", err); // 打印错误便于定位 } finally { setIsLoading(false); } }; fetchAuthStatus(); }, []); // 返回用户授权状态、加载状态、错误信息 return { isAuthenticated: !!user, // 转换为布尔值,存在用户则为true isLoading, error }; }
2. 修正私有路由的判断逻辑
import React from 'react'; import { Navigate } from 'react-router-dom'; import useAuth from '../hooks/useAuth'; export default function PrivateRoute({ children }) { const { isAuthenticated, isLoading } = useAuth(); // 加载中显示占位组件,避免跳转闪烁 if (isLoading) { return <div>加载中...</div>; } // 根据用户是否存在判断是否允许访问 return isAuthenticated ? children : <Navigate to="/" />; }
3. 修正UserContext默认值
import { createContext } from "react"; // 设置更合理的默认值结构,避免混淆 export const UserContext = createContext({ user: null, setUser: () => {}, isLoading: false });
4. 修复Map组件语法错误
import React from 'react'; function Map() { return ( <div> <p style={{color:'red'}}>You have access to the private route</p> </div> ); } export default Map;
内容的提问来源于stack exchange,提问作者program.exe
相关产品推荐
相关产品推荐

