我尝试使用react的useEffect钩子来呈现一个组件(SideNavbar),但该组件(SideNavbar)在我手动重新加载页面之前没有变化。当我重新加载页面时,系统工作,但我如何才能做到这一点,而不必手动重新加载页面。
我需要删除一个Sidenavbar时,用户没有登录,并显示导航栏时,用户登录。如何在用户成功登录后立即重新呈现组件?如何在用户注销后立即隐藏组件(SideNavbar)。
import Navbar from "./Components/Navbar";
import React, { useEffect, useState } from "react";
import { Route,Routes } from "react-router";
import Home from "./Routes/Home";
import Contact from "./Routes/Contact";
import Enroll from "./Routes/Enroll";
import Login from "./Routes/Login";
import SideNavbar from "./Components/InnerComponents/SideNavbar";
import Profile from './Routes/Admin/Profile';
import Notice from './Routes/Admin/Notice';
import Result from './Routes/Admin/Result';
import StudentList from "./Routes/Admin/StudentList";
import TeacherList from "./Routes/Admin/TeacherList";
import Classroom from "./Routes/Admin/Classroom";
import NoticeState from "./context/notices/NoticeState";
import NewAccount from "./Routes/Admin/NewAccount.js"
import UserState from "./context/user/UserState";
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(()=>{
if(localStorage.getItem('token')){
setIsLoggedIn(true);
}
},[localStorage.getItem('token')])
return (
<div className="App">
<UserState>
<NoticeState>
<Navbar/>
{isLoggedIn && <SideNavbar/>}
<div className="containerApp">
<Routes>
<Route element={<NewAccount/>} exact path='/newaccount' />
<Route element={<Profile/>} exact path='/profile' />
<Route element={<Notice/>} exact path="/notice"/>
<Route element={<Result/>} exact path="/result"/>
<Route element={<TeacherList/>} exact path="/teacherList" />
<Route element={<Classroom/>} exact path="/classroom" />
<Route element={<StudentList/>} path="/classroom/:classID"/>
<Route element={<Home/>} exact path='/' />
<Route element={<Contact/>} exact path='/contact' />
<Route element={<Enroll/>} exact path='/enroll' />
<Route element={<Login/>} exact path='/login' />
</Routes>
</div>
</NoticeState>
</UserState>
</div>
);
}
export default App;
2条答案
按热度按时间mqkwyuun1#
问题出在这个
useEffect
因为在deps数组中,有
localStorage.getItem('token')
,它被调用once,<App/>
没有理由重新渲染(这是由setState
引起的)。最快的解决方案是创建一个定期检查,检查localStorage
中是否有令牌。它会工作,但这不是一个理想的解决方案。以下是一些原因:
1.令牌检查-事实上,您拥有令牌并不意味着您已登录。应该检查令牌是否有效、是否过时、是否来自正确的发行者等等。有一些指导如何更正确地做到这一点:oAuth guide,another quite comprehensive guide .你可以在互联网上找到一吨。
1.安全性-将令牌存储在
localStorage
中很方便,但也有很多很多缺点。它很容易泄漏,所以这不是一个推荐的方法。您可以在this SO post中阅读更多内容。1.定期检查--这些都远非理想。由于
React
React系统和自动更新,例如setState
或React.Context
值更改,我们应该寻找一个解决方案,在登录并获得令牌后,将导致自动重新呈现<App/>
,例如通过更新React.Context
值,设置状态。提示是,您应该通过设置一个将更新<App/>
组件的值,在成功登录时触发此重新呈现。React
将负责与重新渲染和显示Sidebar
相关的其余工作。dy2hfwbg2#
当用户成功登录/注销时,需要重新渲染组件。使用useEffect依赖性,如下面代码所述。
查看更新的代码。