Next.js路由向组件传值及LocalStorage存储失败问题求助
问题分析
- API路由调用localStorage报错:API路由运行在服务器端,
localStorage是浏览器专属API,服务器环境不存在该对象,因此报错,这部分代码完全无效,必须删除。 - LoginForm存值后Navbar无法读取:
- 登录成功判断逻辑错误:你用
data.status === 200判断,但后端返回的JSON中并没有status字段,应使用res.ok或res.status === 200。 - 未导入路由钩子:
router.push('/')会报错,因为没引入Next.js的useRouter,导致登录后无法跳转,Navbar可能无法重新渲染。 - Navbar的
useEffect仅执行一次:登录后跳转回首页时,Navbar已完成挂载,不会重新读取localStorage,状态无法更新。
- 登录成功判断逻辑错误:你用
修复代码示例
1. 修正API路由(移除localStorage相关代码)
import { NextResponse } from "next/server"; import { sql } from "@vercel/postgres"; export async function POST(req) { const body = await req.json(); const { username, password } = body; const resultat = await sql`SELECT * FROM Users WHERE username=${username} AND passwordhash=${password}`; if (resultat.rows.length === 0) { console.log("Authentification failed"); return NextResponse.json({ error: "Invalid credentials" }, { status: 404 }); } if (username === resultat.rows[0].username && password === resultat.rows[0].passwordhash) { console.log("Merge autentificarea"); return NextResponse.json({ message: "Logged In" }, { status: 200 }); } return NextResponse.json({ error: "Invalid credentials" }, { status: 404 }); }
2. 修正LoginForm组件(修复路由与判断逻辑)
"use client" import './LoginForm.css'; import Button from '../Button'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; const LoginForm = () => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const router = useRouter(); const onClickHandle = async () => { const res = await fetch("/api/login", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ username, password }), }); if (res.ok) { localStorage.setItem("auth", "true"); localStorage.setItem("username", username); router.push('/'); } else { const data = await res.json(); console.error("Login failed", data.error); } } return ( <div className="login-container"> <form className="login-form"> <h2>Login</h2> <div className="form-group"> <label htmlFor="username">Username:</label> <input type="text" id="username" onChange={(e) => setUsername(e.target.value)} required /> </div> <div className="form-group"> <label htmlFor="password">Password:</label> <input type="password" id="password" onChange={(e) => setPassword(e.target.value)} required /> </div> <div> <Button onClick={onClickHandle}>Log In</Button> </div> </form> </div> ); }; export default LoginForm;
注意:移除了Link包裹Button的写法,因为点击事件中已包含
router.push,重复包裹会导致跳转异常。
3. 修正Navbar组件(监听localStorage变化)
"use client" import "./Navbar.css" import Button from './Button'; import Link from 'next/link'; import { useState, useEffect } from 'react'; export default function Navbar(){ const [username, setUsername] = useState(""); useEffect(() => { const updateUsername = () => { if (typeof window !== "undefined") { const auth = localStorage.getItem("auth"); setUsername(auth ? localStorage.getItem("username") || "" : ""); } }; updateUsername(); // 监听localStorage变化,同步更新状态 window.addEventListener('storage', updateUsername); return () => window.removeEventListener('storage', updateUsername); }, []); return ( <nav className="navbar"> <div className="container"> <ul className="nav-links"> <li> <Link href="/"> <Button>Home</Button> </Link> </li> </ul> </div> <div> <Link href='/categories'><Button>Categorii</Button></Link> </div> <div> <Link href="/newreleases"><Button>New Releases</Button></Link> </div> <div> <Link href='/search'><Button>Search</Button></Link> </div> {!username ? ( <div> <Link href='/login'><Button>Log In</Button></Link> </div> ) : ( <div> <Link href='/'><Button>{username}</Button></Link> </div> )} </nav> ) }
优化了登录状态显示逻辑,添加
storage事件监听,确保其他页面修改localStorage时Navbar能同步更新。
其他可行的传值/状态管理方式
- React Context:创建AuthContext,登录成功后更新Context中的用户信息,Navbar直接从Context读取,无需依赖localStorage,适合小型项目。
- 轻量状态管理库(Zustand/Jotai):相比Context更简洁,无需层层包裹,组件可直接订阅状态,登录时更新状态后Navbar实时获取。
- NextAuth.js:专业身份验证方案,支持Session管理,服务器端与客户端均可获取用户信息,安全性更高,适合需要完善身份验证的项目。
- Cookie存储:API路由登录成功后设置HttpOnly Cookie存储用户信息,服务器端渲染时可直接读取Cookie,适合需要SSR显示用户信息的场景。
内容的提问来源于stack exchange,提问作者Riippeerreerr
相关产品推荐
相关产品推荐

