2017-12-16 4 views
1

Ich habe die folgende Komponente:Reagieren Router + Redux: Geschichte ist nicht definiert

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

ich diesen Fehler in der Konsole:

Cannot read property 'push' of undefined

Warum nicht diese Komponente haben Geschichte in seine Stützen?

Update 1

Das ist mein App.js die Gastgeber 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')); 

und dies ist der 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; 

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

Update 2

ich auch Loginform Komponente haben, die mehr oder weniger die gleiche wie die vorherige Komponente ist, aber es funktioniert gut:

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) 
); 
+0

Verwenden Sie React Router? Können wir das sehen? – Li357

+0

Sicher, ich habe gerade meine Frage aktualisiert und weitere Informationen hinzugefügt. –

Antwort

3

Sie benötigen eine Komponente zu verzieren withRouter

z. hinzufügen nach oben:

import { withRouter } from 'react-router';

und Export ändern:

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

Das die Router Requisiten reagieren geben.

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

+0

Bitte beachten Sie mein Update 2, das ich gerade zu meinem Beitrag hinzugefügt habe. Ich habe dieselbe Komponente, wie kommt es, dass diese Komponente nicht 'withRouter' braucht, damit die Geschichte funktioniert? –

+0

Ich denke, das liegt daran, dass die 'NavBar'-Komponente nicht direkt im Router verwendet wird und daher keine" Geschichte "in ihren Requisiten hat. Habe ich recht ? –

+0

Ja, das stimmt - "LoginForm" wird von der '' Komponente erstellt, daher werden die Stützen injiziert. Wenn du deinen Code ansiehst, wird 'HomePage' ebenfalls von' Route' erstellt, also hat er die'History'-Prop, also wäre eine andere Möglichkeit, 'History' zu erhalten,' History' als Prop für 'NavBar' zu verwenden . – ekcr1

Verwandte Themen