Skip to content

Commit b84f4f2

Browse files
committed
Lift unstable_shouldRevalidateArgs to DataStrategyMatch
1 parent 668b4f5 commit b84f4f2

File tree

3 files changed

+53
-75
lines changed

3 files changed

+53
-75
lines changed

packages/react-router/lib/dom/ssr/single-fetch.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,7 @@ async function nonSsrStrategy(
302302
// Loaders are trickier since we only want to hit the server once, so we
303303
// create a singular promise for all server-loader routes to latch onto.
304304
async function singleFetchLoaderNavigationStrategy(
305-
{
306-
request,
307-
matches,
308-
unstable_shouldRevalidateArgs: shouldRevalidateArgs,
309-
}: DataStrategyFunctionArgs,
305+
{ request, matches }: DataStrategyFunctionArgs,
310306
manifest: AssetsManifest,
311307
ssr: boolean,
312308
router: DataRouter,
@@ -345,19 +341,18 @@ async function singleFetchLoaderNavigationStrategy(
345341
let manifestRoute = manifest.routes[m.route.id];
346342

347343
let defaultShouldRevalidate =
348-
!shouldRevalidateArgs ||
349-
shouldRevalidateArgs.actionStatus == null ||
350-
shouldRevalidateArgs.actionStatus < 400;
344+
!m.unstable_shouldRevalidateArgs ||
345+
m.unstable_shouldRevalidateArgs.actionStatus == null ||
346+
m.unstable_shouldRevalidateArgs.actionStatus < 400;
351347
let shouldCall = m.unstable_shouldCallHandler(defaultShouldRevalidate);
352348

353349
if (!shouldCall) {
354-
// Mark an opt out route if we currently have data and a `shouldRevalidate`
355-
// function. This implies that the user opted out via `shouldRevalidate`
356-
// so we don't want to include it in the single fetch .data request
350+
// If this route opted out of revalidation, we don't want to include
351+
// it in the single fetch .data request
357352
foundOptOutRoute ||=
358-
manifestRoute?.hasLoader === true &&
359-
m.route.id in router.state.loaderData &&
360-
m.route.shouldRevalidate != null;
353+
m.unstable_shouldRevalidateArgs != null && // This is a revalidation,
354+
manifestRoute?.hasLoader === true && // for a route with a server loader,
355+
m.route.shouldRevalidate != null; // and a shouldRevalidate function
361356
return;
362357
}
363358

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

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,7 +1799,6 @@ export function createRouter(init: RouterInit): Router {
17991799
let results = await callDataStrategy(
18001800
request,
18011801
dsMatches,
1802-
null,
18031802
scopedContext,
18041803
null
18051804
);
@@ -1959,11 +1958,8 @@ export function createRouter(init: RouterInit): Router {
19591958
}
19601959

19611960
let routesToUse = inFlightDataRoutes || dataRoutes;
1962-
let {
1963-
navigationMatches: dsMatches,
1964-
revalidatingFetchers,
1965-
shouldRevalidateArgs,
1966-
} = getMatchesToLoad(
1961+
let { navigationMatches: dsMatches, revalidatingFetchers } =
1962+
getMatchesToLoad(
19671963
request,
19681964
scopedContext,
19691965
mapRouteProperties,
@@ -2053,7 +2049,6 @@ export function createRouter(init: RouterInit): Router {
20532049
await callLoadersAndMaybeResolveData(
20542050
dsMatches,
20552051
revalidatingFetchers,
2056-
shouldRevalidateArgs,
20572052
request,
20582053
scopedContext
20592054
);
@@ -2339,7 +2334,6 @@ export function createRouter(init: RouterInit): Router {
23392334
let actionResults = await callDataStrategy(
23402335
fetchRequest,
23412336
fetchMatches,
2342-
null,
23432337
scopedContext,
23442338
key
23452339
);
@@ -2411,11 +2405,8 @@ export function createRouter(init: RouterInit): Router {
24112405
let loadFetcher = getLoadingFetcher(submission, actionResult.data);
24122406
state.fetchers.set(key, loadFetcher);
24132407

2414-
let {
2415-
navigationMatches: dsMatches,
2416-
revalidatingFetchers,
2417-
shouldRevalidateArgs,
2418-
} = getMatchesToLoad(
2408+
let { navigationMatches: dsMatches, revalidatingFetchers } =
2409+
getMatchesToLoad(
24192410
revalidationRequest,
24202411
scopedContext,
24212412
mapRouteProperties,
@@ -2470,7 +2461,6 @@ export function createRouter(init: RouterInit): Router {
24702461
await callLoadersAndMaybeResolveData(
24712462
dsMatches,
24722463
revalidatingFetchers,
2473-
shouldRevalidateArgs,
24742464
revalidationRequest,
24752465
scopedContext
24762466
);
@@ -2638,7 +2628,6 @@ export function createRouter(init: RouterInit): Router {
26382628
let results = await callDataStrategy(
26392629
fetchRequest,
26402630
dsMatches,
2641-
null,
26422631
scopedContext,
26432632
key
26442633
);
@@ -2829,7 +2818,6 @@ export function createRouter(init: RouterInit): Router {
28292818
async function callDataStrategy(
28302819
request: Request,
28312820
matches: DataStrategyMatch[],
2832-
shouldRevalidateArgs: DataStrategyFunctionArgs["unstable_shouldRevalidateArgs"],
28332821
scopedContext: unstable_RouterContextProvider,
28342822
fetcherKey: string | null
28352823
): Promise<Record<string, DataResult>> {
@@ -2840,7 +2828,6 @@ export function createRouter(init: RouterInit): Router {
28402828
dataStrategyImpl as DataStrategyFunction<unknown>,
28412829
request,
28422830
matches,
2843-
shouldRevalidateArgs,
28442831
fetcherKey,
28452832
scopedContext
28462833
);
@@ -2884,15 +2871,13 @@ export function createRouter(init: RouterInit): Router {
28842871
async function callLoadersAndMaybeResolveData(
28852872
matches: DataStrategyMatch[],
28862873
fetchersToLoad: RevalidatingFetcher[],
2887-
shouldRevalidateArgs: DataStrategyFunctionArgs["unstable_shouldRevalidateArgs"],
28882874
request: Request,
28892875
scopedContext: unstable_RouterContextProvider
28902876
) {
28912877
// Kick off loaders and fetchers in parallel
28922878
let loaderResultsPromise = callDataStrategy(
28932879
request,
28942880
matches,
2895-
shouldRevalidateArgs,
28962881
scopedContext,
28972882
null
28982883
);
@@ -2903,7 +2888,6 @@ export function createRouter(init: RouterInit): Router {
29032888
let results = await callDataStrategy(
29042889
f.request,
29052890
f.matches,
2906-
shouldRevalidateArgs,
29072891
scopedContext,
29082892
f.key
29092893
);
@@ -4250,7 +4234,6 @@ export function createStaticHandler(
42504234
request,
42514235
matches,
42524236
null,
4253-
null,
42544237
requestContext
42554238
);
42564239

@@ -4587,7 +4570,6 @@ function getMatchesToLoad(
45874570
): {
45884571
navigationMatches: DataStrategyMatch[];
45894572
revalidatingFetchers: RevalidatingFetcher[];
4590-
shouldRevalidateArgs: DataStrategyFunctionArgs["unstable_shouldRevalidateArgs"];
45914573
} {
45924574
let actionResult = pendingActionResult
45934575
? isErrorResult(pendingActionResult[1])
@@ -4622,7 +4604,7 @@ function getMatchesToLoad(
46224604
: undefined;
46234605
let shouldSkipRevalidation = actionStatus && actionStatus >= 400;
46244606

4625-
let shouldRevalidateArgs: Omit<
4607+
let baseShouldRevalidateArgs: Omit<
46264608
ShouldRevalidateFunctionArgs,
46274609
"defaultShouldRevalidate"
46284610
> | null = initialHydration
@@ -4709,13 +4691,25 @@ function getMatchesToLoad(
47094691
isNewRouteInstance(state.matches[index], match);
47104692
// Already checked `initialHydration` above so this should always be defined
47114693
invariant(
4712-
shouldRevalidateArgs,
4713-
"Expected shouldRevalidateArgs to be defined for fetcher"
4694+
baseShouldRevalidateArgs,
4695+
"Expected shouldRevalidateArgs to be defined for route match"
47144696
);
4715-
let shouldLoad = shouldRevalidateLoader(match, {
4716-
...shouldRevalidateArgs,
4697+
let shouldRevalidateArgs: ShouldRevalidateFunctionArgs = {
4698+
...baseShouldRevalidateArgs,
47174699
defaultShouldRevalidate,
4718-
});
4700+
};
4701+
let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs);
4702+
let shouldCallHandler: DataStrategyMatch["unstable_shouldCallHandler"] = (
4703+
defaultOverride
4704+
) =>
4705+
shouldRevalidateLoader(match, {
4706+
// We're not in initialHydration here so this will be defined
4707+
...shouldRevalidateArgs!,
4708+
defaultShouldRevalidate:
4709+
typeof defaultOverride === "boolean"
4710+
? defaultOverride
4711+
: defaultShouldRevalidate,
4712+
});
47194713

47204714
return getDataStrategyMatch(
47214715
mapRouteProperties,
@@ -4725,15 +4719,8 @@ function getMatchesToLoad(
47254719
lazyRoutePropertiesToSkip,
47264720
scopedContext,
47274721
shouldLoad,
4728-
(defaultOverride) =>
4729-
shouldRevalidateLoader(match, {
4730-
// We're not in initialHydration here so this will be defined
4731-
...shouldRevalidateArgs!,
4732-
defaultShouldRevalidate:
4733-
typeof defaultOverride === "boolean"
4734-
? defaultOverride
4735-
: defaultShouldRevalidate,
4736-
})
4722+
shouldRevalidateArgs,
4723+
shouldCallHandler
47374724
);
47384725
}
47394726
});
@@ -4846,13 +4833,17 @@ function getMatchesToLoad(
48464833
: isRevalidationRequired;
48474834
// Shouldn't run during initialHydration so this should always be defined
48484835
invariant(
4849-
shouldRevalidateArgs,
4836+
baseShouldRevalidateArgs,
48504837
"Expected shouldRevalidateArgs to be defined for fetcher"
48514838
);
4852-
let shouldLoad = shouldRevalidateLoader(fetcherMatch, {
4853-
...shouldRevalidateArgs,
4839+
let shouldRevalidateArgs: ShouldRevalidateFunctionArgs = {
4840+
...baseShouldRevalidateArgs,
48544841
defaultShouldRevalidate,
4855-
});
4842+
};
4843+
let shouldLoad = shouldRevalidateLoader(
4844+
fetcherMatch,
4845+
shouldRevalidateArgs
4846+
);
48564847

48574848
if (shouldLoad) {
48584849
revalidatingFetchers.push({
@@ -4866,7 +4857,8 @@ function getMatchesToLoad(
48664857
fetcherMatches,
48674858
fetcherMatch,
48684859
lazyRoutePropertiesToSkip,
4869-
scopedContext
4860+
scopedContext,
4861+
shouldRevalidateArgs
48704862
),
48714863
match: fetcherMatch,
48724864
request: fetchRequest,
@@ -4876,11 +4868,7 @@ function getMatchesToLoad(
48764868
}
48774869
});
48784870

4879-
return {
4880-
navigationMatches,
4881-
revalidatingFetchers,
4882-
shouldRevalidateArgs,
4883-
};
4871+
return { navigationMatches, revalidatingFetchers };
48844872
}
48854873

48864874
function shouldLoadRouteOnHydration(
@@ -5532,6 +5520,7 @@ function getDataStrategyMatch(
55325520
lazyRoutePropertiesToSkip: string[],
55335521
scopedContext: unknown,
55345522
shouldLoad: boolean,
5523+
unstable_shouldRevalidateArgs: DataStrategyMatch["unstable_shouldRevalidateArgs"] = null,
55355524
unstable_shouldCallHandler: DataStrategyMatch["unstable_shouldCallHandler"] = () =>
55365525
shouldLoad
55375526
): DataStrategyMatch {
@@ -5551,6 +5540,7 @@ function getDataStrategyMatch(
55515540
return {
55525541
...match,
55535542
shouldLoad,
5543+
unstable_shouldRevalidateArgs,
55545544
unstable_shouldCallHandler(defaultShouldRevalidate) {
55555545
isUsingNewApi = true;
55565546
return unstable_shouldCallHandler(defaultShouldRevalidate);
@@ -5585,7 +5575,8 @@ function getTargetedDataStrategyMatches(
55855575
matches: AgnosticDataRouteMatch[],
55865576
targetMatch: AgnosticDataRouteMatch,
55875577
lazyRoutePropertiesToSkip: string[],
5588-
scopedContext: unknown
5578+
scopedContext: unknown,
5579+
unstable_shouldRevalidateArgs: DataStrategyMatch["unstable_shouldRevalidateArgs"] = null
55895580
): DataStrategyMatch[] {
55905581
return matches.map((match) => {
55915582
if (match.route.id !== targetMatch.route.id) {
@@ -5594,6 +5585,7 @@ function getTargetedDataStrategyMatches(
55945585
return {
55955586
...match,
55965587
shouldLoad: false,
5588+
unstable_shouldRevalidateArgs,
55975589
unstable_shouldCallHandler: () => false,
55985590
_lazyPromises: getDataStrategyMatchLazyPromises(
55995591
mapRouteProperties,
@@ -5613,7 +5605,8 @@ function getTargetedDataStrategyMatches(
56135605
match,
56145606
lazyRoutePropertiesToSkip,
56155607
scopedContext,
5616-
true
5608+
true,
5609+
unstable_shouldRevalidateArgs
56175610
);
56185611
});
56195612
}
@@ -5622,7 +5615,6 @@ async function callDataStrategyImpl(
56225615
dataStrategyImpl: DataStrategyFunction<unknown>,
56235616
request: Request,
56245617
matches: DataStrategyMatch[],
5625-
shouldRevalidateArgs: DataStrategyFunctionArgs["unstable_shouldRevalidateArgs"],
56265618
fetcherKey: string | null,
56275619
scopedContext: unknown
56285620
): Promise<Record<string, DataStrategyResult>> {
@@ -5636,7 +5628,6 @@ async function callDataStrategyImpl(
56365628
// back out below.
56375629
let results = await dataStrategyImpl({
56385630
matches,
5639-
unstable_shouldRevalidateArgs: shouldRevalidateArgs,
56405631
request,
56415632
params: matches[0].params,
56425633
fetcherKey,

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ export interface ShouldRevalidateFunction {
332332
export interface DataStrategyMatch
333333
extends AgnosticRouteMatch<string, AgnosticDataRouteObject> {
334334
shouldLoad: boolean;
335+
// This can be null for actions calls and for initial hydration calls
336+
unstable_shouldRevalidateArgs: ShouldRevalidateFunctionArgs | null;
335337
// TODO: Figure out a good name for this or use `shouldLoad` and add a future flag
336338
// This function will use a scoped version of `shouldRevalidateArgs` because
337339
// they are read-only but let the user provide an optional override value for
@@ -355,16 +357,6 @@ export interface DataStrategyMatch
355357
export interface DataStrategyFunctionArgs<Context = any>
356358
extends DataFunctionArgs<Context> {
357359
matches: DataStrategyMatch[];
358-
// This can be null for actions calls and for initial hydration calls
359-
// We omit the `defaultShouldRevalidate` because it's a per-route choice
360-
// TODO: Should this be embedded on the match? It only applies to revalidating
361-
// matches, so going from `/a/b -> /a/c` it doesn't really apply to `c` but
362-
// could be potentially misconstrued? If we provide it on the matches then
363-
// it can have the proper `defaultShouldRevalidate` value on it
364-
unstable_shouldRevalidateArgs: Omit<
365-
ShouldRevalidateFunctionArgs,
366-
"defaultShouldRevalidate"
367-
> | null;
368360
// TODO: Implement
369361
// runMiddleware: () => unknown,
370362
fetcherKey: string | null;

0 commit comments

Comments
 (0)