[英]Navbar not updating upon pressing the logout button, only after refreshing the page
我正在嘗試使用 useContext 作為全局狀態管理器。 用戶注銷確實有效,但導航欄上的信息在我點擊刷新之前不會反映此更改。 為什么它不特別更新導航欄超出了我的理解,因為按下注銷按鈕正確地將用戶路由回登錄頁面,但在用戶刷新之前不會更新導航欄。 基本上,需要的是導航欄的用戶信息在點擊注銷后立即更新,而不是在用戶刷新或轉到另一個頁面時更新。
下面是我的相關代碼。
const Logout = () => {
const navigate = useNavigate();
const { user } = useContext(ContextHolder);
useEffect(() => {
const onLogoutSuccess = () => {
_logger('Logged out successfully.');
toast('You have been logged out');
navigate('/login');
};
const onLogoutError = (message) => {
_logger('Logout failed:', user.email + ' ' + message);
navigate('/');
};
userService.logout().then(onLogoutSuccess).catch(onLogoutError);
}, []);
return <>Logging out ...</>;
};
export default Logout;
const defaultUser = {
id: 0,
roles: [],
email: '',
isLoggedIn: false,
};
const ContextHolder = React.createContext({
user: defaultUser,
});
export default ContextHolder;
const NavBar = () => {
const { user } = useContext(ContextHolder);
return (
<Navbar collapseOnSelect expand="lg" className="py-lg-3 navbar" variant="light">
<div className="d-flex justify-content-center mx-4">
<Navbar.Brand href="/" className="me-lg-5">
<img src={logo} alt="" className="logo-dark" height="50px" />
</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav">
<i className="mdi mdi-menu"></i>
</Navbar.Toggle>
<Navbar.Collapse id="responsive-navbar-nav">
<Nav as="ul" className="me-auto align-items-center">
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<AiOutlineLink /> <Nav.Link href="/listings">View Listings</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<MdOutlineQuestionAnswer /> <Nav.Link href="/faq">FAQs</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<BsFillPeopleFill /> <Nav.Link href="/blogs">Blogs</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<AiFillPhone /> <Nav.Link href="/contactus">Contact</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<RiProfileLine /> <Nav.Link href="/profile">Profile</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<BiMap /> <Nav.Link href="/location">Location</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<GoVerified /> <Nav.Link href="/location/verification">Location Verification</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light text-nowrap border-0 text-center">
<TbInfoCircle /> <Nav.Link href="/AboutUs">About Us</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0 text-center">
<FaCogs /> <Nav.Link href="/externallinks">External Links</Nav.Link>
</Nav.Item>
<Nav.Item className="mx-lg-1 btn btn-outline-light border-0">
<GoChecklist /> <Nav.Link href="/venues">Venues</Nav.Link>
</Nav.Item>
</Nav>
<Nav className="ms-auto align-items-center">
{user.isLoggedIn ? (
<React.Fragment>
<Nav.Item className="me-0 text-center">
<span className="text-dark fw-bold"> Welcome back, {user.email}!</span>
</Nav.Item>
<Nav.Item>
<Link
to="/logout"
className="mx-3 btn btn-sm btn-outline-dark d-none d-lg-inline-flex mt-1"
style={{ width: '80px' }}>
Log Out
</Link>
</Nav.Item>
</React.Fragment>
) : (
<Nav.Item className="me-0">
<Nav.Link href="/login" target="_self" className="d-lg-none">
Log In
</Nav.Link>
<Link
to="/login"
target="_self"
className="mx-3 btn btn-sm btn-outline-dark d-none d-lg-inline-flex">
Log In
</Link>
</Nav.Item>
)}
</Nav>
</Navbar.Collapse>
</div>
</Navbar>
);
};
NavBar.propTypes = {
currentUser: PropTypes.shape({
id: PropTypes.number,
roles: PropTypes.arrayOf(PropTypes.string),
email: PropTypes.string,
isLoggedIn: PropTypes.bool,
}),
};
export default NavBar;
所有相關組件都無法知道變量“user”在任何給定時刻發生了變化,因為“user”不是一個狀態。 現在,react 通過“靜態”渲染您的組件,並且據其所知,“永不改變的變量”解釋了為什么視圖只有在刷新后才能正確渲染。 你應該像這樣創建一個狀態
const [user, setUser] = useState(defaultUser);
此外,您應該使用上下文提供程序包裝您的代碼,並在“value”屬性中添加“用戶”狀態,同時傳遞“setUser”函數,以便您可以在任何給定時刻從應用程序設置用戶。 在你的情況下:
<ContextHolder.Provider value={{ user, setUser }}>
...
</ContextHolder.Provider>
總而言之,您的代碼應如下所示:
const defaultUser = { ... };
function App () {
const [user, setUser] = useState(defaultUser);
return (
<ContextHolder.Provider value={{ user, setUser }}>
<NavBar />
<Logout />
...etc..
</ContextHolder.Provider>
)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.