Skip to content

Commit 737863d

Browse files
committed
Router: Instead of returning single-element-array, return element
1 parent c7afc0a commit 737863d

File tree

1 file changed

+31
-47
lines changed

1 file changed

+31
-47
lines changed

packages/router/src/router.tsx

+31-47
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ const LocationAwareRouter: React.FC<RouterProps> = ({
198198
)
199199
}
200200

201-
const { activeRouteTree, activeRoute, NotFoundPage } = analyzeRouteTree(
201+
const { activeRoute, activePath, NotFoundPage } = analyzeRouterTree(
202202
children,
203203
pathname,
204204
paramTypes
@@ -210,15 +210,14 @@ const LocationAwareRouter: React.FC<RouterProps> = ({
210210
paramTypes={paramTypes}
211211
pageLoadingDelay={pageLoadingDelay}
212212
>
213-
<ParamsProvider path={activeRoute?.props?.path}>
214-
{!activeRoute && NotFoundPage ? (
213+
<ParamsProvider path={activePath}>
214+
{!activeRoute && NotFoundPage && (
215215
<PageLoader
216216
spec={normalizePage(NotFoundPage)}
217217
delay={pageLoadingDelay}
218218
/>
219-
) : (
220-
activeRoute && activeRouteTree
221219
)}
220+
{activeRoute}
222221
</ParamsProvider>
223222
</RouterContextProvider>
224223
)
@@ -234,49 +233,44 @@ const LocationAwareRouter: React.FC<RouterProps> = ({
234233
* route, and in that case we don't need the NotFoundPage, so it doesn't
235234
* matter.
236235
*/
237-
function analyzeRouteTree(
236+
function analyzeRouterTree(
238237
children: React.ReactNode,
239238
pathname: string,
240239
paramTypes?: Record<string, ParamType>
241240
) {
242-
let activeRoute: React.ReactElement<InternalRouteProps> | undefined =
243-
undefined
244241
let NotFoundPage: PageType | undefined = undefined
242+
let activePath: string | undefined = undefined
245243

246244
function isActiveRoute(route: React.ReactElement<InternalRouteProps>) {
247245
if (route.props.path) {
248246
const { match } = matchPath(route.props.path, pathname, paramTypes)
249247

250248
if (match) {
251-
// No need to loop further. As soon as we have a matching route we have
252-
// all the info we need
253249
return true
254250
}
255251
}
256252

257-
if (route.props.notfound && route.props.page) {
258-
NotFoundPage = route.props.page
259-
}
260-
261253
return false
262254
}
263255

264-
function analyzeRouteTreeInternal(children: React.ReactNode) {
265-
let active = false
266-
267-
const activeRouteTree = React.Children.toArray(children).reduce<
268-
React.ReactNode[]
269-
>((acc, child) => {
270-
if (active) {
271-
return acc
256+
function analyzeRouterTreeInternal(
257+
children: React.ReactNode
258+
): React.ReactElement | undefined {
259+
return React.Children.toArray(children).reduce<
260+
React.ReactElement | undefined
261+
>((previousValue, child) => {
262+
if (previousValue) {
263+
return previousValue
272264
}
273265

274266
if (isRoute(child)) {
267+
if (child.props.notfound && child.props.page) {
268+
NotFoundPage = child.props.page
269+
}
270+
275271
// We have a <Route ...> element, let's check if it's the one we should
276272
// render (i.e. the active route)
277-
active = isActiveRoute(child)
278-
279-
if (active) {
273+
if (isActiveRoute(child)) {
280274
// All <Route>s have a key that React has generated for them.
281275
// Something like '.1', '.2', etc
282276
// But we know we'll only ever render one <Route>, so we can give
@@ -289,38 +283,28 @@ function analyzeRouteTree(
289283
key: '.rw-route',
290284
})
291285

292-
// Keep this child. It's the last one we'll keep since `active` is `true`
293-
// now
294-
acc.push(childWithKey)
286+
activePath = child.props.path
295287

296-
activeRoute = childWithKey
288+
return childWithKey
297289
}
298290
} else if (isReactElement(child) && child.props.children) {
299291
// We have a child element that's not a <Route ...>, and that has
300292
// children. It's probably a <Set>. Recurse down one level
301-
const nestedChildren = analyzeRouteTreeInternal(child.props.children)
302-
303-
if (nestedChildren.activeRouteTree.length > 0) {
304-
// We found something we wanted to keep. So let's push it to our
305-
// "active route tree"
306-
acc.push(
307-
React.cloneElement(
308-
child,
309-
child.props,
310-
nestedChildren.activeRouteTree
311-
)
312-
)
313-
active = true
293+
const nestedActive = analyzeRouterTreeInternal(child.props.children)
294+
295+
if (nestedActive) {
296+
// We found something we wanted to keep. So let's return it
297+
return React.cloneElement(child, child.props, nestedActive)
314298
}
315299
}
316300

317-
return acc
318-
}, [])
319-
320-
return { activeRouteTree, activeRoute, NotFoundPage }
301+
return previousValue
302+
}, undefined)
321303
}
322304

323-
return analyzeRouteTreeInternal(children)
305+
const activeRoute = analyzeRouterTreeInternal(children)
306+
307+
return { activeRoute, activePath, NotFoundPage }
324308
}
325309

326310
function isSpec(specOrPage: Spec | React.ComponentType): specOrPage is Spec {

0 commit comments

Comments
 (0)