javascript - 使用本地存储的 Logot 功能
问题描述
所以在这里我有通过本地存储令牌登录的功能。我在开发工具/应用程序中创建用户后获得令牌,它将我重定向到家。但是应该显示注销而不是登录,当我登录时,它没有这样做,我不知道为什么。任何帮助都会很方便
语境
import React from "react";
const UserContext = React.createContext();
function getUserFromLocalStorage() {
return localStorage.getItem("authToken")
? JSON.parse(localStorage.getItem("authToken"))
: { username: null, token: null };
}
function UserProvider({ children }) {
const [user, setUser] = React.useState(getUserFromLocalStorage());
const history = useHistory();
const logoutHandler = () =>{
localStorage.removeItem("user");
history.push("/")
}
return (
<UserContext.Provider
value={{ user, logoutHandler }}
>
{children}
</UserContext.Provider>
);
}
export { UserContext, UserProvider };
登录组件
import { useState, } from "react";
import { useHistory } from "react-router-dom"
import axios from "axios";
import { Link } from "react-router-dom";
import "./Signin.css";
const Login = () => {
const { user, setUser } = React.useContext(UserContext);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const history = useHistory()
const loginHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/login",
{ email, password },
config
);
localStorage.setItem("authToken", data.token);
setUser(user)
history.push("/");
} catch (error) {
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="login-screen">
<form onSubmit={loginHandler} className="login-screen__form">
<h3 className="login-screen__title">Login</h3>
{error && <span className="error-message">{error}</span>}
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="Email address"
onChange={(e) => setEmail(e.target.value)}
value={email}
tabIndex={1}
/>
</div>
<div className="form-group">
<label htmlFor="password">
Password:{" "}
<Link to="/forgotpassword" className="login-screen__forgotpassword">
Forgot Password?
</Link>
</label>
<input
type="password"
required
id="password"
autoComplete="true"
placeholder="Enter password"
onChange={(e) => setPassword(e.target.value)}
value={password}
tabIndex={2}
/>
</div>
<button type="submit" className="btn btn-primary">
Login
</button>
<span className="login-screen__subtext">
Don't have an account? <Link to="/register">Register</Link>
</span>
</form>
</div>
);
};
export default Login;
标题
import React from 'react';
import { Link, useHistory } from "react-router-dom";
import Search from './Search';
import './Header.css'
import SearchBooks from './SearchBooks';
import LoginLink from '../Signin/LoginLink';
import CartLink from '../Cart/CartLink';
import { UserContext } from '../../context/user';
const Header = () => {
const { user } = React.useContext(UserContext);
return (
<div className='header__container'>
<Link to='/'>
<img src='/audi.png' />
</Link>
<li>
<LoginLink />
</li>
{user.authToken &&(
<CartLink />
)
}
</div>
)
}
登录链接
import React from "react";
import { Link } from "react-router-dom";
import { UserContext } from "../../context/user";
import { useHistory } from "react-router-dom"
export default function LoginLink() {
const { user, logoutHandler } = React.useContext(UserContext);
if (user.authToken) {
return (
<button
onClick={() => {
logoutHandler();
}}
className="login-btn"
>
logout
</button>
);
}
return <Link to="/login">login</Link>;
}
解决方案
// here you get "authToken", so you hope user is Object struct, not string.
function getUserFromLocalStorage() {
return localStorage.getItem("authToken")
? JSON.parse(localStorage.getItem("authToken"))
: { username: null, token: null };
}
// here you store "authToken"
localStorage.setItem("authToken", JSON.parse({ username: data.username || "", token: data.token }))
user.token = data.token;
setUser(user)
// here you use token in "authToken"
if (user.token) {
return (
<button
onClick={() => {
logoutHandler();
}}
className="login-btn"
>
logout
</button>
);
}
推荐阅读
- karate - 没有生成 karate.log 文件
- mysql - 如何获得具有特定血型的男性和女性的数量
- c# - 无法使用 Directory.get 文件获取文件 c#
- python - 在 raspberrypi(ubuntu18.04) 上运行 pynput lib 示例程序
- javascript - 如何使用 lodash 添加相同对象的总和
- python - 将 pandas 数据导出到 excel - Python/Pandas
- javascript - 当我在输入字段中按 Enter 键时,即使我设置了 preventDefault,我的 React 表单仍会提交
- c# - 有没有办法在 Mocked Logger 上使用 Assert 或 Moq.Verify?
- javascript - 如何使用 setAttribute 在文本框中的答案之前添加文本,但仅在打印结果之后
- spring - 避免在 RestTemplate Junit 中进行实际的 Rest 调用