Skip to content

Global mutate with a matcher function does not receive keys from useSWRInfinite #4149

@AayushBharti

Description

@AayushBharti

When using a matcher function with the global mutate API from useSWRConfig, keys generated by useSWRInfinite hooks are not passed to the matcher. This prevents the global invalidation of all pages of an infinite query, which is a necessary pattern for actions like adding a new item to a collection that affects all pages.

The same matcher function correctly receives keys from standard useSWR hooks, but it completely ignores the keys associated with useSWRInfinite (which are prefixed with $inf$).

Expected Behavior

I expect that a matcher function provided to the global mutate(matcher, ...) would be called with all active keys in the SWR cache. This should include the internal keys used by useSWRInfinite, allowing for global revalidation of infinite queries using a filter, like so:

mutate((key) => /boards/.test(key), null);

Observed Behavior

The matcher function is only ever called for keys associated with standard useSWR hooks. When logging the key argument inside the matcher, the keys managed by useSWRInfinite never appear, even though they are confirmed to be present in the cache.

As a result, attempting to globally mutate an infinite query with a regex or function matcher fails silently, as the relevant keys are never processed.

Steps to Reproduce

  1. Set up an infinite query: Create a component (Component A) that uses the useSWRInfinite hook to fetch paginated data.

    import useSWRInfinite from 'swr/infinite';
    
    const getKey = (pageIndex, previousPageData) => {
      if (previousPageData && !previousPageData.content.length) return null;
      return `/boards?page=${pageIndex}&perPage=25`;
    };
    
    const { data } = useSWRInfinite(getKey, fetcher);
  2. Attempt a global mutation: In a separate component (Component B) or global function, call mutate with a matcher function designed to target the infinite query keys.

    // Component B
    import { useSWRConfig } from 'swr';
    
    const { mutate } = useSWRConfig();
    
    const revalidateBoards = () => {
      mutate(
        (key) => {
          // This log will NEVER show keys starting with "$inf$/boards..."
          console.log('Key received by matcher:', key);
          return /^\$inf\$\/boards/.test(key);
        },
        null, // Revalidate
        { revalidate: true }
      );
    };
  3. Trigger the mutation: Call the revalidateBoards function.

  4. Observe the console: Notice that the console.log inside the matcher is never executed for the keys belonging to useSWRInfinite. The infinite query is not revalidated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions