Skip to content

Commit a015f8b

Browse files
committed
Add callsite revalidation optout to navigations
1 parent b95dff0 commit a015f8b

File tree

3 files changed

+20
-22
lines changed

3 files changed

+20
-22
lines changed

packages/react-router/lib/context.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ export interface NavigateOptions {
154154
flushSync?: boolean;
155155
/** Enables a {@link https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API View Transition} for this navigation by wrapping the final state update in `document.startViewTransition()`. If you need to apply specific styles for this view transition, you will also need to leverage the {@link https://api.reactrouter.com/v7/functions/react_router.useViewTransitionState.html useViewTransitionState()} hook. */
156156
viewTransition?: boolean;
157+
/** When false, suppresses loader revalidation triggered by this navigation **/
158+
defaultShouldRevalidate?: boolean;
157159
}
158160

159161
/**

packages/react-router/lib/dom/lib.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,6 +1287,8 @@ export interface LinkProps
12871287
* To apply specific styles for the transition, see {@link useViewTransitionState}
12881288
*/
12891289
viewTransition?: boolean;
1290+
1291+
defaultShouldRevalidate?: boolean;
12901292
}
12911293

12921294
const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
@@ -1319,6 +1321,7 @@ const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
13191321
* @param {LinkProps.state} props.state n/a
13201322
* @param {LinkProps.to} props.to n/a
13211323
* @param {LinkProps.viewTransition} props.viewTransition [modes: framework, data] n/a
1324+
* @param {LinkProps.defaultShouldRevalidate} props.defaultShouldRevalidate n/a
13221325
*/
13231326
export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
13241327
function LinkWithRef(
@@ -1334,6 +1337,7 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
13341337
to,
13351338
preventScrollReset,
13361339
viewTransition,
1340+
defaultShouldRevalidate,
13371341
...rest
13381342
},
13391343
forwardedRef,
@@ -1389,6 +1393,7 @@ export const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
13891393
preventScrollReset,
13901394
relative,
13911395
viewTransition,
1396+
defaultShouldRevalidate,
13921397
});
13931398
function handleClick(
13941399
event: React.MouseEvent<HTMLAnchorElement, MouseEvent>,
@@ -2183,6 +2188,7 @@ function useDataRouterState(hookName: DataRouterStateHook) {
21832188
* @param options.viewTransition Enables a [View Transition](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
21842189
* for this navigation. To apply specific styles during the transition, see
21852190
* {@link useViewTransitionState}. Defaults to `false`.
2191+
* @param options.defaultShouldRevalidate Defaults to `true`
21862192
* @returns A click handler function that can be used in a custom {@link Link} component.
21872193
*/
21882194
export function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
@@ -2194,13 +2200,15 @@ export function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
21942200
preventScrollReset,
21952201
relative,
21962202
viewTransition,
2203+
defaultShouldRevalidate,
21972204
}: {
21982205
target?: React.HTMLAttributeAnchorTarget;
21992206
replace?: boolean;
22002207
state?: any;
22012208
preventScrollReset?: boolean;
22022209
relative?: RelativeRoutingType;
22032210
viewTransition?: boolean;
2211+
defaultShouldRevalidate?: boolean;
22042212
} = {},
22052213
): (event: React.MouseEvent<E, MouseEvent>) => void {
22062214
let navigate = useNavigate();
@@ -2225,6 +2233,7 @@ export function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
22252233
preventScrollReset,
22262234
relative,
22272235
viewTransition,
2236+
defaultShouldRevalidate,
22282237
});
22292238
}
22302239
},
@@ -2239,6 +2248,7 @@ export function useLinkClickHandler<E extends Element = HTMLAnchorElement>(
22392248
preventScrollReset,
22402249
relative,
22412250
viewTransition,
2251+
defaultShouldRevalidate,
22422252
],
22432253
);
22442254
}
@@ -2549,8 +2559,6 @@ export function useSubmit(): SubmitFunction {
25492559

25502560
return React.useCallback<SubmitFunction>(
25512561
async (target, options = {}) => {
2552-
debugger;
2553-
console.log("useSubmit", target, options);
25542562
let { action, method, encType, formData, body } = getFormSubmissionInfo(
25552563
target,
25562564
basename,

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

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,6 +1511,8 @@ export function createRouter(init: RouterInit): Router {
15111511
// action/loader this will be ignored and the redirect will be a PUSH
15121512
historyAction = NavigationType.Replace;
15131513
}
1514+
let callSiteDefaultShouldRevalidate =
1515+
opts?.defaultShouldRevalidate !== false;
15141516

15151517
let preventScrollReset =
15161518
opts && "preventScrollReset" in opts
@@ -1549,14 +1551,6 @@ export function createRouter(init: RouterInit): Router {
15491551
return;
15501552
}
15511553

1552-
let shouldRevalidate =
1553-
opts && "shouldRevalidate" in opts
1554-
? typeof opts.shouldRevalidate === "function"
1555-
? opts.shouldRevalidate()
1556-
: // undefined should eval to true
1557-
opts.shouldRevalidate !== false
1558-
: true;
1559-
15601554
await startNavigation(historyAction, nextLocation, {
15611555
submission,
15621556
// Send through the formData serialization error if we have one so we can
@@ -1565,8 +1559,8 @@ export function createRouter(init: RouterInit): Router {
15651559
preventScrollReset,
15661560
replace: opts && opts.replace,
15671561
enableViewTransition: opts && opts.viewTransition,
1568-
shouldRevalidate,
15691562
flushSync,
1563+
callSiteDefaultShouldRevalidate,
15701564
});
15711565
}
15721566

@@ -1642,7 +1636,7 @@ export function createRouter(init: RouterInit): Router {
16421636
replace?: boolean;
16431637
enableViewTransition?: boolean;
16441638
flushSync?: boolean;
1645-
shouldRevalidate?: boolean;
1639+
callSiteDefaultShouldRevalidate?: boolean;
16461640
},
16471641
): Promise<void> {
16481642
// Abort any in-progress navigations and start a new one. Unset any ongoing
@@ -1782,15 +1776,6 @@ export function createRouter(init: RouterInit): Router {
17821776

17831777
matches = actionResult.matches || matches;
17841778
pendingActionResult = actionResult.pendingActionResult;
1785-
1786-
if (opts.shouldRevalidate === false) {
1787-
completeNavigation(location, {
1788-
matches,
1789-
...getActionDataForCommit(pendingActionResult),
1790-
});
1791-
return;
1792-
}
1793-
17941779
loadingNavigation = getLoadingNavigation(location, opts.submission);
17951780
flushSync = false;
17961781
// No need to do fog of war matching again on loader execution
@@ -1823,6 +1808,7 @@ export function createRouter(init: RouterInit): Router {
18231808
opts && opts.initialHydration === true,
18241809
flushSync,
18251810
pendingActionResult,
1811+
opts && opts.callSiteDefaultShouldRevalidate !== false,
18261812
);
18271813

18281814
if (shortCircuited) {
@@ -2028,6 +2014,7 @@ export function createRouter(init: RouterInit): Router {
20282014
initialHydration?: boolean,
20292015
flushSync?: boolean,
20302016
pendingActionResult?: PendingActionResult,
2017+
callSiteDefaultShouldRevalidate?: boolean,
20312018
): Promise<HandleLoadersResult> {
20322019
// Figure out the right navigation we want to use for data loading
20332020
let loadingNavigation =
@@ -2135,6 +2122,7 @@ export function createRouter(init: RouterInit): Router {
21352122
basename,
21362123
init.patchRoutesOnNavigation != null,
21372124
pendingActionResult,
2125+
callSiteDefaultShouldRevalidate,
21382126
);
21392127

21402128
pendingNavigationLoadId = ++incrementingLoadId;
@@ -2396,7 +2384,6 @@ export function createRouter(init: RouterInit): Router {
23962384
flushSync,
23972385
preventScrollReset,
23982386
submission,
2399-
// defaultShouldRevalidate, // todo
24002387
);
24012388
}
24022389

@@ -4937,6 +4924,7 @@ function getMatchesToLoad(
49374924
forceShouldLoad,
49384925
);
49394926
}
4927+
49404928
// This is the default implementation for when we revalidate. If the route
49414929
// provides it's own implementation, then we give them full control but
49424930
// provide this value so they can leverage it if needed after they check

0 commit comments

Comments
 (0)