为什么三元运算符会破坏我PERN栈项目的登录路由功能?
问题修复点
前端问题(App.jsx)
- 状态更新逻辑被注释:你用来更新
isAuthenticated的三元判断代码是注释状态,自然无法同步授权状态 - useEffect无依赖数组:会导致每次组件渲染都重复调用校验接口,触发无限重渲染
- Hook调用顺序错误:
useState声明放在了useEffect之后,违反React Hook调用顺序规则,会引发不可预期的异常 - 无token场景未兼容:未判断
localStorage.token是否存在就直接放到请求头,会给后端传无效的undefined值 - 未处理请求异常状态:未判断fetch响应的HTTP状态是否合法,接口401/500时会直接抛出JSON解析错误
修复后的前端代码
import React, { Fragment, useState, useEffect } from "react"; import './App.css'; import { BrowserRouter as Router, Switch, Route, Redirect } from "react-router-dom"; //components import Dashboard from "./components/Dashboard"; import Login from "./components/Login"; import Register from "./components/Register"; function App() { // 把state声明放到最前面,符合Hook调用顺序 const [isAuthenticated, setIsAuthenticated] = useState(false); async function isAuth() { // 先判断有没有token,没有直接返回未授权 if (!localStorage.token) { setIsAuthenticated(false); return; } try { const response = await fetch("http://localhost:4000/api/v1/auth/verify/", { method: "GET", headers: { jwt_token : localStorage.token } }); // 先判断请求是否成功 if (!response.ok) { setIsAuthenticated(false); return; } const parseRes = await response.json(); // 打开注释的状态更新逻辑 parseRes === true ? setIsAuthenticated(true) : setIsAuthenticated(false); } catch (err) { console.error(err.message); setIsAuthenticated(false); } } // 加空依赖数组,只在组件挂载时执行一次校验 useEffect(() => { isAuth() }, []) const setAuth = boolean => { setIsAuthenticated(boolean); }; return ( <Fragment> <Router> <div className="container"> <Switch> <Route exact path="/login" render={props => !isAuthenticated ? ( <Login {...props} setAuth={setAuth} /> ) : ( <Redirect to="/dashboard" /> ) } /> <Route exact path="/register" render={props => !isAuthenticated ? ( <Register {...props} setAuth={setAuth} /> ) : ( <Redirect to="/dashboard" /> ) } /> <Route exact path="/dashboard" render={props => isAuthenticated ? ( <Dashboard {...props} setAuth={setAuth} /> ) : ( <Redirect to="/login" /> ) } /> </Switch> </div> </Router> </Fragment> ); } export default App;
后端问题
- 日志方法拼写错误:错误捕获里的
console.err应为console.error,会导致报错时无法正常打印日志 - 需确认
/api/v1/auth/verify接口逻辑:确保该接口在JWT校验通过时返回布尔值true,校验失败/无token时返回false,与前端判断逻辑对齐
修复后的后端dashboard路由代码
const router = require("express").Router(); const db = require("../db"); const authorization = require('../middleware/authorization'); router.get("/", authorization, async(req, res) => { try { // req.user comes from authorization, contains jwt payload const user = await db.query("SELECT user_name, user_email FROM users WHERE user_id = $1", [req.user]); res.json(user.rows[0]); } catch (err) { // 修正拼写错误 console.error(err.message) res.status(500).json("Server Error"); } }); module.exports = router;
内容的提问来源于stack exchange,提问作者dxandersz
相关产品推荐
相关产品推荐

