#4247·swr

[useSWRMutation] `trigger` called within `<form action />` won't have proper `isMutating`

Author: SukkaWCreated Apr 24, 2026Updated Apr 24, 2026

Bug report

Description / Observed Behavior

typescript
  async function formAction(formData: FormData) {
    const username = formData.get('username') as string;
    await trigger({ username });
    await mutate({ username });
  }

        <form action={formAction}>
          <input />
          <p>After clicking the button, the button's text should change to "Saving..."</p>
          <button type="submit" disabled={isMutating} style={{ padding: '0.4rem 1rem', fontSize: '1rem' }}>
            {isMutating ? 'Saving...' : 'Update'}
          </button>
        </form>

When the button is clicked, the button never shows Saving... and is stuck with Update.

Expected Behavior

When the button is clicked, the button text should transition to Saving..., and back to Update after mutatoin is finishes.

Repro Steps / Code Example

Reproduction: https://github.com/sukka-reproductions/swr-mutation-transition Online demo: https://swr-mutation-transition.pages.dev/

Additional Context

SWR version: 2.4.1

useSWRMutation's trigger updates isMutaing via setState({ isMutaing: true }).

However, <form action />'s action prop creates a React async transition (similar to startTransition) here. In React async transitions, any state update (like setState({ isMutaing: true }) in useSWRMutation) gets scheduled and "delayed", and will only happen (and re-render) after the async function is resolved/rejected. But this also means the isMutaing never got a chance to be rendered as true.