Introduce SWR v2 and SWRDevTools
SWR v2 has been released in Dec 2022, which includes many features and improvements like the following.
- New
useSWRMutation
hook - Mutate multiple items feature
- New
preload
API - New
isLoading
state - New
keepPreviousData
option - Improve Optimistic Updates support
- Improve React 18 support
- SWRDevTools
You can check these updates in the blog post. These features improve user experiences of your application and developer experiences of your team.
In this post, I’ll focus on some of the updates.
Mutate Multiple Items
I’d say this was the biggest missing feature for SWR v1.
The global mutate
API now accepts a filter function as its first argument.
This gives us flexibility for mutation scenarios. Let’s take a look at examples.
Revalidate all cache data for the same API endpoint with different query params
For example, you have an API /api/users/?sort={id, name, etc}
that returns users data, which accepts a sort key. When you have updated a user, you would want to revalidate all cache data for /api/users/
regardless of the sort key. The Mutate Multiple Items makes this possible.
import { mutate } from "swr";
const handleUpdateUser = async (user) => {
await updateUser(user);
// revalidate all cache data its key is start with /api/users
mutate(key => typeof key === "string" && key.startWith("/api/users/"));
// If you don't want to relivadate all keys and just want to invalidate the cache data,
mutate(
key => typeof key === "string" && key.startWith("/api/users/"),
undefined,
{ revalidate: false }
)
}
Revalidate the specific cache data of which keys are tagged arrays
SWR allows us to use an array as the key, which means you can add a tag into each key.
// ['user', 1]
// ['user', 2]
// ['item', 1]
We can update all cache data that have the same tag by the Mutate Multiple Items.
// Revalidate all cache data of which tag is "user"
mutate(key => Array.isArray(key) && key[0] === "user");
The filter function is applied to all cache keys, so you have to check the type of each cache key.
The Mutate Multiple Items gives us more flexible key management.
Clear all cache data
The Mutate Multiple Items can also use to clear all cache data.
const clearCache = () => mutate(
() => true,
undefined,
{ revalidate: false }
)
// ...clear cache on logout
clearCache()
You might wonder why we shouldn’t clear the cache data directly by accessing the cache object. Updating cache data directly might cause inconsistency in some scenarios like concurrent features or race conditions. So you should avoid it and use mutate
instead.
Documentation
I think documentation is crucial for libraries. Developers can’t find a feature or might use it the wrong way when it’s not well documented. In the v2 release, We’ve reorganized some documentation, like the Mutation page. I’ve also added a new “Understanding SWR” page so that developers can understand how SWR behaves.
This is from my past experience. When I started trying SWR, I was very confused about how to combine return values, which are data
, isValidating
, and error
. SWR v2 introduces more patterns with isLoading
and the keepPreviousData
option. I think developers get more confused with them. In order to help understand this, I’ve added the new page based on the diagrams Shu created.
Bundle Size and Optimization
As you can see, SWR v2 has many features, but the bundle size is smaller than v1! The reason is that we’ve updated the build target version from ES5 to ES2018, which drastically reduced the bundle size. It also brings performance improvements with SSR.
Middleware abstraction
This is about internal implementation, so you don’t have to care about that. But I wanted to pick up that because I was impressed the power of abstraction. SWR introduced Middleware in the v1 release, which enables us to extend SWR in user land. But this is also beneficial for SWR itself.
For example, useSWRMutation
, preload
are implemented as a middleware, so we separate these implementation from core implementation of SWR, which keeps core implementation small. I think it’s important for us to keep adding new features to SWR. useSWRInfinite
and useSWRImmutable
are also implemented as middleware. you can check it on the GitHub.
SWRDevTools
DevTools is a long standing issue for SWR, so I started implementing it because it seems to be fun 😁 I’m honored that SWRDevTools is a part of features of v2 release.
https://swr-devtools.vercel.app/
This is the my first browser extension, so I’ve learned a lot of thing like this.
- How to develop and debug a extension
- How to inject a script into a web page
- How to add a panel to the developer tools
- How to communicate between a webpage, a content script, a background script, and a devtool panel
- How to implement a browser extension that works on Chrome (MV3) and Firefox (MV2)
SWR v2 has a native support of SWRDevTools, so you don’t have to do any setup in your application. SWRDevTools has also support SWR v1. When you want to use SWRDevTools for SWR v1, you have to wrap your application into the SWRDevTools
component.
I’ve also build a demo on the webpage so that developers can try SWRDevTools without installing the extension. This is also implemented by using SWRDevTools
. This brings additional complexity into it, but that makes sense.
I hope SWRDevTools helps your development.
Thank you!
You can check other great features on the blog post and documentation!
I’ve learned a lot of things through working on the v2 release. All of the core member of SWR are great. Thank you for working with me!