React Router + Redux:历史未定义

Ari*_*deh 1 reactjs react-router redux

我有以下组件:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { logoutUser } from '../actions';

class NavBar extends Component {

  onLogoutClick() {
    this.props.logoutUser();
    this.props.history.push('/login'); // here is the issue
  }

  render() {
    return (
      <div>
        <button
          className="btn btn-danger pull-xs-right"
          onClick={this.onLogoutClick.bind(this)}
        >
          Logout
        </button>
      </div>
    );
  }
}

export default connect(null, {logoutUser})(NavBar);
Run Code Online (Sandbox Code Playgroud)

我在控制台中收到此错误:

Cannot read property 'push' of undefined

为什么这个组件的 props 没有历史记录?

更新 1

这是我的App.js主机BrowserRouter

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import promise from 'redux-promise';

import reducers from './reducers';

import LoginForm from './components/login_form';
import NavBar from './components/nav_bar';
import Homepage from './components/home_page';
import PrivateRoute from './components/private_route';

const createStoreWithMiddleware = applyMiddleware(promise)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
      <BrowserRouter>
        <div>
          <PrivateRoute exact path="/" component={Homepage} />
          <Route exact path="/login" component={LoginForm} />
        </div>
      </BrowserRouter>
  </Provider>
  , document.querySelector('.container'));
Run Code Online (Sandbox Code Playgroud)

这是 PrivateRoute:

import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import Homepage from './home_page';

export const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={props => (
      <Component {...props} />
props.location } }} />
    )} />
)

export default PrivateRoute;
Run Code Online (Sandbox Code Playgroud)

Homepage.js

import React, { Component } from 'react';
import { connect } from 'react-redux';
import NavBar from './nav_bar';

export default class HomePage extends Component {
  render() {
    return (
      <div>
        <NavBar />
        <h1>Welcome to the homepage</h1>
      </div>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

更新 2

我还有LoginForm组件,它或多或少与前一个组件相同,但它工作正常:

import React, { Component } from 'react';
import { Field, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import { loginUser } from '../actions';
import validator from 'validator';

class LoginForm extends Component {
  renderField(field) {
      //....
  }

  onSubmit(values) {
    this.props.loginUser(values, () => {
      this.props.history.push('/');
    });
  }

  render() {
    const {handleSubmit} = this.props;

    return (
      <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
        <Field
          name="username"
          label="Username"
          component={this.renderField}
        />
        <Field
          name="password"
          label="Password"
          component={this.renderField}
        />
        <button type="submit" className="btn btn-primary">Enter</button>
      </form>
    );
  }
}

function validate(values) {
  const errors = {};
  return errors;
}

export default reduxForm({
  validate,
  form:'LoginForm'
})(
  connect(null, { loginUser })(LoginForm)
);
Run Code Online (Sandbox Code Playgroud)

ekc*_*cr1 5

你需要装饰你的组件 withRouter

例如。添加到顶部:

import { withRouter } from 'react-router';

并将您的导出更改为:

export default withRouter(connect(null, {logoutUser})(NavBar));

这将为您提供反应路由器道具。

https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md