this.props.history.push 适用于某些组件而不适用于其他组件

IT技术 javascript reactjs react-router router
2021-05-23 02:48:03

我正在尝试使用browserHistory.push. 在我的一个组件中,但不在我嵌入到该组件中的组件中。

有谁知道为什么我的项目只为子组件而不是父组件抛出以下错误?

无法读取未定义的属性“推送”

父组件

import React, {Component} from 'react';
import { browserHistory } from 'react-router';
import ChildView from './ChildView';

class ParentView extends Component {

constructor(props) {
    super(props);
    this.addEvent = this.addEvent.bind(this);
  }

changePage() {
    this.props.history.push("/someNewPage");
  }

render() {
    return (
      <div>
        <div>
          <button onClick={this.changePage}>Go to a New Page!</button>
        </div>

        <ChildView />  // this is the child component where this.props.history.push doesn't work 

      </div>
    );
  }
}

function mapStateToProps(state) {
    return {
        user: state.user
    };
}

function matchDispatchToProps(dispatch) {
    return bindActionCreators({
      setName: setName
    }, dispatch)
}

export default connect(mapStateToProps, matchDispatchToProps)(ParentView);

子组件

    import React, {Component} from 'react';
    import { browserHistory } from 'react-router';

    class ChildView extends Component {

    constructor(props) {
        super(props);
        this.addEvent = this.addEvent.bind(this);
      }

    changePage() {
        this.props.history.push("/someNewPage");
      }

    render() {
        return (
          <div>
            <div>
              <button onClick={this.changePage}>Go to a New Page!</button>
            </div>

          </div>
        );
      }
    }

    function mapStateToProps(state) {
        return {
            user: state.user
        };
    }

    function matchDispatchToProps(dispatch) {
        return bindActionCreators({
          setName: setName
        }, dispatch)
    }

    export default connect(mapStateToProps, matchDispatchToProps)(ChildView);

路由器

// Libraries
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { browserHistory } from 'react-router';

// Components
import NotFound from './components/NotFound';
import ParentView from './components/ParentView';
import ChildView from './components/ChildView';
import SomeNewPage from './components/SomeNewPage';

// Redux
import { Provider } from 'react-redux';
import {createStore} from 'redux';
import allReducers from './reducers';

const store = createStore(
  allReducers,
  window.devToolsExtension && window.devToolsExtension()
);

const routes = (
    <Router history={browserHistory}>
      <div>
        <Provider store={store}>
            <Switch>
              <Route path="/" exact component={Home} />
              <Route path="/parentView" component={ParentView} />
              <Route path="/someNewPage" component={SomeNewPage} />
              <Route path="/childView" component={ChildView} />
              <Route component={NotFound} />
            </Switch>
        </Provider>
      </div>
    </Router>
);

export default routes;

如您所见,除了子组件位于父组件内部之外,组件几乎完全相同。

注意我已经尝试过这些方法,但它们并没有为我解决问题:

4个回答

你在你的问题中回答了你的问题。

如您所见,除了子组件位于父组件内部之外,组件几乎完全相同。

组件进一步嵌套的事实是您的问题。React router 只将路由 props 注入它路由到的组件,但不会注入到嵌套的组件中。

请参阅问题的已接受答案基本思想是,您现在需要找到一种方法将路由props注入子组件。您可以通过将孩子包装在 HOC 中来做到这一点withRouter

export default withRouter(connect(mapStateToProps, matchDispatchToProps)(ChildView));

我希望这有帮助。

使用 withRouter 很好,另一种选择是将历史作为props从父级传递给子级(不使用 withRouter),例如:

家长

<SignupForm history={this.props.history}/>

孩子

this.props.history.push('/dashboard');

你可以试试这个

this.context.history.push('/dashboard')

或将历史作为props从父组件传递给子组件,例如

父母

<SignupForm history={this.props.history}/>

孩子

this.props.history.push('/dashboard');

或者 withRouter

import { withRouter } from "react-router";
export default withRouter(connect(mapStateToProps, {
    ...
})(Header));

这就是嵌套组件的问题。我在 Header 组件中遇到了这个问题。我想通过单击徽标将页面重定向到主页。

this.props.history.push 不适用于嵌套组件。

所以解决方案是使用withRouter.

要使用withRouter仅复制粘贴标题中的以下 2 行(您可以在您的组件中使用它):

import { withRouter } from "react-router";
export default withRouter(connect(mapStateToProps, {
    ...
})(Header));