- Resources Google Document: Click here
- Learn React Query with Web Dev Simplified: Click here
- Learn mutation
- Five Clever Hacks for React-Query and SWR: Click here by Jack Herrington
Date: 20 Aug, 2022, Souce: https://npmtrends.com/react-query
Date: 20 Aug, 2022, Souce: https://npmtrends.com/react-query
Try awsome React Query's way of doing it: Click here
{
staleTime: 3000, //default is 0. Setting it to 3000 will tell react query to keep it fresh for 3 secs.
//Also we can set staleTime to `Infinity` to query result will be fresh for life.
//When we provide `initialData` it will be considered `fresh` for the time specified as staleTime.
refetchOnWindowFocus: false, //default is true. Setting it false will tell react query to not refetch on window focus.
cacheTime: 3000, // default is Infinity(never garbage collect). cacheTime tells react query to garabage collected(i.e., completely delete) in when the component using that query is unmounted(i.e., query result is no longer in use).
//Also, set cacheTime to 0 if you want query result to dispose as soon query result becomes unused it gets removed immediately.
enabled: 'someCondition or some variable here, so query is only fetched when its truthy value',
//Also, setting `enabled` property to true (or atleast for once in past) will turn the queryInfo.isIdle flag to `true`.
//enabled: flag is very important as it enables us to use queryInfo.isIdle flag to let us detemine if the query is not in loading state but in idle state, and we may want to show different things in ui in each of those states.
retry: 1, // default is 3 times, i.e., if query fails it'll try 3 mroe times to fetch. Setting it to 1, will only try to fetch once more. You may set retry to `0` or `false` to tell react-query to not to retry at all.
retryDelay: 300, //Will set dealy time between retries.
initialData: 'someValueHere', // initialData will be used instead of query results, though it is stale by default so it'll be fetched from server on mount as well and will update the queryInfo.data .
// initialStale: false, //This option is _DEPRECATED_ in react-query-v3(now initialData is always stale), and instead we have almost similar option(already studied) i.e., `staleTime` for the initial time it would be considered FRESHH and no actual query will be made for that time period.
//const postsQuery = useQuery("posts", fetchPosts, {
onSuccess: (data) => {
increment();
},
onError: (error) => {
console.log(); //Or we can do someting getting error from the request.
},
onSettled: (data, error) => {
// if the reqeust was successful, error will be undefined.
// if the reqeust was failed, data will be undefined.
},
refetchInterval: 1000,//Sets the time after each that interval the query will refetch and will be reflected back in component, yikes!!
refetchIntervalInBackground: true,// default is false, so refetch will occur even if some other is opened currently.
});
}
- queryInfo.isLoading (initially true) is false after first fetching-request promise is fulfilled(i.e., either resolved or rejected).
Retry mutations in same order.
const Pokemon = () => {
const queryInfo = usePokemon();
log(queryInfo);
return queryInfo.isLoading ? (
'Loading...'
) : queryInfo.isError ? (
queryInfo.error.message
) : (
<div className="App">
{queryInfo.isFetching ? 'Updating...' : null}
<h1>Hello CodeSandbox</h1>
{queryInfo.data.map((r) => (
<div key={r.name}>{r.name}</div>
))}
</div>
);
};
Remember to place ReactQueryDevtools component under component tree of , so that devtools can access it.
import { ReactQueryDevtools, ReactQueryDevtoolsPanel } from "react-query/devtools";
<ReactQueryDevtools/> // This is beatiful embedded mode.
<ReactQueryDevtoolsPanel /> //This one is for embedded mode.
<ReactQueryDevtools position="bottom-right" />
From api:
position?: "top-left" | "top-right" | "bottom-left" | "bottom-right"
Defaults to bottom-left
(Query cancellation - vid 17 )Cancelling request via axios+react-query instead of using debounce(though using debounce is much cleaner option IMO )
- Always prefer - use-debounce @ npm/yarn - A very impressing hook ~ sahilrajput03.
Using axios
import axios, {CancelToken} from "axios";
const myAxiosRequest = () => {
const source = CancelToken.source()
const promise = new Promise(resolve => setTimeout(resolve, 1000))
.then(() => {
return axios.get(
`https://pokeapi.co/api/v2/pokemon/${pokemon}`,
{
cancelToken: source.token
}
)
})
.then(res => res.data)
promise.cancel = () => {
source.cancel('Query wass cancelled by React Query')
}
return promise
}
function PokemonSearch({pokemon}){
const queryInfo = useQuery(
['pokemon', pokemon], myAxiosRequest)
return ...
}
Using fetch
const myFetchRequest = () => {
const controller = new AbortController()
const signal = controller.signal
const promise = new Promise(resolve => setTimeout(resolve, 1000))
.then(() => {
return fetch(`https://pokeapi.co/api/v2/pokemon/${pokemon}`, {
method: 'get',
signal,
})
})
.then(res => res.json())
promise.cancel = () => {
controller.abort()
}
return promise
}
function PokemonSearch({pokeomn}){
const queryInfo = useQuery(
['pokemon', pokemon], myFetchRequest)
}
import {queryClient} from "./QueryClient";
//src: vid 28.
//****Also, we have used `staleTime: Infinity` for the "number" query so it'll not automatically refetch query on window refocus, but when we invalidate query with queryClient.invalidateQueries method, it's gonna refetch immediately. Yikes!!
<button
onClick={() => {
queryClient.invalidateQueries("number",{
refetchActive: false, //Default is true. Setting it false make it refetch only on window refocus or via refetch function only.
refetchInactive: true, //Default is false. Setting it to true will refetch the inactive queries too.
});
}}>
Invalidate number query
</button>
Quoting from docs :
If you do not want active queries to refetch, and simply be marked as invalid, you can use the refetchActive: false option.
src: Link.
import {queryClient} from "./QueryClient";
queryClient.prefetchQuery(['post', post.id], () => fetchPost(post.id), null, {force: true})
//Use above statement to prefetchQuery according to your usecase.
//Also, `force` option is truly optional as with force option, react-query will refetch fresh queries(for e.g., for Post Component => staleTime: 60 * 1000), otherwise it would not refetch fresh queries. Yikes!!
//
Put: PUT is a method of modifying resource where the client sends data that updates the entire resource.
Patch: Unlike PUT, PATCH applies a partial update to the resource.
Tanner linsley suggests to use 'queryClient.setQueryData' followed by 'queryClient.invalidateQuery' (vid 38)
Its bcoz, we must be sure that the data(partial data) we are manually settting for a query via setQueryData
method could be completely updated via the query request followed by invalidateQuery
method.
You may use either way of using queryClient in your app, i.e.,
import {queryClient} from './queryClient.js'
//Yup this works great!!
// or if you wanna follow the docs way.., then
import {useQueryClient} from './react-query'
const App = () => {
const queryClient = useQueryClient()
//Thought this is they way to use queryClient as mentioned in docs, but the former one works in equally decent way. Yikes!!
}
Src: [Link in docs](https://react-query.tanstack.com/guides/query-invalidation#query-matching-with-invalidatequeries)
### Using axios's params option
```js
const fetchPosts = () => {
axios.get('/api/posts', {
params: {
pageSize: 10,
pageOffset: page,
}
})
}
The new keepPreviousData options is available for both useQuery and useInfiniteQuery and will have the same "lagging" effect on your data:
import { useQuery } from 'react-query'
function Page({ page }) {
const { data } = useQuery(['page', page], fetchPage, {
keepPreviousData: true,
})
}
queryInfo.resolvedData and queryInfo.latestData are deprecated, there's no such things in latest version of react-query, but queryInfo.data
.
The content of vid 45 is mostly(80%) deprecated, so instead review only the tutorial's code in reactProjects/learning-react-query folder only. Also, see the amazing docs exaplaining other great things about infinite query api here.