TanStack / TanStack/query

useMutationState does not update when filters change (react-query)

Open
#11,272 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
50.3k
Forks
4.2k
Avg merge
18h 25m
Merged PRs (30d)
200

Description

Describe the bug

useMutationState() ignores changes to filters. The result is only recomputed when the mutation cache notifies, so after a filter change the array keeps showing the old filters' results until something unrelated touches the cache. If nothing does, it stays wrong.

result.current is only written inside the mutationCache.subscribe() callback, and getSnapshot is () => result.current. So a render with new options recomputes nothing.

Same symptom as #11152 / #11153 in svelte-query, different cause.

Your minimal, reproducible example

N/A, reproduces in the package's own vitest suite.

Steps to reproduce

Add to packages/react-query/src/__tests__/useMutationState.test.tsx, run pnpm nx run @tanstack/react-query:test:lib -- useMutationState:

it('should update the result when mutation filters change without a cache update', async () => {
  const queryClient = new QueryClient()
  const key1 = queryKey()
  const key2 = queryKey()

  function Variables({ mutationKey }: { mutationKey?: Array<string> }) {
    const variables = useMutationState({
      filters: { mutationKey },
      select: (mutation) => mutation.state.variables,
    })

    return <div>variables: {variables.join(',')}</div>
  }

  function Page({ mutationKey }: { mutationKey?: Array<string> }) {
    const { mutate: mutate1 } = useMutation({
      mutationKey: key1,
      mutationFn: (input: number) => sleep(100).then(() => 'data' + input),
    })
    const { mutate: mutate2 } = useMutation({
      mutationKey: key2,
      mutationFn: (input: number) => sleep(100).then(() => 'data' + input),
    })

    React.useEffect(() => {
      mutate1(1)
      mutate2(2)
    }, [mutate1, mutate2])

    return <Variables mutationKey={mutationKey} />
  }

  const rendered = renderWithClient(queryClient, <Page mutationKey={undefined} />)

  await vi.advanceTimersByTimeAsync(0)
  expect(rendered.getByText('variables: 1,2')).toBeInTheDocument()

  rendered.rerender(<Page mutationKey={key1} />)

  expect(rendered.getByText('variables: 1')).toBeInTheDocument()
})

Both mutations stay pending, so the cache never notifies. Output stays variables: 1,2 instead of variables: 1.

Expected behavior

The array should always reflect whatever filters currently select, as it does in vue-query, angular and lit.

How often does this bug happen?

Every time

Platform

N/A, jsdom.

Tanstack Query adapter

react-query

TanStack Query version

v5.102.2

TypeScript version

v6.0.3

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the useMutationState implementation and its getSnapshot and mutationCache.subscribe logic, then add the regression case to packages/react-query/src/tests/useMutationState.test.tsx. Run pnpm nx run @tanstack/react-query:test:lib -- useMutationState. Done means the result updates from variables: 1,2 to variables: 1 when filters change without a cache update.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, testing
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.