The React Query library lets us make HTTP requests easily in our React apps.
In this article, we’ll look at how to make HTTP requests with React Query.
Paginated Queries
We can make paginated queries as we do with any other queries with the useQuery
hook.
For instance, we can write:
index.js
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { QueryClient, QueryClientProvider } from "react-query";
import App from "./App";
const queryClient = new QueryClient();
const rootElement = document.getElementById("root");
ReactDOM.render(
<QueryClientProvider client={queryClient}>
<StrictMode>
<App />
</StrictMode>
</QueryClientProvider>,
rootElement
);
App.js
import axios from "axios";
import React from "react";
import { useQuery } from "react-query";
export default function App() {
const [page, setPage] = React.useState(1);
const { data: { data: { data, totalPages } } = { data: [] } } = useQuery(
["todo", page],
({ queryKey: [, page] }) => {
return axios(
`https://api.instantwebtools.net/v1/passenger?page=${page}&size=10`
);
}
);
return (
<div>
<button onClick={(p) => setPage(Math.max(1, page - 1))}>prev</button>
<button onClick={(p) => setPage(Math.min(totalPages, page + 1))}>
next
</button>
<div>
{Array.isArray(data) &&
data.map((d, i) => <p key={`${i}-${d.name}`}>{d.name}</p>)}
</div>
</div>
);
}
We just create the page
state and pass it into the request to make a paginated query.
We’ll see that there’s a lot of flashing since every query is going to make as a new query.
To make the queries without the extra flashing, we set the keepPreviousData
option to true
:
App.js
import axios from "axios";
import React from "react";
import { useQuery } from "react-query";
export default function App() {
const [page, setPage] = React.useState(1);
const { data: { data: { data, totalPages } } = { data: [] } } = useQuery(
["todo", page],
({ queryKey: [, page] }) => {
return axios(
`https://api.instantwebtools.net/v1/passenger?page=${page}&size=10`
);
},
{
keepPreviousData: true
}
);
return (
<div>
<button onClick={(p) => setPage(Math.max(1, page - 1))}>prev</button>
<button onClick={(p) => setPage(Math.min(totalPages, page + 1))}>
next
</button>
<div>
{Array.isArray(data) &&
data.map((d, i) => <p key={`${i}-${d.name}`}>{d.name}</p>)}
</div>
</div>
);
}
Infinite Queries
We can also use React Query to make requests for infinite scrolling.
To do this, we use the useInfiniteQuery
hook.
This lets us display all the items that have been fetched so far.
For instance, we can write:
import axios from "axios";
import React from "react";
import { useInfiniteQuery } from "react-query";
export default function App() {
const [page, setPage] = React.useState(1);
const { data, fetchNextPage } = useInfiniteQuery(
"names",
({ pageParam = 1 }) => {
return axios(
`https://api.instantwebtools.net/v1/passenger?page=${pageParam}&size=10`
);
},
{
getNextPageParam: (lastPage) => {
const { totalPages } = lastPage.data;
return page < totalPages ? page + 1 : totalPages;
}
}
);
return (
<div>
<div>
{data &&
Array.isArray(data.pages) &&
data?.pages.map((group, i) => {
return group?.data?.data.map((d, i) => (
<p key={`${i}-${d.name}`}>{d.name}</p>
));
})}
</div>
<button
onClick={() => {
setPage(page + 1);
fetchNextPage();
}}
>
load more
</button>
</div>
);
}
We call the useInfiniteQuery
hook with the identifier for the request as the first argument.
The 2nd argument is the query function.
It takes an object with the pageParam
property as the parameter.
pageParam
is the return value of the getNextPageParam
function.
getNextPageParam
returns the next value of pageParam
.
Then in the JSX, we return the data.pages
array with the array of pages.
And we call map
to render the data with the data from the page.
The load more button calls fetchNextPage
to fetch the next page.
Conclusion
We can create paginated and requests for infinite scrolling with React Query.