为什么注销导航链接不适用于 localStorage?
Why logout navlink doesn't work with localStorage?
我正在尝试使用 localStorage 以便 connect/disconnect 我网站上的用户。我试图通过点击导航栏的条件来管理这个(它涉及最新的 NavLink
组件)。在中间件中,我恢复了令牌(使用 console.log 验证)。当用户想要注销时,我想清空令牌并显示 "LogIn" 而不是 "LogOut" 。但这没有效果。单击时令牌确实为空,但无法断开连接。也无法再次连接,因为始终存在“注销”而未显示模态。非常感谢您的帮助!
AppHeader (index.js)
// import Bootsrap-react's components
import {
Container,
Navbar,
Nav,
Modal,
Button,
Form,
} from 'react-bootstrap';
import { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { LinkContainer } from 'react-router-bootstrap';
import logo from 'src/assets/images/logo.png';
import { fetchAllEvents } from '../../actions/events';
import { setSelectedRegionId } from '../../actions/regions';
import { setSelectedGenreId } from '../../actions/genres';
import { changeEmail, changePassword, logIn } from '../../actions/user';
import './appHeader.scss';
const AppHeader = () => {
const dispatch = useDispatch();
const [show, setShow] = useState(false);
const emailValue = useSelector((state) => state.user.email);
const passwordValue = useSelector((state) => state.user.password);
const token = localStorage.getItem('token');
const callLogin = () => {
let isLogged;
if (token !== null) {
isLogged = 'Logout';
}
else {
isLogged = 'Log In';
}
return isLogged;
};
const handleClose = () => setShow(false);
const handleOpen = () => setShow(true);
const logOut = () => localStorage.setItem('token', null);
return (
<div>
<Navbar id="mainNav" expand="lg">
<Container id="navbar-container">
<LinkContainer to="/">
<Navbar.Brand> <img src={logo} alt="logo" height="60" />
</Navbar.Brand>
</LinkContainer>
<LinkContainer to="/">
<Nav.Link>
<h2 className="navbar-title">Concert'o</h2>
</Nav.Link>
</LinkContainer>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav " placement="right">
<Nav className="flex-grow-1 justify-content-evenly">
<LinkContainer
to="/"
onClick={() => {
dispatch(setSelectedGenreId());
dispatch(setSelectedRegionId());
}}
>
<Nav.Link className="navlink-header">Accueil</Nav.Link>
</LinkContainer>
<LinkContainer to="/genres">
<Nav.Link className="navlink-header">Genres</Nav.Link>
</LinkContainer>
<LinkContainer to="/regions">
<Nav.Link className="navlink-header">Regions</Nav.Link>
</LinkContainer>
<LinkContainer
to="/tous-les-evenements"
onClick={() => {
dispatch(setSelectedGenreId());
dispatch(setSelectedRegionId());
dispatch(fetchAllEvents());
}}
>
<Nav.Link className="navlink-header">Tous les événements</Nav.Link>
</LinkContainer>
<Nav.Link
className="navlink-header "
onClick={() => {
if (token !== null) {
dispatch(logOut());
}
else {
dispatch(handleOpen());
}
}}
>{callLogin()}
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Me connecter</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
placeholder="name@example.com"
autoFocus
email={emailValue}
onChange={(event) => {
// console.log(event.target.value);
dispatch(changeEmail(event.target.value));
}}
/>
</Form.Group>
<Form.Group
className="mb-3"
controlId="exampleForm.ControlTextarea1"
>
<Form.Label>Mot de passe</Form.Label>
<Form.Control
type="password"
password={passwordValue}
onChange={(event) => {
// console.log(event.target.value);
dispatch(changePassword(event.target.value));
}}
/>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button
variant="secondary"
onClick={() => {
dispatch(logIn());
dispatch(handleClose());
}}
>
Valider
</Button>
<LinkContainer
to="/inscription"
>
<Button onClick={handleClose} variant="primary">
Pas encore inscrit ? Cliquez ici
</Button>
</LinkContainer>
</Modal.Footer>
</Modal>
</div>
);
};
export default AppHeader;
用户缩减器
import { CHANGE_EMAIL, CHANGE_PASSWORD, SAVE_USER_DATA } from '../actions/user';
export const initialState = {
email: '',
password: '',
username: '',
token: null,
errorMessage: '',
};
const user = (state = initialState, action = {}) => {
switch (action.type) {
case CHANGE_EMAIL:
return {
...state,
email: action.value,
};
case CHANGE_PASSWORD:
return {
...state,
password: action.value,
};
case SAVE_USER_DATA:
return {
...state,
username: action.nickname,
token: action.token,
};
default:
return state;
}
};
export default user;
为什么 token
不是 null
You can only store a string in localStorage
,因此当您将其设置为 null
并稍后检查值是否为 null
时,答案是否定的,因为 localStorage
现在等于字符串 "null"
,不是null
.
您可以做的是完全删除令牌:
localStorage.removeItem("token");
然后简单地检查token
是否存在:
let isLogged;
if (token) {
isLogged = "Logout";
} else {
isLogged = "Log In";
}
return isLogged;
您还可以使用以下代码缩短您的代码:
return token ? 'Logout' : 'Log In'
此外
您正在使用 dispatch
,这是一个通过 传入操作对象 来更新 store
的函数,但是 dispatch(logOut());
, dispatch(handleOpen());
和 dispatch(handleClose());
没有传入对象,这些函数没有 return 任何东西。这意味着您可能(并且应该)因此 运行 出错,因为这是对 dispatch
函数的不当使用。
我正在尝试使用 localStorage 以便 connect/disconnect 我网站上的用户。我试图通过点击导航栏的条件来管理这个(它涉及最新的 NavLink 组件)。在中间件中,我恢复了令牌(使用 console.log 验证)。当用户想要注销时,我想清空令牌并显示 "LogIn" 而不是 "LogOut" 。但这没有效果。单击时令牌确实为空,但无法断开连接。也无法再次连接,因为始终存在“注销”而未显示模态。非常感谢您的帮助! AppHeader (index.js)
// import Bootsrap-react's components
import {
Container,
Navbar,
Nav,
Modal,
Button,
Form,
} from 'react-bootstrap';
import { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { LinkContainer } from 'react-router-bootstrap';
import logo from 'src/assets/images/logo.png';
import { fetchAllEvents } from '../../actions/events';
import { setSelectedRegionId } from '../../actions/regions';
import { setSelectedGenreId } from '../../actions/genres';
import { changeEmail, changePassword, logIn } from '../../actions/user';
import './appHeader.scss';
const AppHeader = () => {
const dispatch = useDispatch();
const [show, setShow] = useState(false);
const emailValue = useSelector((state) => state.user.email);
const passwordValue = useSelector((state) => state.user.password);
const token = localStorage.getItem('token');
const callLogin = () => {
let isLogged;
if (token !== null) {
isLogged = 'Logout';
}
else {
isLogged = 'Log In';
}
return isLogged;
};
const handleClose = () => setShow(false);
const handleOpen = () => setShow(true);
const logOut = () => localStorage.setItem('token', null);
return (
<div>
<Navbar id="mainNav" expand="lg">
<Container id="navbar-container">
<LinkContainer to="/">
<Navbar.Brand> <img src={logo} alt="logo" height="60" />
</Navbar.Brand>
</LinkContainer>
<LinkContainer to="/">
<Nav.Link>
<h2 className="navbar-title">Concert'o</h2>
</Nav.Link>
</LinkContainer>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav " placement="right">
<Nav className="flex-grow-1 justify-content-evenly">
<LinkContainer
to="/"
onClick={() => {
dispatch(setSelectedGenreId());
dispatch(setSelectedRegionId());
}}
>
<Nav.Link className="navlink-header">Accueil</Nav.Link>
</LinkContainer>
<LinkContainer to="/genres">
<Nav.Link className="navlink-header">Genres</Nav.Link>
</LinkContainer>
<LinkContainer to="/regions">
<Nav.Link className="navlink-header">Regions</Nav.Link>
</LinkContainer>
<LinkContainer
to="/tous-les-evenements"
onClick={() => {
dispatch(setSelectedGenreId());
dispatch(setSelectedRegionId());
dispatch(fetchAllEvents());
}}
>
<Nav.Link className="navlink-header">Tous les événements</Nav.Link>
</LinkContainer>
<Nav.Link
className="navlink-header "
onClick={() => {
if (token !== null) {
dispatch(logOut());
}
else {
dispatch(handleOpen());
}
}}
>{callLogin()}
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
<Modal show={show} onHide={handleClose}>
<Modal.Header closeButton>
<Modal.Title>Me connecter</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group className="mb-3" controlId="exampleForm.ControlInput1">
<Form.Label>Email</Form.Label>
<Form.Control
type="email"
placeholder="name@example.com"
autoFocus
email={emailValue}
onChange={(event) => {
// console.log(event.target.value);
dispatch(changeEmail(event.target.value));
}}
/>
</Form.Group>
<Form.Group
className="mb-3"
controlId="exampleForm.ControlTextarea1"
>
<Form.Label>Mot de passe</Form.Label>
<Form.Control
type="password"
password={passwordValue}
onChange={(event) => {
// console.log(event.target.value);
dispatch(changePassword(event.target.value));
}}
/>
</Form.Group>
</Form>
</Modal.Body>
<Modal.Footer>
<Button
variant="secondary"
onClick={() => {
dispatch(logIn());
dispatch(handleClose());
}}
>
Valider
</Button>
<LinkContainer
to="/inscription"
>
<Button onClick={handleClose} variant="primary">
Pas encore inscrit ? Cliquez ici
</Button>
</LinkContainer>
</Modal.Footer>
</Modal>
</div>
);
};
export default AppHeader;
用户缩减器
import { CHANGE_EMAIL, CHANGE_PASSWORD, SAVE_USER_DATA } from '../actions/user';
export const initialState = {
email: '',
password: '',
username: '',
token: null,
errorMessage: '',
};
const user = (state = initialState, action = {}) => {
switch (action.type) {
case CHANGE_EMAIL:
return {
...state,
email: action.value,
};
case CHANGE_PASSWORD:
return {
...state,
password: action.value,
};
case SAVE_USER_DATA:
return {
...state,
username: action.nickname,
token: action.token,
};
default:
return state;
}
};
export default user;
为什么 token
不是 null
You can only store a string in localStorage
,因此当您将其设置为 null
并稍后检查值是否为 null
时,答案是否定的,因为 localStorage
现在等于字符串 "null"
,不是null
.
您可以做的是完全删除令牌:
localStorage.removeItem("token");
然后简单地检查token
是否存在:
let isLogged;
if (token) {
isLogged = "Logout";
} else {
isLogged = "Log In";
}
return isLogged;
您还可以使用以下代码缩短您的代码:
return token ? 'Logout' : 'Log In'
此外
您正在使用 dispatch
,这是一个通过 传入操作对象 来更新 store
的函数,但是 dispatch(logOut());
, dispatch(handleOpen());
和 dispatch(handleClose());
没有传入对象,这些函数没有 return 任何东西。这意味着您可能(并且应该)因此 运行 出错,因为这是对 dispatch
函数的不当使用。