swr icon indicating copy to clipboard operation
swr copied to clipboard

fix: enable global mutate to revalidate useSWRInfinite data with includeSpecialKeys option

Open joseph0926 opened this issue 8 months ago • 3 comments

Problem

After investigating this issue, I traced its origins back to [Issue #1670](https://github.com/vercel/swr/issues/1670) where it was first reported. Following this, [RFC #1946](https://github.com/vercel/swr/issues/1946) mentioned improvements that would address this problem, and the RFC discussion explicitly stated that "special keys would be excluded." This was then implemented in [PR #1989](https://github.com/vercel/swr/pull/1989) where special keys were indeed excluded.

However, the problem is that global mutate ignores special keys - specifically the $inf$ keys - causing revalidation failures for useSWRInfinite data.

Investigation Process

To solve this, I added a new includeSpecialKeys flag to MutatorOptions to create an exception in the // Skip the special useSWRInfinite and useSWRSubscription keys conditional. This seemed promising, and I wrote several edge test cases to verify the solution.

However, I discovered an additional problem: useSWRInfinite sets an _i flag in the cache when calling its own mutate, which the fetcher checks to determine whether to refetch all pages. The issue was that global mutate had no way to set this flag (at least not within the scope of what a regular contributor could modify in a single PR).

While there are several potential solutions - like automatically setting the _i flag during fetcher traversal (though this makes responsibility boundaries unclear) or adding a new flag (which would mean adding two flags just for global mutate) - the final solution was to have includeSpecialKeys also handle setting the _i flag when true.

Solution

This PR adds an includeSpecialKeys option to MutatorOptions that

  1. Includes special keys ($inf$, $sub$) in the matcher function
  2. Automatically sets the _i flag for $inf$ keys to trigger full revalidation

Usage

mutate(
  key => key.includes('/api/todos'),
  undefined,
  { revalidate: true, includeSpecialKeys: true }
)

Testing

Added comprehensive test cases covering:

  • Basic revalidation of infinite queries
  • Mixed useSWR and useSWRInfinite scenarios
  • Performance with large cache
  • Edge cases with empty matchers and concurrent mutations

Fixes #4149

joseph0926 avatar Aug 25 '25 05:08 joseph0926

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

codesandbox-ci[bot] avatar Aug 25 '25 05:08 codesandbox-ci[bot]

Please review and merge this !

SuperstrongBE avatar Aug 27 '25 20:08 SuperstrongBE

Hi @shuding @huozhi — just a gentle bump on this PR.

Happy to adjust the approach, split into smaller PRs, or follow any project preferences.
If there’s anything blocking review, please let me know. Thanks!

joseph0926 avatar Sep 06 '25 00:09 joseph0926