反应:令牌传递到本地存储后,Navbar不变

时间:2018-12-16 14:06:04

标签: reactjs redux navbar

我写了一个导航栏组件,创建了2个const函数,以便根据本地存储中“ usertoken”的出现来显示它们。使用正确的数据登录后,我收到了用户令牌,并将其保存在本地存储中。但是,在将用户令牌放置在本地存储中后,它不会立即重新渲染导航栏。当我刷新页面时,它会重新呈现。

我已将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));

LoginForm.js中的onSubmitHandler

  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();
}

loginUser操作

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中传递令牌的事实?

2 个答案:

答案 0 :(得分:2)

  

这是因为您的Navbar组件既未连接到Redux存储,也未收到userToken作为props。这就是为什么当减速器更新state时,Navbar不会重新呈现。

     

基于stateprops渲染任何内容也是最好的做法。您的Navbar组件正直接在localStorage中检查rendering appropriate view。如果您决定将userToken作为props的{​​{1}}从商店或父组件传递给Navbar,则将其更改为以下内容。

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>

答案 1 :(得分:0)

您需要在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)