-
-
Notifications
You must be signed in to change notification settings - Fork 10.8k
fix: pass skipRevalidation option through middleware pipeline in singleFetchAction #14286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: pass skipRevalidation option through middleware pipeline in singleFetchAction #14286
Conversation
|
|
This should address #14285 as well 👍 |
|
Shouldn't the flag be |
You are correct
Therefore, I based my work on the So in order to follow the contribution guidelines and run tests, I had no choice but to proceed with |
|
Oh, sorry, the search only looks at the default branch, so I missed that change on dev. Nevermind! |
|
Should I add a changeset for this bug fix? |
|
Thank you for signing the Contributor License Agreement. Let's get this merged! 🥳 |
|
improve test isolation and cleanup console.log handling add beforeEach/afterEach hooks to properly save and restore console.log and remove unnecessary console output to keep CI logs clean |
|
|
|
Thank you for the PR @joseph0926! We can fix this in a slightly simpler manner by falling back on the internal |
|
🤖 Hello there, We just published version Thanks! |
|
🤖 Hello there, We just published version Thanks! |
|
When visiting Is this a limitation of multi-level nested routes, or is there something I'm overlooking in the configuration? Any guidance would be appreciated! |
|
Can you open an issue with a minimal reproduction and we can take a look? |
|
As I understand it, your comment implies that in a nested route structure, if export default [
index(“routes/home.tsx”),
// Here, if shouldRevalidate returns false...
layout(“routes/layout.tsx”, [
// Here, you expect it to work without explicitly returning false
route(“servers”, “routes/servers/list.tsx”, [
route(“new”, “routes/servers/new.tsx”),
route(“:id”, “routes/servers/detail.tsx”),
]),
])
] satisfies RouteConfig;However, the official documentation states Based on these statements, I'm guessing this is the intended behavior? Also, in the code react-router/packages/react-router/lib/router/router.ts Lines 5005 to 5017 in c1cdded
Looking at this, it doesn't seem like a design that affects propagation or sub-layouts... I'm not sure. Also, it doesn't seem significantly related to the core issue of this PR—that the parent loader keeps getting called even when |
|
|
Note on Middleware Selection
Description
Fixes a regression where
shouldRevalidate: falseis ignored whenv8_middlewareis enabled in SSR mode, causing unnecessary parent loader re-executions during child route navigation.Problem
When using React Router v7.8.2 with
ssr: truev8_middleware: trueshouldRevalidate: () => falseThe parent loader is incorrectly re-executed on every child route navigation, despite
shouldRevalidatereturningfalse. This does not occur whenv8_middleware: false.Root Cause
After comparing v7.8.1 (working) and v7.8.2 (broken), I identified the issue in the middleware implementation
packages/react-router/lib/server-runtime/single-fetch.tsskipRevalidation: trueoption is set insingleFetchActionto prevent unnecessary loader re-executionsgenerateMiddlewareResponseis provided (middleware enabled), this option is not forwarded to the innerquerycallpackages/react-router/lib/router/router.tsgenerateMiddlewareResponsecallback signature doesn't includeskipRevalidationin itsargstypeopts?.skipRevalidationbut it's alwaysundefinedbecause it's not passed throughSolution
Changes Made
packages/react-router/lib/server-runtime/single-fetch.tsgenerateMiddlewareResponse: build.future.v8_middleware ? async (query) => { try { - let innerResult = await query(handlerRequest); + let innerResult = await query(handlerRequest, { + filterMatchesToLoad: (m) => !loadRouteIds || loadRouteIds.has(m.route.id), + skipRevalidation: true + }); return handleQueryResult(innerResult); } catch (error) { return handleQueryError(error); } } : undefined,Type definitions updated: to include
skipRevalidationin thegenerateMiddlewareResponsecallback signaturegenerateMiddlewareResponse?: ( query: ( r: Request, args?: { filterMatchesToLoad?: (match: AgnosticDataRouteMatch) => boolean; + skipRevalidation?: boolean; }, ) => Promise<StaticHandlerContext | Response>, ) => MaybePromise<Response>;Test Plan
Added new integration test:
integration/middleware-revalidate-test.tsThe test verifies
shouldRevalidate: () => falsev8_middleware: false(passes) andv8_middleware: true(now passes with fix)Test Results
v8_middleware: falsepasses,v8_middleware: truefails (parent loader called 4 times)Breaking Changes
None. This is a bug fix that restores the intended behavior of
shouldRevalidate: falsewhen middleware is enabled.Related Issues
Fixes #14257