Introduction
When I first heard of SWR, I didn't fully grasp all the concepts. The thought of having all the frustrations that I've had when dealing with global state as well as api calls just disappearing seemed impossible. Using additional tooling for debugging global state, trying to figure out the best way to handle actions and reducers and action types, all the overhead of creating new components and linking to the global state store, having to make api calls in parent components and pass data down to the children. All of these frustrations are completely gone now, by this single library that Vercel created, called SWR.
What is SWR?
SWR is a React hooks library that supercharges your application and eliminates the need for global state (in most cases). "SWR" is derived from an HTTP cache invalidation strategy HTTP RFC 5861, which means to return the cached "stale" data first, then send a fetch request to "revalidate" the data, and finally update the cache accordingly. What does this mean for your applications using this library? Well I couldn't have said it any better than what is said in the official documentation.
With SWR, components will get a stream of data updates constantly and automatically. And the UI will be always fast and reactive.
By using SWR, your application will always have data up to date and will always have a very fast perceived performance.
What are the features?
A quick disclaimer, I'm only going to cover a couple of the features, as there is way too much for me to cover in the scope of this article.
Built-in cache AND request deduplication
This is in my opinion, the most important of all the features and is the bread and butter of SWR. Requests made by SWR are automatically cached based on the key used (usually the url). This is really great if you are switching between pages and have components unmounting and mounting. SWR will serve the cached data automatically first, before trying to make a request for new fresh data. Now the caching is great, but SWR doesn't just stop there. It also has built in request deduplication, so if you have multiple SWR hooks making requests to the same endpoint within multiple components on the same page, that request will only actually be made one single time, and ALL instances will receive the fetched data at the same time. Let's check out an example and see what this looks like.
import React from 'react';
import useSWR from 'swr';
const dataFetcher = url => fetch(url).then(res => res.json());
const useProfile = () => {
const { data, error } = useSWR('/user', dataFetcher);
return {
profile: data,
error: error,
isLoading: !data && !error
};
};
const Name = () => {
const { profile } = useProfile();
return <p>{ profile.firstName } { profile.lastName }</p>;
};
const Avatar = () => {
const { profile } = useProfile();
return <img src={profile.avatar} />;
};
const Profile = () => (
<div>
<Avatar />
<Name />
</div>
);
You're probably thinking to yourself "Wait, you're using the same hook in two different components! Won't this make 2 separate api calls?!". This was the first thought that I had too, but there is a lot of magic that SWR is doing behind the scenes, and if you were to test out this example and view your network tab, you'd see the call is only ever made one time. Not only this awesome, but it opens up so many opportunities for getting rid of prop drilling and global state. Now I could stop here, and I bet most of you would be happy with just these features, but SWR doesn't just stop there, it still has a couple more amazing features I'd love to touch on.
Data Revalidation
The final feature of SWR that I'm going to cover, is data re validation. Out of the box, it will do this on it's own, but you can disable it if you don't want it or don't need it. If your web page loses focus (like changing tabs, or minimizing your web browser), and then comes back in to focus, SWR will automatically trigger a request for new data to "re validate" your data and make sure it's cached data is up to date. It also has several other ways of handling this that are also optional such as polling based on an interval, or when the device using your application loses internet connectivity and then reconnects. This plays a huge role in keeping your application feeling fast and responsive, and always keeping user data up to date even when they come back at a later time.
Outro
As you can see, SWR has many amazing features that can be used to start removing global state from your application. This doesn't mean you have to get rid of global state, or even fully eliminate it, as SWR and Redux, or Mobx, or any other global state library can live harmoniously together, but I'd encourage you to look in to SWR and consider embracing it in your next project, or even replacing parts of your current application. I don't think you'll regret it, and if you dreaded dealing with shared state before, you may just start loving it again.