Skip to content
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 fetcher revalidation logic #10344

Merged
merged 2 commits into from Apr 14, 2023
Merged

Conversation

brophdawg11
Copy link
Contributor

  • Fetchers no longer revalidate on search param changes or when routing to the same URL
  • Also fixed a semi-related bug where fetcher.load redirects wouldn't be marked as done on the completion of the redirect

@changeset-bot
Copy link

changeset-bot bot commented Apr 14, 2023

🦋 Changeset detected

Latest commit: 53698a6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
@remix-run/router Patch
react-router Patch
react-router-dom Patch
react-router-dom-v5-compat Patch
react-router-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

// We called fetcher.load('/parent') from the root route, so when we
// redirect back to the root it triggers a revalidation of the
// fetcher.load('/parent')
await B.loaders.parent.resolve("Revalidated");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test flow no longer triggers a fetcher revalidation

@@ -814,7 +814,7 @@ export function createRouter(init: RouterInit): Router {
// Fetchers that triggered data reloads as a result of their actions
let fetchReloadIds = new Map<string, number>();

// Fetchers that triggered redirect navigations from their actions
// Fetchers that triggered redirect navigations
let fetchRedirectIds = new Set<string>();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This captures fetcher.load redirects now as well

@@ -1470,12 +1470,14 @@ export function createRouter(init: RouterInit): Router {

// Short circuit if we have no loaders to run
if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {
let updatedFetchers = markFetchRedirectsDone();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a bug before as well - but since fetcher's were too-eagerly revalidating it wasn't common to have a fetch-driven redirect that triggered zero loaders.

...(didAbortFetchLoads || revalidatingFetchers.length > 0
? { fetchers: new Map(state.fetchers) }
: {}),
...(shouldUpdateFetchers ? { fetchers: new Map(state.fetchers) } : {}),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that if any fetch redirects got cleaned up we commit them

@@ -1971,6 +1973,7 @@ export function createRouter(init: RouterInit): Router {

// If the loader threw a redirect Response, start a new REPLACE navigation
if (isRedirectResult(result)) {
fetchRedirectIds.add(key);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Track fetcher.load redirects as well so they can get cleaned up on completion of the redirect navigation

- Fetchers no longer revalidate on search param changes or when routing to the same URL
- Also fixed a semi-related bug where fetcher.load redirects wouldn't be marked as done on the completion of the redirect
@brophdawg11 brophdawg11 force-pushed the brophdawg11/fetcher-revalidation branch from 99b3acc to 7603a77 Compare April 14, 2023 14:31
@@ -9578,7 +9571,7 @@ describe("a router", () => {
});
});

it("revalidates fetchers on searchParams changes", async () => {
it("does not revalidate fetchers on searchParams changes", async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change tests asserting the old incorrect behavior

@@ -3231,7 +3234,8 @@ function getMatchesToLoad(
nextParams: matches[matches.length - 1].params,
...submission,
actionResult,
defaultShouldRevalidate,
// Forced revalidation due to submission, useRevalidate, or X-Remix-Revalidate
defaultShouldRevalidate: isRevalidationRequired,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the crux of the bug fix. Fetchers should not use the same logic as routes (which takes into account search params and same-URL navigations). They should only revalidate on action submissions, router.revalidate, or X-Remix-Revalidate

@ryanflorence ryanflorence merged commit 530a504 into dev Apr 14, 2023
2 checks passed
@ryanflorence ryanflorence deleted the brophdawg11/fetcher-revalidation branch April 14, 2023 16:25
@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version 6.11.0-pre.0 which includes this pull request. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

@github-actions
Copy link
Contributor

🤖 Hello there,

We just published version 6.11.0 which includes this pull request. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants