Comparison with other libs
Prefetching
xswr
user.fetch()
swr
mutate('/api/user', fetch('/api/user').then(res => res.json()))
react-query
await queryClient.prefetchQuery(['user'], fetchUser)
Optimistic updates
xswr
document.update(async function* (previous) { yield { data: "My optimistic document" } return await postAsJson("/api/edit", "My document")})
swr
mutate('/api/todos', updateFn(user), { optimisticData: user, rollbackOnError: true })
react-query
useMutation(updateTodo, { onMutate: async newTodo => { await queryClient.cancelQueries(['todos']) const previousTodos = queryClient.getQueryData(['todos']) queryClient.setQueryData(['todos'], old => [...old, newTodo]) return { previousTodos } }, onError: (err, newTodo, context) => { queryClient.setQueryData(['todos'], context.previousTodos) }, onSettled: () => { queryClient.invalidateQueries(['todos']) },})
Cancellation
xswr
user.aborter.abort()
swr
Unsupported.
react-query
queryClient.cancelQueries(['todos'])
Garbage collection
xswr
Global, per-query, and per-fetch expiration time. You can use response headers like Cache-Control
to set an expiration time.
swr
Unsupported.
react-query
Global and per-query expiration time. You can only define an expiration time at global scope or query scope.
Persistent storage
xswr
Per-query persistent storage. You can set a query as persistent in its schema. Out of the box support for IndexedDB and LocalStorage.
swr
Partial support. You have to create your own storage or install third party ones.
react-query
Global persistent storage. You persist your whole app and define excluded queries using shouldDehydrateQuery
. You have to install extra dependencies.
Store normalization
xswr
Very simple. Out of the box. No dependency needed.
swr
Unsupported.
react-query
Unsupported.
React Suspense
Super natural and easy. Doesn't enforce any pattern and doesn't require any configuration. Partially compatible with SSR.
function Component() { const { data, error, suspend } = useData() // Throw the error if (error) throw error // Fetch and suspend until next state change if (!data) throw suspend() return <div>{JSON.stringify(data)}</div>}
swr
Forces you to use an ErrorBoundary. No control over when to throw and when to suspend. Not compatible with SSR.
react-query
Seems simple at first but you have to use a configuration for it to work like you want. Error cleaning requires even more code. Compatibility with SSR? Unknown.