无法使用react-router-dom的WithRouter

时间:2019-01-22 09:24:40

标签: javascript reactjs redux react-redux react-router

我是React JS的新手。在这里,我尝试使用withrouter来获取我的位置信息。

所以,我有以下结构。

index.js

ReactDOM.render(
  <App />
  , document.getElementById('root'));

App.js

 <Provider store={store}>
        <div>
          <Header />
          <Main />
        </div>
      </Provider>

Main.js

return (
      <Router history={history}>
        <div>
          {this.props.isFetching && <Loading />}
          <Switch>
            <PrivateRoute exact path="/" component={LandingPage} />
            <PrivateRoute exact path="/create-job" component={NewJob} />
            <PrivateRoute exact path="/user-jobs" component={JobList} />
            <Route exact path="/login" component={Login} />
          </Switch>
        </div>
      </Router>

现在,我正在尝试在Header.js中使用withRouter。不属于Router的一部分。所以,

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

我尝试过使用这种方式。因此,它给了我以下错误。

You should not use <Route> or withRouter() outside a <Router>

我在这里做错什么了?

4 个答案:

答案 0 :(得分:1)

您要在Header组件外部渲染withRouter组件(使用Router)。您需要确保所有Route和使用withRouter的组件都必须是层次结构中某个级别的Router的子代。

在您的情况下,也许用divApp包裹在Router中?

来源详细信息

如果Route没有从其here传递contextprovider,则会生成错误。而且,withRouter只是Route的包装。上下文唯一不可用的时间是Route没有嵌套在Router内的某个地方。

答案 1 :(得分:1)

您的问题是withRouter道具被PureComponent检查阻止,将其放在连接后:

export default connect(mapStateToProps, {  logout  })(withRouter(Header));

请参阅:https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/withRouter.md#important-note

我个人更喜欢将提供程序放在index.js中的某个位置而不是App.js中,您的整个应用程序应该包装在Router中,而不是App.js的一部分:

const WrappedApp = (
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>
);

ReactDOM.render(WrappedApp, document.getElementById('root'));

答案 2 :(得分:0)

您需要将<Header>组件移至<Router>组件内,否则将无法正常工作,如错误提示所述。

答案 3 :(得分:0)

因此,您想做两件事,在Header中注入状态,并在Header中注入路由信息。 如果您不在<Router/>组件之外,则将无法使用withRouter(,因为您没有任何匹配道具可以链接到您的compoonent。

您需要做的是创建一个称为layouts ...的东西,并在页面定义中使用这样的布局。

假设您有这条路线<PrivateRoute exact path="/" component={LandingPageContainer} /> 现在,在LandingPage内部,您需要执行类似的操作

landingPageContainer.js
render() {
   return (
    <SimpleLayout header={<Header ...this.props/> footer={<Footer ...this.props/>}>
       <LandingPageDummyPage ...this.props/>
    <SimpleLayout/>
   );
}
export default connect(withRouter(LandingPageContainer);

这会将传递到简单布局的所有道具复制到您的LandingPageLayout,页眉和页脚

simpleLayout.js
render() {
   return (
    <div>{this.props.header} </div>
    <div>{this.props.children} </div>
    <div{this.props.footer} </div>
   );
}

export withRouter(SimpleLayout);

advice . read the router documentation and try to understand whats the purpose if it... you didn`t quite get it :) ...