Exploring the use case for SWR and if i can use it as a replacement for Redux
tl;dr:
error
, loading
, success
state and write reducers for them. SWR gives you these out of the boxmutate
function to update SWR cacheIts cache is a global state object, keys are things in the state, useSWR calls and dependent fetching are selectors. Not sure about the local app state part though that would probably need to be in a separate context. @rauchg is smarter than me so he might have a better idea!
— Giuseppe (@giuseppegurgone) October 31, 2019
Basic mentality behind SWR is that remote data is not state, it belongs in a cache.
“Remote data is read-only. It doesn’t belong in the same location as our UI state.”
If you don’t keep server side data in state (making a client side copy), it won’t become stale.
Server cache | Local (UI) state |
---|---|
State that’s actually stored on the server and we store in the client for quick-access | State that’s only useful in the UI for controlling the interactive parts of our app |
Conversations, User profiles, Blog posts | Is the modal open? Is the box checked? |
SWR is great if we’re using GraphQL, because then you are not making multiple HTTP calls every time you need data, so all the revalidating is less expensive. But if you’re using plain old REST APIs with lots of HTTP requests, i wonder how much bandwidth it’ll consume and if we can afford making so many calls so frequently?
The key you pass to useSWR
helps SWR identify our request. If the key is the same for multiple requests, only one API call will be made and all components will get the results.
all components fetching the same data are updated when the data changes.
You can use onSuccess
callback on useSWR
to dispatch redux actions..
SWR is using an in-memory Map for the cache (both React and React Native). It does not save cache with AsyncStorage or MemoryStore in React Native. Right now it clears everything on hard refresh. According to folks from Vercel, LocalStorage is IO heavy and slowed down rendering. ANd IndexedDb is async, which means SWR can not return data from cache synchronously.
With Redux, persisting is simple, you use redux-persist. A similar ready made solution for SWR doesn’t exist yet. There is swr-sync-storage from a guy who used to work at Vercel, and it’ll sync SWR cache with localStorage
or sessionStorage
to get offline cache. But it’s for web and not React Native.
There is this solution that derindutz is using in production. You can switch out localforage
for whichever caching mechanism you want.
tl;d: you can do it, but it’ll save the entire cache and is not performant as disk IO is heavy.
We did an extensive experiment with IndexedDB and it was awful from a product perspective. Disks are slow and customers tend to want strong reads from the kind of apps and dashboards that you use SWR for. - Vercel CEO
As of now, i can’t use SWR in React Native apps because a solution to persist it by synching it to AsyncStorage
(HDD/Disk) doesn’t exist (yet). So the in-memory (RAM) cache will be gone every time i exit the app. If i exit the app and the next time i open it and i’m offline, the cache will be blank and i won’t have any data to make the app usable offline.
I can use it in React on the web, and i can persist it to Web localStorage
or sessionStorage
.
My ideal scenario is using SWR on the web with GraphQL API and persisting it to web storage for offline access.