React Router,不会推送到新组件 - 无法读取未定义

时间:2018-01-18 19:28:17

标签: reactjs redux react-router

我一直很头疼,希望有人可以提供帮助。

注销时,我想呈现已注销的主页,或者要重定向到用户的登录页面。

相反,我的导航栏从登录更改为已注销(因此我知道用户已注销),但登录或主页组件未呈现。

我知道路线存在。 '/login' or '/' ...我已经尝试过了。

这是错误。

user_navigation.jsx:20 Uncaught TypeError: Cannot read property 'history' of undefined

如果我手动刷新页面,它将返回主页,但这是来自登录组件的componentDidMount函数的重定向。

这也告诉我在promise中没有达到this.props.history.push('/login'),因为除非我刷新然后它重定向到我没有发送给它的页面,否则用户ID会保留在url中。

下面是注销功能,我将添加路线。

我提前感谢任何帮助。

import React from 'react';
import { Nav, Navbar, NavItem, NavDropdown, MenuItem, Button } from 'react-bootstrap';
import UniversalButton from '../buttons/universal_button.jsx';
import { withRouter } from 'react-router-dom';
import ReactLoading from 'react-loading';
import { clearAll } from '../../actions/reset_state';
import { connect } from 'react-redux';
import { logout } from '../../actions/session_actions'

class UserNavigation extends React.Component {
  constructor(props) {
    super(props);

    this.handleLogout = this.handleLogout.bind(this)
  }

  handleLogout(e) {
    e.preventDefault();
    this.props.logout().then(() => {
      this.props.clearAll()
      this.props.history.push('/login')
    })
  }

  render() {
    return(
      <Navbar inverse collapseOnSelect className="nav-bar">
        <Navbar.Header>
          <Navbar.Brand>
            <a href="#">liftly</a>
          </Navbar.Brand>
          <Navbar.Toggle />
        </Navbar.Header>
        <Navbar.Collapse>
          <Nav>
            <NavItem eventKey={2} href="#">Leaderboard</NavItem>
            <NavDropdown eventKey={3} title="Portfolio" id="basic-nav-dropdown">
              <MenuItem eventKey={3.1}>Workout Log</MenuItem>
              <MenuItem eventKey={3.2}>Progress Tracker</MenuItem>
              <MenuItem eventKey={3.3}>Friends</MenuItem>
              <MenuItem divider />
              <MenuItem eventKey={3.3}>Coaching</MenuItem>
            </NavDropdown>
          </Nav>
          <Navbar.Form pullRight>
            <Button bsStyle="danger" onClick={this.handleLogout}>Log Out</Button>
          </Navbar.Form>
        </Navbar.Collapse>
      </Navbar>
    )
  }
}

const mapDispatchToProps = dispatch => {
  return {
    clearAll: () => dispatch(clearAll()),
    logout: () => dispatch(logout())
  }
}
export default withRouter(connect(null, mapDispatchToProps)(UserNavigation))

路线

const app = () => (
  <div>
    <Navigation/>
    <Switch>
      <ProtectedRoute exact path='/' component={LoggedOutHomePage} />
      <AuthRoute path='/login' component={Login} />
      <AuthRoute path='/coach-signup' component={CoachSignup} />
      <AuthRoute path='/member-signup' component={MemberSignup} />
      <Route path ='/users/:userId' component={MembersHomePage} />
      <Route path ='/new-workout' component={NewWorkout} />
      <Route path ='/workout/:workoutId' component={WorkoutDetailsContainer} />
    </Switch>
  </div>
);

export default DragDropContext(HTML5Backend)(app);

受保护/验证路由

import React from 'react'
import { Route, withRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';


const Protected = ({component: Component, path, loggedIn, currentUser}) => {
  return(
    <Route
      path={path}
      render={ props => loggedIn ? <Redirect to={`/users/${currentUser.id}`} />  : <Component {...props}/> }
    />
  )
}


const Auth = ({component: Component, path, loggedIn}) => {
  return(
    <Route
      path={path}
      render={ props => !loggedIn ? <Component {...props}/>  : <Redirect to="/" /> }
    />
  )
}


const mapStateToProps = (state) => {
  return{
    loggedIn: Boolean(state.session.currentUser),
    currentUser: state.session.currentUser
  }
}

export const ProtectedRoute = withRouter(connect(mapStateToProps)(Protected))
export const AuthRoute = withRouter(connect(mapStateToProps)(Auth))

1 个答案:

答案 0 :(得分:0)

我终于通过删除诺言来解决这个问题。

在:

NEXT_VAL

之后:

handleLogout(e) {
    e.preventDefault();
    this.props.logout().then(() => {
      this.props.clearAll()
      this.props.history.push('/login')
    })
  }