@@ -26,63 +26,89 @@ var RouteStore = {
2626 * from the store.
2727 */
2828 unregisterRoute : function ( route ) {
29- if ( route . props . name )
30- delete _namedRoutes [ route . props . name ] ;
29+ var props = route . props ;
3130
32- React . Children . forEach ( route . props . children , function ( child ) {
33- RouteStore . unregisterRoute ( child ) ;
34- } ) ;
31+ if ( props . name )
32+ delete _namedRoutes [ props . name ] ;
33+
34+ React . Children . forEach ( props . children , RouteStore . unregisterRoute ) ;
3535 } ,
3636
3737 /**
3838 * Registers a <Route> and all of its children with the store. Also,
3939 * does some normalization and validation on route props.
4040 */
4141 registerRoute : function ( route , _parentRoute ) {
42- // Make sure the <Route>'s path begins with a slash. Default to its name.
43- // We can't do this in getDefaultProps because it may not be called on
44- // <Route>s that are never actually mounted.
45- if ( route . props . path || route . props . name ) {
46- route . props . path = Path . normalize ( route . props . path || route . props . name ) ;
47- } else {
48- route . props . path = '/' ;
49- }
42+ // Note: When route is a top-level route, _parentRoute
43+ // is actually a <Routes>, not a <Route>. We do this so
44+ // <Routes> can get a defaultRoute like <Route> does.
45+ var props = route . props ;
5046
51- // Make sure the <Route> has a valid React component for a handler.
5247 invariant (
53- React . isValidClass ( route . props . handler ) ,
54- 'The handler for Route "' + ( route . props . name || route . props . path ) + '" ' +
55- 'must be a valid React component'
48+ React . isValidClass ( props . handler ) ,
49+ 'The handler for the "%s" route must be a valid React class' ,
50+ props . name || props . path
5651 ) ;
5752
58- // Make sure the <Route> has all params that its parent needs.
59- if ( _parentRoute ) {
60- var paramNames = Path . extractParamNames ( route . props . path ) ;
53+ // Default routes have no name, path, or children.
54+ var isDefault = ! ( props . path || props . name || props . children ) ;
6155
62- Path . extractParamNames ( _parentRoute . props . path ) . forEach ( function ( paramName ) {
56+ if ( props . path || props . name ) {
57+ props . path = Path . normalize ( props . path || props . name ) ;
58+ } else if ( _parentRoute && _parentRoute . props . path ) {
59+ props . path = _parentRoute . props . path ;
60+ } else {
61+ props . path = '/' ;
62+ }
63+
64+ props . paramNames = Path . extractParamNames ( props . path ) ;
65+
66+ // Make sure the route's path has all params its parent needs.
67+ if ( _parentRoute && Array . isArray ( _parentRoute . props . paramNames ) ) {
68+ _parentRoute . props . paramNames . forEach ( function ( paramName ) {
6369 invariant (
64- paramNames . indexOf ( paramName ) !== - 1 ,
65- 'The nested route path "' + route . props . path + ' " is missing the "' + paramName + '" ' +
66- 'parameter of its parent path "' + _parentRoute . props . path + '"'
70+ props . paramNames . indexOf ( paramName ) !== - 1 ,
71+ 'The nested route path "%s " is missing the "%s" parameter of its parent path "%s"' ,
72+ props . path , paramName , _parentRoute . props . path
6773 ) ;
6874 } ) ;
6975 }
7076
71- // Make sure the <Route> can be looked up by <Link>s.
72- if ( route . props . name ) {
73- var existingRoute = _namedRoutes [ route . props . name ] ;
77+ // Make sure the route can be looked up by <Link>s.
78+ if ( props . name ) {
79+ var existingRoute = _namedRoutes [ props . name ] ;
7480
7581 invariant (
7682 ! existingRoute || route === existingRoute ,
77- 'You cannot use the name "' + route . props . name + '" for more than one route'
83+ 'You cannot use the name "%s" for more than one route' ,
84+ props . name
7885 ) ;
7986
80- _namedRoutes [ route . props . name ] = route ;
87+ _namedRoutes [ props . name ] = route ;
8188 }
8289
83- React . Children . forEach ( route . props . children , function ( child ) {
84- RouteStore . registerRoute ( child , route ) ;
90+ if ( _parentRoute && isDefault ) {
91+ invariant (
92+ _parentRoute . props . defaultRoute == null ,
93+ 'You may not have more than one <DefaultRoute> per <Route>'
94+ ) ;
95+
96+ _parentRoute . props . defaultRoute = route ;
97+
98+ return null ;
99+ }
100+
101+ // Make sure children is an array, excluding <DefaultRoute>s.
102+ var children = [ ] ;
103+
104+ React . Children . forEach ( props . children , function ( child ) {
105+ if ( child = RouteStore . registerRoute ( child , route ) )
106+ children . push ( child ) ;
85107 } ) ;
108+
109+ props . children = children ;
110+
111+ return route ;
86112 } ,
87113
88114 /**
0 commit comments