Skip to content

Commit d5ec922

Browse files
committed
Move route discovery logic back to fetcher handlers
1 parent 5c7091d commit d5ec922

File tree

1 file changed

+88
-56
lines changed

1 file changed

+88
-56
lines changed

packages/react-router/lib/router/router.ts

Lines changed: 88 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2237,56 +2237,27 @@ export function createRouter(init: RouterInit): Router {
22372237
matches = fogOfWar.matches;
22382238
}
22392239

2240+
if (!matches) {
2241+
setFetcherError(
2242+
key,
2243+
routeId,
2244+
getInternalRouterError(404, { pathname: normalizedPath }),
2245+
{ flushSync }
2246+
);
2247+
return;
2248+
}
2249+
22402250
let { path, submission, error } = normalizeNavigateOptions(
22412251
true,
22422252
normalizedPath,
22432253
opts
22442254
);
22452255

2246-
let abortController = new AbortController();
2247-
2248-
if (!matches) {
2249-
if (!fogOfWar.active) {
2250-
setFetcherError(
2251-
key,
2252-
routeId,
2253-
getInternalRouterError(404, { pathname: normalizedPath }),
2254-
{ flushSync }
2255-
);
2256-
return;
2257-
} else {
2258-
let discoverResult = await discoverRoutes(
2259-
matches ?? [],
2260-
path,
2261-
abortController.signal,
2262-
key
2263-
);
2264-
2265-
if (discoverResult.type === "aborted") {
2266-
return;
2267-
} else if (discoverResult.type === "error") {
2268-
setFetcherError(key, routeId, discoverResult.error, { flushSync });
2269-
return;
2270-
} else if (!discoverResult.matches) {
2271-
setFetcherError(
2272-
key,
2273-
routeId,
2274-
getInternalRouterError(404, { pathname: path }),
2275-
{ flushSync }
2276-
);
2277-
return;
2278-
} else {
2279-
matches = discoverResult.matches;
2280-
}
2281-
}
2282-
}
2283-
22842256
if (error) {
22852257
setFetcherError(key, routeId, error, { flushSync });
22862258
return;
22872259
}
22882260

2289-
let match = getTargetMatch(matches, path);
22902261
// Create a new context per fetch
22912262
let scopedContext = new unstable_RouterContextProvider(
22922263
init.unstable_getContext ? await init.unstable_getContext() : undefined
@@ -2298,10 +2269,9 @@ export function createRouter(init: RouterInit): Router {
22982269
key,
22992270
routeId,
23002271
path,
2301-
match,
23022272
matches,
23032273
scopedContext,
2304-
abortController,
2274+
fogOfWar.active,
23052275
flushSync,
23062276
preventScrollReset,
23072277
submission
@@ -2316,10 +2286,9 @@ export function createRouter(init: RouterInit): Router {
23162286
key,
23172287
routeId,
23182288
path,
2319-
match,
23202289
matches,
23212290
scopedContext,
2322-
abortController,
2291+
fogOfWar.active,
23232292
flushSync,
23242293
preventScrollReset,
23252294
submission
@@ -2332,25 +2301,27 @@ export function createRouter(init: RouterInit): Router {
23322301
key: string,
23332302
routeId: string,
23342303
path: string,
2335-
match: AgnosticDataRouteMatch,
23362304
requestMatches: AgnosticDataRouteMatch[],
23372305
scopedContext: unstable_RouterContextProvider,
2338-
abortController: AbortController,
2306+
isFogOfWar: boolean,
23392307
flushSync: boolean,
23402308
preventScrollReset: boolean,
23412309
submission: Submission
23422310
) {
23432311
interruptActiveLoads();
23442312
fetchLoadMatches.delete(key);
23452313

2346-
if (!match.route.action && !match.route.lazy) {
2347-
let error = getInternalRouterError(405, {
2348-
method: submission.formMethod,
2349-
pathname: path,
2350-
routeId: routeId,
2351-
});
2352-
setFetcherError(key, routeId, error, { flushSync });
2353-
return;
2314+
function detectAndHandle405Error(m: AgnosticDataRouteMatch) {
2315+
if (!m.route.action && !m.route.lazy) {
2316+
let error = getInternalRouterError(405, {
2317+
method: submission.formMethod,
2318+
pathname: path,
2319+
routeId: routeId,
2320+
});
2321+
setFetcherError(key, routeId, error, { flushSync });
2322+
return true;
2323+
}
2324+
return false;
23542325
}
23552326

23562327
// Put this fetcher into it's submitting state
@@ -2359,13 +2330,46 @@ export function createRouter(init: RouterInit): Router {
23592330
flushSync,
23602331
});
23612332

2333+
let abortController = new AbortController();
23622334
let fetchRequest = createClientSideRequest(
23632335
init.history,
23642336
path,
23652337
abortController.signal,
23662338
submission
23672339
);
23682340

2341+
if (isFogOfWar) {
2342+
let discoverResult = await discoverRoutes(
2343+
requestMatches,
2344+
path,
2345+
fetchRequest.signal,
2346+
key
2347+
);
2348+
2349+
if (discoverResult.type === "aborted") {
2350+
return;
2351+
} else if (discoverResult.type === "error") {
2352+
setFetcherError(key, routeId, discoverResult.error, { flushSync });
2353+
return;
2354+
} else if (!discoverResult.matches) {
2355+
setFetcherError(
2356+
key,
2357+
routeId,
2358+
getInternalRouterError(404, { pathname: path }),
2359+
{ flushSync }
2360+
);
2361+
return;
2362+
} else {
2363+
requestMatches = discoverResult.matches;
2364+
}
2365+
}
2366+
2367+
let match = getTargetMatch(requestMatches, path);
2368+
2369+
if (detectAndHandle405Error(match)) {
2370+
return;
2371+
}
2372+
23692373
// Call the action for the fetcher
23702374
fetchControllers.set(key, abortController);
23712375

@@ -2608,10 +2612,9 @@ export function createRouter(init: RouterInit): Router {
26082612
key: string,
26092613
routeId: string,
26102614
path: string,
2611-
match: AgnosticDataRouteMatch,
26122615
matches: AgnosticDataRouteMatch[],
26132616
scopedContext: unstable_RouterContextProvider,
2614-
abortController: AbortController,
2617+
isFogOfWar: boolean,
26152618
flushSync: boolean,
26162619
preventScrollReset: boolean,
26172620
submission?: Submission
@@ -2626,12 +2629,41 @@ export function createRouter(init: RouterInit): Router {
26262629
{ flushSync }
26272630
);
26282631

2632+
let abortController = new AbortController();
26292633
let fetchRequest = createClientSideRequest(
26302634
init.history,
26312635
path,
26322636
abortController.signal
26332637
);
26342638

2639+
if (isFogOfWar) {
2640+
let discoverResult = await discoverRoutes(
2641+
matches,
2642+
path,
2643+
fetchRequest.signal,
2644+
key
2645+
);
2646+
2647+
if (discoverResult.type === "aborted") {
2648+
return;
2649+
} else if (discoverResult.type === "error") {
2650+
setFetcherError(key, routeId, discoverResult.error, { flushSync });
2651+
return;
2652+
} else if (!discoverResult.matches) {
2653+
setFetcherError(
2654+
key,
2655+
routeId,
2656+
getInternalRouterError(404, { pathname: path }),
2657+
{ flushSync }
2658+
);
2659+
return;
2660+
} else {
2661+
matches = discoverResult.matches;
2662+
}
2663+
}
2664+
2665+
let match = getTargetMatch(matches, path);
2666+
26352667
// Call the loader for this fetcher route match
26362668
fetchControllers.set(key, abortController);
26372669

@@ -3236,7 +3268,7 @@ export function createRouter(init: RouterInit): Router {
32363268
true
32373269
);
32383270

3239-
return { active: true, matches: fogMatches };
3271+
return { active: true, matches: fogMatches || [] };
32403272
} else {
32413273
if (Object.keys(matches[0].params).length > 0) {
32423274
// If we matched a dynamic param or a splat, it might only be because

0 commit comments

Comments
 (0)