SWR 2.0 coming soon, and this is the first beta version!
Keep in mind that APIs might still change until the stable release. Documentation will also be updated once stable.
💖 Give feedback in discussion: #1919.
Highlights
useSWRMutation — dedicated API for remote mutations, e.g. POST (#1450)
Added in #1450, the new useSWRMutation
hook covers all the use cases of:
- Requests that change data on the remote side: such as POST, PUT, DELETE, etc.
- Requests that need to be triggered manually, instead of automatically by SWR.
- Passing extra argument to fetcher, when triggering a request.
- Knowing the status of a mutation, similar to
isValidating
but for mutations. - A lot more...
Here's a quick example of how it looks:
import useSWRMutation from 'swr/mutation'
async function sendRequest(url, { arg }) {
return fetch(url, {
method: 'POST',
body: JSON.stringify(arg)
})
}
function App() {
const { trigger } = useSWRMutation('/api/user', sendRequest)
return <button onClick={() => {
trigger({ username: 'johndoe' })
}}>Create User</button>
}
In this example, the "fetcher", which is sendRequest
, will receive the value { username: 'johndoe' }
as the arg
from the second parameter. The request will only be triggered when clicking the button.
The new useSWRMutation
hook is actually more powerful than this, it also supports:
- Optimistic updates
- Automatic error rollback
- Detect and avoid race conditions between
useSWR
- Populate the cache of
useSWR
after mutation finishes - ...
More examples to come.
Breakings
Fetcher no longer accepts multiple arguments (#1864)
Previously, if the key
is an array, the values will be passed to the fetcher
function as arguments separately. In 2.0, the key
will always be passed to the fetcher
as is.
Before:
// SWR 1.x
useSWR([1, 2, 3], (a, b, c) => {
assert(a === 1)
assert(b === 2)
assert(c === 3)
})
After 2.0.0:
// SWR 2.0.0
useSWR([1, 2, 3], (a) => {
assert(a === [1, 2, 3])
})
Internal structure of the cached data (#1863)
This change affects the code that directly reads/writes to the cache, or provides a cache preset. For example if you have something like cache.set(key, value)
, you'll have to update your code.
Previously, the cached value of key
will be the associated data
, so this was guaranteed:
// SWR 1.x
assert(cache.get(key) === data)
And we keep other states (error
, isValidating
) with a special, prefixed key. Something like '$err$' + key
.
Since 2.0.0, the internal structure will be an object that holds all the current states:
// SWR 2.0.0
assert(cache.get(key) === { data, error, isValidating })
So you will have to do the following change to your code, get
:
- cache.get(key)
+ cache.get(key)?.data
And set
:
- cache.set(key, data)
+ cache.set(key, { ...cache.get(key), data })
What's Changed
- bugfix: make suspense and revalidateIfStale work together by @simowe in #1851
- feat: support functional optimisticData by @huozhi in #1861
- test: fix an act warning by @koba04 in #1888
- breaking: Change the fetcher argument to be consistent with the passed key by @shuding in #1864
- Keep all fields with one single key by @shuding in #1863
- fix: wrong spell by @baojie223 in #1902
- Update React 18 dependencies by @shuding in #1824
- build(deps): bump minimist from 1.2.5 to 1.2.6 by @dependabot in #1903
- type: make type inference simpler by @promer94 in #1908
- type: fix type error on SWRConfig by @Himself65 in #1913
- feat: Hook for remote mutations by @shuding in #1450
New Contributors
- @simowe made their first contribution in #1851
- @baojie223 made their first contribution in #1902
- @Himself65 made their first contribution in #1913
Full Changelog: 1.2.2...2.0.0-beta.0