React如何在登录页底部展示useState存储的详情并实现跨页传值
React登录页用户数据展示+跨页传值实现
修复原代码的已知问题
先调整几个容易引发异常的问题:
- 原代码中组件名和登录点击处理函数都叫
Login,存在命名冲突,把点击处理函数重命名为handleLogin - 原代码在fetch外层打印
details拿不到最新值:React的setState是异步执行的,请求刚发完时打印的state还是旧值,需要查看值可以用useEffect监听details变化再输出 - 补充接口请求错误捕获,避免接口报错时页面白屏
1. 登录页底部展示学生数据
你已经通过第二次fetch请求拿到学生数据存在details状态里,只需要在表单下方加判断:当details存在有效用户id时,渲染对应字段即可,避免页面刚加载时details是空对象导致渲染异常。
对应渲染代码加在你标注注释的位置即可,示例:
{/* 学生详情展示区域 */} {details.id ? ( <div className="student-details" style={{marginTop: '2rem', padding: '1rem', border: '1px solid #eee', borderRadius: '4px'}}> <h4>当前登录学生信息</h4> <p style={{margin: '0.5rem 0'}}>学生ID:{details.id}</p> <p style={{margin: '0.5rem 0'}}>姓名:{details.fname} {details.lname}</p> <p style={{margin: '0.5rem 0'}}>邮箱:{details.email}</p> </div> ) : null}
2. 跨页面传递学生数据
根据项目复杂度选方案即可,登录场景优先用持久化存储+全局状态的方案,避免刷新页面丢数据:
方案1:路由传参(适合简单项目、少量页面跳转用)
你已经引入了useNavigate,拿到学生数据后跳转路由时,把数据存在路由state里传递即可:
- 在
setDetails(result)之后加跳转逻辑:
.then((result)=>{ setDetails(result); // 跳转到登录后的目标页面,把学生数据带过去 navigate('/dashboard', { state: { studentInfo: result } }) })
- 在目标页面用
useLocation取数据:
import { useLocation } from 'react-router-dom' const Dashboard = () => { const location = useLocation() const studentInfo = location.state?.studentInfo // 直接用studentInfo渲染即可 return <div>欢迎你,{studentInfo?.fname}</div> }
注意:这个方案刷新页面后路由state会丢失,不适合长期存储登录态
方案2:本地存储+全局状态(推荐登录场景用)
登录成功后把学生数据存在sessionStorage/localStorage里,刷新页面数据不会丢,配合Context做全局取值,所有页面都能直接拿到用户信息,不用逐层传props:
- 拿到数据后存入本地存储:
.then((result)=>{ setDetails(result); // 存入sessionStorage,关闭标签页自动清除;要长期保留登录态就换localStorage sessionStorage.setItem('studentInfo', JSON.stringify(result)) navigate('/dashboard') })
- 如果项目已经用了Redux/Zustand等状态管理库,直接把用户数据存在全局store里即可,全项目任意组件都能直接读取。
修正后的完整Login组件代码
import './Login.css' import { FcGoogle } from "react-icons/fc" import { FaGithub, FaFacebook } from "react-icons/fa" import { Link } from 'react-router-dom' import React from 'react' import { useNavigate } from 'react-router-dom' import { useEffect } from 'react' const Login = () =>{ const showConsole =()=>{ console.log("I am google, facebook, github"); } const navigate = useNavigate(); const [email, setEmail] = React.useState(""); const [password, setPassword] = React.useState(""); const [details, setDetails] = React.useState({}); // 监听details变化,打印最新值 useEffect(() => { if(details.id) console.log('最新学生数据:', details) }, [details]) // 重命名处理函数,避免和组件名冲突 async function handleLogin(){ let item = {password, email}; console.log(item); try { const loginRes = await fetch("http://localhost:8080/student/login",{ method:'POST', body:JSON.stringify(item), headers:{ "Content-Type":'application/json', "Accept":'application/json' } }) if(loginRes.status === 200){ console.log("登录成功") window.alert("Student Logged in successfully"); const studentRes = await fetch(`http://localhost:8080/student/oneStudentEmail?email=${email}`,{ method:'GET', headers:{ "Content-Type":'application/json', "Accept":'application/json' } }) const result = await studentRes.json() setDetails(result); // 选择对应跨页传值逻辑即可,示例为本地存储+跳转 sessionStorage.setItem('studentInfo', JSON.stringify(result)) navigate('/dashboard') }else{ console.log("账号密码错误",item) window.alert("账号或密码错误"); } } catch (err) { console.log('请求出错', err) window.alert("登录请求失败,请检查网络") } } return ( <> <div className='main_login'> <div><button className="btn_google" onClick={showConsole}><FcGoogle /></button></div> <div><button className="btn_github" onClick={showConsole}><FaGithub /></button></div> <div><button className="btn_facebook" onClick={showConsole}><FaFacebook /></button></div> <div className="col-sm-6 offset-sm-3"> <h3>Enter Details</h3> <input type="text" className="form-control" placeholder="Email" value={email} onChange={(e)=>{setEmail(e.target.value)}} /><br/> <input type="password" className="form-control" placeholder="Password" value={password} onChange={(e)=>setPassword(e.target.value)} /><br/> <button className="btn btn-primary" onClick={handleLogin} > Login </button><br/> Already have an Account?<Link to="/sign-up">Sign Up</Link> {/* 底部展示学生信息 */} {details.id ? ( <div className="student-details" style={{marginTop: '2rem', padding: '1rem', border: '1px solid #eee', borderRadius: '4px'}}> <h4>当前登录学生信息</h4> <p style={{margin: '0.5rem 0'}}>学生ID:{details.id}</p> <p style={{margin: '0.5rem 0'}}>姓名:{details.fname} {details.lname}</p> <p style={{margin: '0.5rem 0'}}>邮箱:{details.email}</p> </div> ) : null} </div> </div> </> ) } export default Login;
内容的提问来源于stack exchange,提问作者S Sahoo
相关产品推荐
相关产品推荐

