这个.props.children对于<route>是不同于其他React组件?

时间:2017-01-15 07:36:13

标签: javascript reactjs react-router

每个react组件都通过以下函数传递,可在node_modules中找到ReactElement.js:

ReactElement.createElement = function (type, config, children){
   .
   .
   .
}

这还包括<Route><Router>。请考虑React Tutorial中的以下JSX代码:

<Router history={hashHistory}>
    <Route path="/" component={Layout}>
        <IndexRoute component={Featured} />
        <Route path="Settings" component={Settings} />
        <Route path="Archives" component={Archives} />
    </Route> 
</Router>

以上代码将使用Babel <:p>转换为下面显示的代码

"use strict";

React.createElement(
    Router,
    { history: hashHistory },
    React.createElement(
        Route,
        { path: "/", component: Layout },
        React.createElement(IndexRoute, { component: Featured }),
        React.createElement(Route, { path: "Settings", component: Settings }),
        React.createElement(Route, { path: "Archives", component: Archives })
    )
);

通过此代码,&#34;孩子&#34;外<Route>的内部是<Route>s。我们知道:

<MyContainer>
  <MyFirstComponent />
  <MySecondComponent />
</MyContainer>

class MyContainer extends React.Component{
   render(){
      return (
         .
         .
         //This will be MyFirstComponent or MySecondComponent 
         {this.props.children}
         .
         .
       );
   }
}

<Route>s的情况并非如此。 JSX路由器代码的this.prop.children值适用于component道具,但不适用于路由器本身。为什么this.props.children对<Route>的这种行为与任何其他ReactComponent不同?

1 个答案:

答案 0 :(得分:2)

因为路由器删除了路由孩子的孩子。

这里是react-router 3.0.1中的createRouteFromReactElement function from RouteUtils.js

export function createRouteFromReactElement(element) {
  const type = element.type
  const route = createRoute(type.defaultProps, element.props)

  if (route.children) {
    const childRoutes = createRoutesFromReactChildren(route.children, route)

    if (childRoutes.length)
      route.childRoutes = childRoutes

    delete route.children
  }

  return route
}

注意结尾的第五行:delete route.children

为什么这样做?考虑这个不变的警告from Route.prototype.render

render() {
  invariant(
    false,
    '<Route> elements are for router configuration only and should not be rendered'
  )
}