Skip to content

Commit

Permalink
fix: useSWRMutation should always use the latest fetcher (#2290)
Browse files Browse the repository at this point in the history
  • Loading branch information
koba04 authored Dec 16, 2022
1 parent 0018706 commit 9ea4a45
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
6 changes: 4 additions & 2 deletions mutation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const mutation = (<Data, Error>() =>
const { mutate } = useSWRConfig()

const keyRef = useRef(key)
const fetcherRef = useRef(fetcher)
// Ditch all mutation results that happened earlier than this timestamp.
const ditchMutationsUntilRef = useRef(0)

Expand All @@ -40,7 +41,7 @@ const mutation = (<Data, Error>() =>
async (arg: any, opts?: SWRMutationConfiguration<Data, Error>) => {
const [serializedKey, resolvedKey] = serialize(keyRef.current)

if (!fetcher) {
if (!fetcherRef.current) {
throw new Error('Can’t trigger the mutation: missing fetcher.')
}
if (!serializedKey) {
Expand All @@ -64,7 +65,7 @@ const mutation = (<Data, Error>() =>
try {
const data = await mutate<Data>(
serializedKey,
(fetcher as any)(resolvedKey, { arg }),
(fetcherRef.current as any)(resolvedKey, { arg }),
// We must throw the error here so we can catch and update the states.
mergeObjects(options, { throwOnError: true })
)
Expand Down Expand Up @@ -99,6 +100,7 @@ const mutation = (<Data, Error>() =>

useIsomorphicLayoutEffect(() => {
keyRef.current = key
fetcherRef.current = fetcher
})

// We don't return `mutate` here as it can be pretty confusing (e.g. people
Expand Down
45 changes: 44 additions & 1 deletion test/use-swr-remote-mutation.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { act, fireEvent, render, screen } from '@testing-library/react'
import React from 'react'
import React, { useState } from 'react'
import useSWR from 'swr'
import useSWRMutation from 'swr/mutation'
import { createKey, sleep, nextTick } from './utils'
Expand Down Expand Up @@ -884,4 +884,47 @@ describe('useSWR - remote mutation', () => {
fireEvent.click(screen.getByText('trigger'))
await screen.findByText('Error: none')
})

it('should always use the latest fetcher', async () => {
const key = createKey()

function Page() {
const [count, setCount] = useState(0)
const { data, trigger } = useSWRMutation(key, () => count)

return (
<div>
<button
onClick={() => {
setCount(c => c + 1)
}}
>
++
</button>
<button
onClick={() => {
trigger()
}}
>
trigger
</button>
<div>
data:{data},count:{count}
</div>
</div>
)
}

render(<Page />)

await screen.findByText('data:,count:0')
fireEvent.click(screen.getByText('trigger'))
await screen.findByText('data:0,count:0')

fireEvent.click(screen.getByText('++'))
await screen.findByText('data:0,count:1')

fireEvent.click(screen.getByText('trigger'))
await screen.findByText('data:1,count:1')
})
})

0 comments on commit 9ea4a45

Please sign in to comment.