@@ -26,63 +26,89 @@ var RouteStore = {
26
26
* from the store.
27
27
*/
28
28
unregisterRoute : function ( route ) {
29
- if ( route . props . name )
30
- delete _namedRoutes [ route . props . name ] ;
29
+ var props = route . props ;
31
30
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 ) ;
35
35
} ,
36
36
37
37
/**
38
38
* Registers a <Route> and all of its children with the store. Also,
39
39
* does some normalization and validation on route props.
40
40
*/
41
41
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 ;
50
46
51
- // Make sure the <Route> has a valid React component for a handler.
52
47
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
56
51
) ;
57
52
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 ) ;
61
55
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 ) {
63
69
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
67
73
) ;
68
74
} ) ;
69
75
}
70
76
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 ] ;
74
80
75
81
invariant (
76
82
! 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
78
85
) ;
79
86
80
- _namedRoutes [ route . props . name ] = route ;
87
+ _namedRoutes [ props . name ] = route ;
81
88
}
82
89
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 ) ;
85
107
} ) ;
108
+
109
+ props . children = children ;
110
+
111
+ return route ;
86
112
} ,
87
113
88
114
/**
0 commit comments