React如何在导航栏Navbar上显示已登录用户的用户名
问题根源
- App.js 底部冗余放置了 Login 组件,和路由匹配渲染的 Login 是两个完全独立的组件实例,登录页触发的方法无法同步到 App 的全局状态
- 路由定义的 Login 组件未传入
putName回调方法,登录操作无法通知 App 更新用户名状态 - 登录按钮点击时 axios 异步请求还未返回,直接取
LoginStatus是旧值,且传递参数时多套了一层对象,导致 App 拿到的不是纯用户名字符串 - 页面刷新时 App 的
name状态会重置,未主动从后端同步登录状态,导致导航栏用户名消失
可行修改方案(无需Redux)
1. 修改 App.js
首先删除底部冗余的 Login 组件标签,新增初始化时拉取登录状态的逻辑,给路由内的 Login 组件传入回调方法:
import "bootstrap/dist/css/bootstrap.min.css"; import React, { useState, useEffect } from "react"; import { BrowserRouter, Switch, Route } from "react-router-dom"; import axios from "axios"; import "./App.css"; // 其余原有导入保持不变 import Nav from "./components/nav_component"; axios.defaults.withCredentials = true; function App() { const [name, setName] = useState(""); // 页面初始化/刷新时主动拉取登录状态 useEffect(() => { axios.get("http://localhost:8000/login").then((response) => { if (response.data.loggedIn === true) { setName(response.data.user[0].UserFullName); } }); }, []); return ( <BrowserRouter> <div className="App"> <Nav loginName={name} /> <Switch> <Route exact path="/" component={Home} /> <Route exact path="/cpmenter" component={CompanyMaster_Enter} /> {/* 修改Login路由,用render传递自定义props */} <Route exact path="/login" render={(props) => <Login {...props} putName={(username) => setName(username)} />} /> <Route exact path="/register" component={Register} /> {/* 其余原有路由保持不变 */} <Route component={notfound} /> </Switch> </div> </BrowserRouter> ); } export default App;
2. 修改 login_component
修复异步时序问题、参数传递问题,阻止表单默认提交刷新:
import "bootstrap/dist/css/bootstrap.min.css"; import React, { useState } from "react"; import axios from "axios"; import { useHistory } from "react-router-dom"; // 可选,用于登录成功跳转 function Login(props) { const [LoginID, setLoginID] = useState(""); const [Password, setPassword] = useState(""); const [LoginStatus, setLoginStatus] = useState(""); const history = useHistory(); // 可选 const login = (event) => { event.preventDefault(); // 阻止表单默认提交刷新页面 axios .post("http://localhost:8000/login", { LoginID: LoginID, Password: Password, }) .then((response) => { if (response.data.message) { setLoginStatus(response.data.message); } else { const username = response.data[0].UserFullName; setLoginStatus(username); props.putName(username); // 直接传递纯用户名字符串 history.push("/"); // 可选,登录成功后跳转到首页 } }); }; // 原有useEffect可以删除,App已经做了全局登录状态同步,保留也不影响运行 return ( <div className="App"> <div className="auth-wrapper"> <div className="auth-inner"> <form onSubmit={login}> <h3>Log In</h3> <div className="form-group"> <label>Login ID</label> <input type="text" className="form-control" placeholder="First Name" onChange={(e) => { setLoginID(e.target.value); }} /> </div> <div className="form-group"> <label>Password</label> <input type="password" className="form-control" placeholder="Password" onChange={(e) => { setPassword(e.target.value); }} /> </div> {/* 移除按钮原有onClick事件,统一用form的onSubmit触发登录 */} <button className="btn btn-primary btn-block" type="submit" > Login </button> </form> <h1>{LoginStatus}</h1> </div> </div> </div> ); } export default Login;
效果验证
修改后全局的Nav组件会直接从App的状态获取用户名,不需要给每个页面单独传props,刷新页面时App会主动拉取登录状态恢复用户名,切换任意页面都不会丢失显示。
内容的提问来源于stack exchange,提问作者Chirag Maurya
相关产品推荐
相关产品推荐

