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

为什么三元运算符会破坏我PERN栈项目的登录路由功能?

问题修复点

前端问题(App.jsx)

  1. 状态更新逻辑被注释:你用来更新isAuthenticated的三元判断代码是注释状态,自然无法同步授权状态
  2. useEffect无依赖数组:会导致每次组件渲染都重复调用校验接口,触发无限重渲染
  3. Hook调用顺序错误:useState声明放在了useEffect之后,违反React Hook调用顺序规则,会引发不可预期的异常
  4. 无token场景未兼容:未判断localStorage.token是否存在就直接放到请求头,会给后端传无效的undefined值
  5. 未处理请求异常状态:未判断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;

后端问题

  1. 日志方法拼写错误:错误捕获里的console.err应为console.error,会导致报错时无法正常打印日志
  2. 需确认/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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:48:04