如何在不使用 Redux 的情况下显示隐藏基于身份验证的注销按钮?
How can I show hide my logout button based on authentication without using Redux?
使用下面的代码,只有当我在成功登录后刷新页面时,注销按钮才会显示。该功能按预期工作,所以没有问题。
此外,我想在用户成功登录 而不 刷新页面时在导航栏上显示注销按钮。
我尝试了很多方法来解决这个问题,但都无济于事。
在我的研究过程中,我遇到了一个叫做 Redux Persist 的东西,但我不确定在这种情况下是否值得使用它。有没有一种方法可以在不使用 Redux 的情况下处理这个问题?
我愿意编写我的代码 improvements/suggestions。提前致谢。
import { Navbar, Nav, Container, Button } from 'react-bootstrap';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
import {useEffect, useState} from "react";
const NavBar = () => {
let history = useHistory();
const [loggedInUser, setLoggedInUser] = useState("");
useEffect(() => {
const loggedInUser = localStorage.getItem("loginToken");
console.log(loggedInUser);
setLoggedInUser(loggedInUser);
});
const logout = (e) => {
e.preventDefault();
const headers = {
"Accept" : "application/json",
"Authorization" : `Bearer ${localStorage.getItem('loginToken')}`
};
axios.post('http://website.test/api/logout', null, {headers})
.then(res => {
console.log(res);
if(res.status === 200) {
localStorage.clear();
return history.push('/');
}
}).catch(err => {
console.log(err);
});
};
return (
<>
<Navbar bg="dark" variant="dark">
<Container>
<Navbar.Brand href="#home">Navbar</Navbar.Brand>
{ loggedInUser ? <Nav className="me-auto"><Button onClick={logout}>Logout</Button></Nav> : null }
</Container>
</Navbar>
</>
);
}
export default NavBar;
首先,我不喜欢Redux(也许和你一样),我使用React Tracked(https://github.com/dai-shi/react-tracked),它有一些类似Redux的功能,但使用起来非常简单。
其次,你应该通过dispatch调用APIquery,方便你的逻辑代码的读写。
与 Redux 一样,React Tracked 使用中心状态,但仅在需要时重新加载组件,而不是同时重新加载所有组件。
我的回答是:不刷新页面,不使用 Redux,使用 React Tracked!
注意:useEffect()
应该像这样调用空依赖项:useEffect(()=> {}, [])
在localStorage.clear();
之前你必须添加setLoggedInUser(false);
,如果你在这里放置return history.push('/');
,你的页面将被重新加载!
如果本地存储发生变化,React 不会收到“通知”。 React 仅对状态(useState、context、redux 等)变化做出反应。最简单的方法是这样的:
--App.jsx
const App = () => {
const [userState, setUserState] = useState(localStorage.getItem("loginToken"));
return (
<>
<Navigation userState={userState} setUserState={setUserState} />
{!userState && <Login setUserState={setUserState} />}
</>
)
}
--Login.jsx
const Login = ({ setUserState }) => {
const onLoginButtonClick = () => {
//.. do api request
setUserState('myState')
}
return (
<button onClick={onButtonClick} />
)
}
--Navigation.jsx
const Navigation = ({ userState, setUserState }) => {
const onLogoutButtonClick => {
//..do api request
localStorage.setItem('loginToken', null);
setUserState(null);
}
return (
<>
<div>some things</div>
{ userState && <button onClick={onLogoutButtonClick}>logout</button> }
</>
)
}
使用下面的代码,只有当我在成功登录后刷新页面时,注销按钮才会显示。该功能按预期工作,所以没有问题。
此外,我想在用户成功登录 而不 刷新页面时在导航栏上显示注销按钮。
我尝试了很多方法来解决这个问题,但都无济于事。
在我的研究过程中,我遇到了一个叫做 Redux Persist 的东西,但我不确定在这种情况下是否值得使用它。有没有一种方法可以在不使用 Redux 的情况下处理这个问题?
我愿意编写我的代码 improvements/suggestions。提前致谢。
import { Navbar, Nav, Container, Button } from 'react-bootstrap';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
import {useEffect, useState} from "react";
const NavBar = () => {
let history = useHistory();
const [loggedInUser, setLoggedInUser] = useState("");
useEffect(() => {
const loggedInUser = localStorage.getItem("loginToken");
console.log(loggedInUser);
setLoggedInUser(loggedInUser);
});
const logout = (e) => {
e.preventDefault();
const headers = {
"Accept" : "application/json",
"Authorization" : `Bearer ${localStorage.getItem('loginToken')}`
};
axios.post('http://website.test/api/logout', null, {headers})
.then(res => {
console.log(res);
if(res.status === 200) {
localStorage.clear();
return history.push('/');
}
}).catch(err => {
console.log(err);
});
};
return (
<>
<Navbar bg="dark" variant="dark">
<Container>
<Navbar.Brand href="#home">Navbar</Navbar.Brand>
{ loggedInUser ? <Nav className="me-auto"><Button onClick={logout}>Logout</Button></Nav> : null }
</Container>
</Navbar>
</>
);
}
export default NavBar;
首先,我不喜欢Redux(也许和你一样),我使用React Tracked(https://github.com/dai-shi/react-tracked),它有一些类似Redux的功能,但使用起来非常简单。
其次,你应该通过dispatch调用APIquery,方便你的逻辑代码的读写。
与 Redux 一样,React Tracked 使用中心状态,但仅在需要时重新加载组件,而不是同时重新加载所有组件。
我的回答是:不刷新页面,不使用 Redux,使用 React Tracked!
注意:useEffect()
应该像这样调用空依赖项:useEffect(()=> {}, [])
在localStorage.clear();
之前你必须添加setLoggedInUser(false);
,如果你在这里放置return history.push('/');
,你的页面将被重新加载!
如果本地存储发生变化,React 不会收到“通知”。 React 仅对状态(useState、context、redux 等)变化做出反应。最简单的方法是这样的:
--App.jsx
const App = () => {
const [userState, setUserState] = useState(localStorage.getItem("loginToken"));
return (
<>
<Navigation userState={userState} setUserState={setUserState} />
{!userState && <Login setUserState={setUserState} />}
</>
)
}
--Login.jsx
const Login = ({ setUserState }) => {
const onLoginButtonClick = () => {
//.. do api request
setUserState('myState')
}
return (
<button onClick={onButtonClick} />
)
}
--Navigation.jsx
const Navigation = ({ userState, setUserState }) => {
const onLogoutButtonClick => {
//..do api request
localStorage.setItem('loginToken', null);
setUserState(null);
}
return (
<>
<div>some things</div>
{ userState && <button onClick={onLogoutButtonClick}>logout</button> }
</>
)
}