Я написал компонент навигационной панели, создал 2 константные функции, чтобы отображать их в соответствии с появлением «токена пользователя» в локальном хранилище. После входа в систему с правильными данными я получаю токен пользователя, и он сохраняется в локальном хранилище. Однако он не выполняет повторную визуализацию навигационной панели сразу после того, как маркер пользователя помещается в локальное хранилище. Когда я обновляю страницу, она перерисовывается.
У меня loginForm подключен к состоянию Redux.
Navbar.js
import React, { Component } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import './Navbar.css'
class Navbar extends Component {
logOutHandler(e) {
e.preventDefault()
localStorage.removeItem('usertoken')
this.props.history.push('/login')
}
render() {
const loginRegistrationLink = (
<ul className='navbar-navigation-dynamic'>
<li className='navbar-navigation-item'>
<Link to='/login' className='navbar-navigation-link'>
Login
</Link>
</li>
<li className='navbar-navigation-item'>
<Link to='/register' className='navbar-navigation-link'>
Register
</Link>
</li>
</ul>
)
const profileLink = (
<ul className='navbar-navigation-dynamic'>
<li className='navbar-navigation-item'>
<Link to='/profile' className='navbar-navigation-link'>
Account
</Link>
</li>
<li className='navbar-navigation-item'>
<a href='#' onClick = {this.logOutHandler.bind(this)} className='navbar-navigation-link'>
Logout
</a>
</li>
</ul>
)
return (
<div className='navbar'>
<ul className = "navbar-navigation">
<li className = "navbar-navigation-item">
<Link to='/' className='navbar-navigation-link'>
Home
</Link>
</li>
</ul>
{localStorage.usertoken ? profileLink : loginRegistrationLink}
</div>
)
}
}
const mapStateToProps = (state) => ({
user: state.auth
});
export default connect(mapStateToProps, {})(withRouter(Navbar));
onSubmitHandler в LoginForm.js
onSubmitHandler = (e) => {
const { user_name, password } = this.state
const loggedUser = {
user_name: user_name,
password: password
}
this.props.loginUser(loggedUser);
this.setState({
user_name: '',
password: ''
})
this.props.history.push('/')
e.preventDefault();
}
действие пользователя
export const loginUser = user => dispatch => {
axios.post('https://damianlibrary.herokuapp.com/users/login', user)
.then(res => dispatch({
type: LOGIN_USER,
payload: localStorage.setItem('usertoken', res.data)
}))
}
authReducer.js
import { LOGIN_USER, REGISTER_USER } from '../actions/types';
const authState = {
users: [],
status: ''
}
export default function(state = authState, action) {
switch(action.type) {
case LOGIN_USER:
return {
...state,
token: action.payload
};
case REGISTER_USER:
return {
...state,
users: [action.payload, ...state.users],
status: action.status
};
default:
return state;
}
}
Есть ли что-то, связанное с тем, что я не пропустил токен в своем authReducer?
Нет, токен пользователя попадает в локальное хранилище, а после запуска действия входа в систему, я думаю, проблема в том, что панель навигации не отображается.
@Wasilewski. что возвращает localStorage.setItem (). если это API-интерфейс localStorage, который предоставляет браузер, то он всегда возвращает undefined после установки пары "ключ-значение" в локальном хранилище.
Возвращает пару ключ-значение. Ключ: usertoken Значение: декодированное значение jwt
могу я узнать, какую библиотеку вы используете для установки localStorage?
Я устанавливаю его через функцию localStorage.setItem () в HTTP-запросе axios.
и подключается ли ваш компонент Navbar к магазину или получает userToken от любого родительского компонента. Потому что, насколько мне известно, лучшая практика для компонента, отображающего что-то условно, должна полностью зависеть от его состояния, а не от каких-то внешних факторов.





Вам нужно передать полезную нагрузку в ваш authreducer. Кроме того, event.preventDefault () следует писать перед history.push ('/') или вы можете писать сразу после вызова функции.
Кроме того, в вашем компоненте входа в систему вы должны вызвать такую функцию:
this.props.dispatch(loginuser()) // pass the input params here
this.props.history.push('/login')
Вам также необходимо подключить свой компонент к вашему хранилищу redux, как показано ниже:
export default connect (mapStateToProps)(YourComp Name)
Сделал все, что вы сказали, и это не помогло
Обновил мой ответ, проверьте это. Я не вижу, чтобы вы использовали mapStateToProps в своем компоненте.
It is because your
Navbarcomponent is neither connected to theReduxstore nor it receives theuserTokenasprops. That is why when your reducer is updating yourstate, theNavbaris not getting re-rendered.Also it is always the best practice, to render anything based on either the
stateorprops. YourNavbarcomponent is checking directly in the localStorage forrendering appropriate view. Change it to something like below if you decide to pass theuserTokenaspropstoNavbareither from store or parent component.
return (
<div className='navbar'>
<ul className = "navbar-navigation">
<li className = "navbar-navigation-item">
<Link to='/' className='navbar-navigation-link'>
Home
</Link>
</li>
</ul>
{this.props.usertoken ? profileLink : loginRegistrationLink}
</div>
Все работает нормально после того, как я подключил свой компонент NavBar к магазину. Теперь у меня проблема с обработчиком выхода. Это не вызывает повторной отрисовки. Нужно ли мне добавить новое действие (logoutUser), которое удалит токен для локального хранилища? А потом передать его редуктору?
@ D.Wasilewski. Не могли бы вы обновить приведенный выше код?
@ D.Wasilewski. Снова. чтобы запустить повторный рендеринг, вам необходимо обновить состояние. Ваше состояние хранится в store. Итак, вам нужно обновить магазин, который изменит состояние. Вы mapDispatchToProps за это. Сообщите мне, если это сработает.
@ D.Wasilewski. Как я объяснил выше, вам нужно обновить состояние. прочтите комментарий. Дай мне знать, если тебе понадобится помощь.
Я создал новое действие «LogoutUser», которое удаляет токен из localStorage. Ваш ответ был очень полезным. Большое Вам спасибо ;)
он работает после того, как вы изменили состояние с помощью действия в случае действия LOGIN_USER?