React Query and React Table are two incredibly dandy libraries to supplement React Development. React Query provides an opinionated way of approaching data synchronization and React Table makes the most annoying parts of modernizing HTML tables easy.

In this post, I’ll demonstrate one way you can combine the two of them together. This post assumes that you are already somewhat familiar with and , but in case you aren't, I'll go over some key ideas from both libraries first. Due to how complex React Query and React Table can be on their own, I highly recommend reading their starter docs first.

We will follow along with example code which can be found at You can set it up like so:

git clone
cd react-query-table-sandbox
npm install
npm start

We will mostly be focusing on the file. Let's get started.

React Query — Key Ideas

One of the main parts of React Query is the hook. In the component from , we have the following:

const {
data: apiResponse,
} = useQuery('discussionGroups', fetchData);

This can be broken down as follows:

  • is a key that we use to uniquely identify a query based on it's context. In this case it is an HTTP request to a REST API. This is necessary for distinguishing and isolating multiple queries that operate under a single QueryClient object and it's cache.
  • is a helper function which performs an API request and returns a promise. We can define this in whichever way is suitable, in this code we use .
  • is the response object that we receive from our API which we destructure and rename to
  • is a loading state variable that we can use to inform our UI

Essentially, using this hook lets us connect our API request logic (with some default re-fetching, caching and polling configurations built-in), retrieve our data and utilize helpful loading state variables to construct our UI in an easy to read and predictable fashion.

React Table — Key Ideas

One of the main parts of React Table is also a hook, and it is the hook. We memoize and feed table data into . The hook then returns a plethora of helpers that are responsible for enhancing our default HTML table. The enhancements allow us to easily render our table data as well as implement sorting, filtering, pagination, and much more. Let's look at the component from :

This may seem daunting at first, but after you understanding the flow of from React Table into our component, it's not that bad. It can be broken down as follows:

  • retrieves a set of props necessary for the table to utilize the libraries features
  • is similar to but for the tag
  • (which contains it's own and helper functions) is responsible for all library features around the and tags
  • are the individual rows to be rendered with similar helper methods associated with them
  • allows us to lazily prepare a row for rendering

In simpler terms, we use these helpers returned to us from the hook to inject all of the correct props into our tag and in doing so, can utilize all of React Table's incredible features.

Understanding Our Mock Data

In the example code, I prepared a mock api which returns data for an imaginary software dev discussion group website. The data is formatted like so:

Which should generate a table in our UI like so:

The interesting part about our mock API is that it is dynamic. Every time you send an api request to it sends an updated payload. This is meant to simulate a real world scenario where people are actively posting on discussion groups, opening new topics and resolving issues. This is also to help us see how React Query handles dynamic changes in our table without any additional configuration.

In our file, we define a function which sends requests to this API as follows:

const fetchData = () => axios.get(`http://localhost:8000/api`);

A Proposal For Structuring React Query with React Table

is structured into three main components:

  1. , which accesses the QueryClient from React Query and handles our data synchronization logic
  2. , which memoizes our table data and uses the hook from React Table
  3. , which takes all of the helpers provided to us by the hook, connects them with the necessary JSX (markup) and renders our final table.

This separation works in sequence:

-> handles query logic (React Query)
-> prepares table data as a prop
-> returns TableInstance

-> memoizes data
-> initiates table instance (React Table)
-> prepares table instance props
-> returns TableLayout

-> utilizes table instance helpers (passed as props)
-> injects props into elements
-> renders table

The TableQuery Component

First we connect to our using the hook. Then we declare a state variable and its associated setter using the hook. This sets the stage for us to work with our api retrieved table data later on. We then utilize the hook as explained earlier and followup with the following:

useEffect(() => {
}, [apiResponse])

This will set our with the appropriate API response once it has been retrieved within .

Since we also have access to the loading state variable, we can use that to determine what our component should render while we wait on our data. In this instance we just show on screen.

Now that we have populated our , we pass it as a prop into the next component in our sequence, the component.

The TableInstance Component

With access to our , we create and array-destructure two new variables called and . These are responsible for defining our table columns and how they access their associated data.

Columns can be formatted as a collection (or a nested collection) where we use as the label for a table header and to instruct React Table on which key to pick the correct value from out of the .

Our variable is also structured as a collection (array of objects) and it contains the raw table data as returned from our API.

We then use and to instantiate a with the hook:

const tableInstance = useTable({ columns, data });

This contains all of the helpers we need to beef up our boring old regular HTML table. It also contains our but formatted in a way that React Table can understand and work with. We then spread all of the properties of the as props into the component and move forward from there.

The component was actually one of the first things we explained in this post. As you can see, by breaking down our components into a , and , we can effectively prepare our table data for display.

The Result

As you can see, we have loading state, we have our data formatted exactly how we want, and React Query even re-fetches data when we leave the page and come back. I hope this tutorial has helped.

Happy Coding!



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Nafeu Nasir

Nafeu Nasir

is a musician and full-stack web developer from Toronto, Canada who studied Computer Science and Linguistics at the University of Toronto.