Javascript React Router v4 嵌套路由 props.children

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43180088/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:44:09  来源:igfitidea点击:

React Router v4 nested routes props.children

javascriptreactjsreact-router

提问by Graeme Paul

I'm updating my universal react redux app to use react router v4. I have nested routes under a main layout route. Previously I used {props.children} to show contents of child routes, but this doesn't work anymore. How does this work in V4?

我正在更新我的通用 react redux 应用程序以使用 react router v4。我在主要布局路线下嵌套了路线。以前我使用 {props.children} 来显示子路由的内容,但这不再起作用。这在 V4 中是如何工作的?

<Provider store={store} key="provider">
  <div>
    <Route component={Layout} />
    <Switch>
      <Route path="/" component={HomePage} />
      <Route component={Error404} />
    </Switch>
  </div>
</Provider>

or

或者

<Provider store={store} key="provider">
  <Layout>
    <Route path="/" component={HomePage} />
    <Route component={Error404} />
  </Layout>
</Provider>

This is how my Layout file looks

这是我的布局文件的外观

const Layout = props => (
 <div className="o-container">
   <Header />
     <main>
      {props.children}
     </main>
   <Footer />
 </div>
);

回答by Dez

I have taken the <Provider>out because it belongs to react-reduxand you don't need it as basis for routing with react-router(anyway you can easily add it encapsulating the structure with it).

我把<Provider>它去掉是因为它属于react-redux你不需要它作为路由的基础react-router(无论如何你可以很容易地添加它来封装它的结构)。

In React Router V4, what was Routerhas been renamed to BrowserRouterand imported from package react-router-dom. So for nesting routes you need to insert this as children of your <Layout>.

在 React Router V4 中,Router已重命名为BrowserRouterpackage 并从 package 导入react-router-dom。因此,对于嵌套路由,您需要将其作为<Layout>.

index.js

索引.js

import { Switch, Route } from 'react-router';
import { BrowserRouter } from 'react-router-dom';
import Layout from './Layout';
...
const Root = () => (
  <Layout>
    <BrowserRouter>
      <Switch>
        <Route exact path="/" component={HomePage} />
        <Route path="/other" component={OtherComponent} />
        <Route component={Error404} />
      </Switch>
    </BrowserRouter>
  </Layout>
);

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

Layout.js

布局.js

import React from 'react';
import Header from './Header';
import Footer from './Footer';

const Layout = props => ({
  render() {
    return (
      <div className="o-container">
        <Header />
        <main>{props.children}</main>
        <Footer />
      </div>
    );
  }
});

export default Layout;

Take in count this only works for web. Native implementation differs.
I uploaded a small projectbased in Create React App where I show the implementation of nested routes in V4.

算上这仅适用于网络。本机实现不同。
我上传了一个基于 Create React App的小项目,其中展示了 V4 中嵌套路由的实现。

回答by loQ

Just thought I have to share this. If you're using a Linkcomponent in your Headercomponent. The answer above won't work. You would have to make the BrowserRouteras the parent again to support Link. Make it like this:

只是觉得我必须分享这个。如果您在Link组件中使用Header组件。上面的答案是行不通的。您必须BrowserRouter再次将设为父级以支持Link. 让它像这样:

<BrowserRouter>
 <Layout>
  <Switch>
    <Route exact path="/" component={HomePage} />
    <Route path="/other" component={OtherComponent} />
    <Route component={Error404} />
  </Switch>
 </Layout>
</BrowserRouter>

回答by zarcode

I would use this structure, without props.children :

我会使用这个结构,没有 props.children :

const Main = () => (
  <main>
    <Switch>
      <Route exact path="/" component={HomePage} />
      <Route component={Error404} />
    </Switch>
  </main>
)

const Layout = () => (
  <div>
    <Header />
    <Main />
    <Footer />
  </div>
)

ReactDOM.render((
    <Provider store={store}>
      <BrowserRouter>
        <Layout />
      </BrowserRouter>
   </Provider>
), document.getElementById('root'))

回答by Kiry Meas

Please read this blog through. https://codeburst.io/react-router-v4-unofficial-migration-guide-5a370b8905a

请通读此博客。https://codeburst.io/react-router-v4-unofficial-migration-guide-5a370b8905a

No More <IndexRoute>

The component allowed to route to a certain component on a top-level path in v3:

不再 <IndexRoute>

组件允许路由到 v3 中顶级路径上的某个组件:

// in src/MyApp.js
const MyApp = () => (
    <Router history={history}>
        <Route path="/" component={Layout}>
            <IndexRoute component={Dashboard} />
            <Route path="/foo" component={Foo} />
            <Route path="/bar" component={Bar} />
        </Route>
    </Router>
)

This component doesn't exist anymore in v4. To replace it, use a combination of , exact, and route ordering (placing the index route last):

这个组件在 v4 中不再存在。要替换它,请使用 、精确和路由排序的组合(将索引路由放在最后):

  // in src/MyApp.js
const MyApp = () => {
    <Router history={history}>
        <Route path="/" component={Layout} />
    </Router>
}
// in src/Layout.js
const Layout = () => (
    <div className="body">
        <h1 className="title">MyApp</h1>
        <div className="content">
            <Switch>
                <Route exact path="/foo" component={Foo} />
                <Route exact path="/bar" component={Bar} />
                <Route exact path="/" component={Dashboard} />
            </Switch>
        </div>
    </div>
);

回答by Vivek Bharatha

Adding to @Dez answer

添加到@Dez 答案

Complete native / core implementation with Redux support

具有 Redux 支持的完整原生/核心实现

index.js

索引.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { Router, Route, Switch } from 'react-router';
import createMemoryHistory from 'history/createMemoryHistory';

const history = createMemoryHistory();

import App from './components/App';
import Home from './components/Home';
import Login from './components/Login';
import store from './store';

ReactDOM.render((
  <Provider store={ store }>
    <Router history={history}>
      <App>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/login" component={Login} />
        </Switch>
      </App>
    </Router>
  </Provider>
), document.getElementById('root'));

App.js

应用程序.js

import Header from './Header';
import Home from './Home';
import React from 'react';
import {connect} from 'react-redux';

const mapStateToProps = state => ({appName: state.appName});

class App extends React.Component {
  render() {
    return (
      <div >
        <Header appName={this.props.appName} /> {/*common header*/}
        {this.props.children}
      </div>
    );
  }
}

export default connect(mapStateToProps, () => ({}))(App);

回答by Homam Bahrani

If using with Redux, without the Switch element

如果与 Redux 一起使用,没有 Switch 元素

AppRouter.js

AppRouter.js

import React from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'



const AppRouter = () => (
  <Layout>
    <Router>
      <div>
        <nav>
          <ul>
            <li><Link to="/">Home</Link></li>
            <li><Link to="/about">About</Link></li>
            <li><Link to="/contact">Contact</Link></li>
          </ul>
        </nav>
        <Route exact path="/" component={Home}/>
        <Route path="/about" component={About}/>
        <Route path="/contact" component={Contact}/>
      </div>
    </Router>
  </Layout>
)

export default AppRouter;

Layout.js

布局.js

const Layout = props => ({
  render() {
    return (
      <div className="container">
        <Header />
        <main>{props.children}</main>
        <Footer />
      </div>
    );
  }
});

export default Layout;

Provider placed in Render function

Provider 放置在 Render 函数中

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';


import AppRouter from './AppRouter';
import reducers from './reducers';

const createStoreWithMiddleware = applyMiddleware()(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <AppRouter />
  </Provider>
  , document.getElementById('app'));