【问题标题】:React-router: How nested routes work?React-router:嵌套路由如何工作?
【发布时间】:2017-06-04 06:39:39
【问题描述】:

我有一个带有 react-router 的 react 应用程序。我正在尝试设置嵌套路由:

"/" --> home page
"/products" --> products list (child component of home page)
"/products/new" --> new product: child component of products list

到目前为止我尝试做的事情:

<Route path="/" component="home" >

     <Route path="products" component="products" >

           <Route path="new" component="products_new" />
     </Route>

</Route>

现在在我的默认主页的浏览器中,当我点击"/products" 时,产品组件已加载,我可以看到我的产品列表。但是当我点击"products/new" 时,什么也没有发生。我得到一个空白页。如果我点击"/new"(未嵌套)它可以工作(页面 product_new 加载到其父级中)。 (这个"/products/new" 不起作用;这个"/new" 起作用)

我在 github 上查看了这个问题 Problem with nested routes #687。解决方案说:

我发现了我的问题。总是调用父路由。那就是 意图。但是子组件需要重复 &lt;Router.RouteHandler/&gt; 得到渲染。

我无法理解这个解决方案。这是什么意思: "但是子组件需要重复 &lt;Router.RouteHandler/&gt; 被渲染”

EDIT1: 这是我的组件(路由器和视图):

  1. 我的路由层次结构:

                <Route path="/" >    
                        <IndexRoute component={Home}/>
                        <Route path="products">
                            <IndexRoute component={Products} />
                            <Route path="new" component={Products_New} />
                        </Route>
                    </Route>                        
                </Router>
    
  2. 我的家庭组件:

         <div className="col-lg-12">
            <h1>Home page</h1>
            <hr />
            {this.props.children}
        </div>
    
  3. 我的产品组件:

        <div>
            <div className="col-lg-12">
                <h1>Products</h1>
            </div>
            <hr />
            {this.props.children}
        </div>
    
  4. 我的产品新组件:

【问题讨论】:

    标签: reactjs react-router nested-routes


    【解决方案1】:

    您看过 IndexRoutes 吗?如果没有,请在official documentation 上阅读它。您的问题是,当您访问 /products/new 时,react-router 会尝试渲染您的 products_new 路由上方的 所有 组件。

    如果您想在父组件内部呈现子组件,则需要此行为。请允许我用几个例子来演示:

    示例 1

    考虑以下home 组件,它有一个包含在所有页面中的页眉和页脚。

    <Header />
    <div>{this.props.children}</div>
    </Footer />
    

    使用以下路由:

    <Route path="/" component={home} >
      <Route path="products" component={products} />
    </Route>
    
    • 访问/ 将呈现一个只有&lt;Header /&gt;、空&lt;div&gt;&lt;Footer /&gt; 的页面。
    • 访问/products 会呈现如上所示的页面,但&lt;div&gt; 现在将包含您的&lt;Products /&gt; 组件。

    因为,在您的代码中,您(可能)不会渲染 {this.props.children},因此无论您访问的是 / 还是 /products,您都将始终获得父组件 &lt;Home /&gt;

    这种行为对于包装网站主要元素的东西很有用,例如菜单、横幅、侧边栏等。


    示例 2

    现在再次考虑相同的home 组件:

    <Header />
    <div>{this.props.children}</div>
    </Footer />
    

    但使用此路由:

    <Route path="/">
      <IndexRoute component={home}
      <Route path="products" component={products} />
    </Route>
    
    • 访问/ 将呈现一个只有&lt;Header /&gt;、空&lt;div&gt;&lt;Footer /&gt; 的页面。
    • 现在访问/products单独呈现您的&lt;Products /&gt; 组件,而不会被包裹在父&lt;Home /&gt; 组件中。

    TL;DR

    如果您希望每条路由都渲染单个组件,而不是该路由树下的所有内容,则应改用以下路由:

    const browserHistory = useRouterHistory(createHistory)({basename: '/'});
    
    ReactDOM.render(
      <Route history={browserHistory}>
        <Route path="/">
          <IndexRoute component={home} />
          <Route path="products" >
            <IndexRoute component={products} />
            <Route path="new" component={products_new} />
          </Route>
        </Route>
      </Router>,
      document.getElementById('content')
    );
    

    【讨论】:

    • 感谢您的回答。我做了你告诉我的,但不幸的是它仍然不起作用。我忘了说这是一个 SPA(单页应用程序)所以我将 browserHistory 更改为 hashHistory 现在它正在工作(只有我的 url 中有一个 #...
    • 对,您需要使用history。我强烈推荐使用browserHistory。我更新了上面的代码,试试吧。
    • 我理解你的回答。我的意图是让每个视图都呈现在其父视图中。我的问题是:为什么这个 url 有效:/products(我的意思是 product-component 在 home-component 中正确呈现)但是这个 url 不起作用 /products/new (尽管有一个占位符({ this.props.children} ) 在 products-components 中。我希望 products-new-component 在 products-component 中呈现,而 products-component 中又会在 home-component 中呈现
    • 我已经编辑了我的答案。现在你可以看到: - 路由层次结构 - home 组件 - products 组件 - products-new 组件
    • 请将您的新代码放入您的问题中,而不是作为答案。您需要删除products 下的IndexRoute 并将products 路由更改为&lt;Route path="products" component={products} /&gt;。这将给出你想要的路由。
    猜你喜欢
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 2022-01-22
    • 2017-02-03
    • 2017-08-28
    • 2015-02-21
    相关资源
    最近更新 更多