Domitrius Clark
Advocate Engineer @ Cloudinary
@domitriusclark
/domitrius_anthony
OK FIRST
what is react-query and why use it?
react-query plainly, is a set of hooks that assist you in dealing with asynchronous data in whatever way you'd prefer
As long as your request returns a promise, react-query can make use of it.
useQuery | usePaginatedQuery | useInfiniteQuery
You're probably wondering what happens when feeding a request through react-query.
Let's begin by taking a look at an example of the useQuery hook.
const { data, status } = useQuery(
query.id && ['user', query.id],
async (key, id) => {
const user = await fetch(`/api/user/${id}`);
return user.json();
}
);
queryKey
async fetch function
useQuery's return vars
We'll start by talking about the queryKey argument. The queryKey is used to define the cache key that will hold onto your data. For example ['user', query.id] sets up our cache to attach to user.
Next is your async fetch function . You see here we're using a REST endpoint with our fetch function to get our response. You can also use things like axios or graphql-request . As was stated, anything that returns a Promise can be fed to the useQuery hooks.
async (key, id) => {
const user = await fetch(`/api/user/${id}`);
return user.json();
}
{data, status, error} — the variables we destructure from useQuery allow us ways to set up our UI for incoming data, loading status, and error's your request return.
Possible Returns
- data
- latestData
- error
- isFetching
- resolvedData
- refetch
- failureCount
The usePaginatedQuery and useInfiniteQuery hooks allow us to deal with fetching our data in chunks that return variables we're used to ie status & error , but also allow us to hook into other variables like resolvedData and isFetching which again help us prepare our UI for data updates and serving cached data from previous requests.
const {
status,
resolvedData,
latestData,
error,
isFetching
} = usePaginatedQuery(
['topAnimeList', page],
async (key, page) => {
const topAnime = await fetch(`https://api.jikan.moe/v3/top/anime/${page}`);
return topAnime.json();
}
);
Let's check out a quick example of how our user query can be done with graphql.
const GET_USER = `
query GetUser($id: ID!) {
getUser(id: $id) {
name
id
email
}
}
`;
const { data, status } = useQuery("user", id], async (key, id) => {
const user = await request(`https://yourendpoint/graphql`,GET_USER, { id })};
return user;
})
useMutation
We've seen how to deal with requesting our data. Now how do we handle manipulating our data with a POST, PUT, or DELETE.
const [createPost] = useMutation(
async ({ post }) => {
await fetch('/api/create/post', {
method: "POST",
body: JSON.stringify(post)
});
},
{
onSuccess: () => {
queryCache.refetchQueries('posts');
}
})
Here we are given our useMutation
function that fires off your useMutation hook.
useMutation's secondary object argument comes with some built in utilities:
Last, but most certainly not least, is the power of the queryCache.
function removeCharacterFromFavorites({ character }) {
queryCache.setQueryData('favoriteCharacters', prevData => {
return prevData.filter(data => data.id !== character.id)
});
}
function fetchFavoriteCharacters(key) {
return queryCache.getQueryData('favoriteCharacters');
}
The queryCache comes built in with a slew of different built in helpers, that allow you to lightly and forcefully make updates, fact check, and refresh your cache
THANK YA'LL FOR COMIN 😍