PageSourceSearch

https://nafeu.com/2021-03-01/using-react-query-with-react-table/

html nafeu.com collected 2026-10-03 23:20:12 UTC 33,444 bytes, 487 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4  <meta charset="utf-8">
5  <meta name="description" content="Personal blog and portfolio site of Nafeu Nasir.">
6  <meta name="keywords" content="Blog,Profile,Portfolio,Nafeu,Nasir,Developer,Toronto">
7  <meta name="author" content="Nafeu Nasir">
8  <meta http-equiv="X-UA-Compatible" content="IE=edge">
9  <meta name="viewport" content="width=device-width, initial-scale=1">
10  <meta property="og:url" content="http://nafeu.com" />
11  <meta property="og:type" content="website" />
12  <meta property="og:title" content="Nafeu Nasir | Blog & Portfolio" />
13  <meta property="og:description" content="Personal blog and portfolio site of Nafeu Nasir." />
14  <meta property="og:image" content="/images/circle-headshot.png" />
15  <title>Using React Query with React Table</title>
16
17  <!-- CSS -->
18  <link rel="stylesheet" href="/assets/css/main.css" type="text/css">
19
20  <!-- Font -->
21  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
22  <!-- <link href='//spoqa.github.io/spoqa-han-sans/css/SpoqaHanSans-kr.css' rel='stylesheet' type='text/css'> -->
23  <link href="https://fonts.googleapis.com/css?family=Ubuntu+Mono" rel="stylesheet">
24  <link href="https://fonts.googleapis.com/css?family=Titillium+Web:200,300,400,700" rel="stylesheet">
25
26  <link rel="alternate" type="application/rss+xml" title="RSS Feed for Nafeu Nasir" href="/feed.xml" />
27
28  <link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon.png">
29  <!-- Begin Jekyll SEO tag v2.8.0 -->
30<title>Using React Query with React Table | Nafeu Nasir</title>
31<meta name="generator" content="Jekyll v3.9.5" />
32<meta property="og:title" content="Using React Query with React Table" />
33<meta property="og:locale" content="en_US" />
34<meta name="description" content="An example on combining react-query with react-table" />
35<meta property="og:description" content="An example on combining react-query with react-table" />
36<link rel="canonical" href="https://nafeu.github.io/2021-03-01/using-react-query-with-react-table/" />
37<meta property="og:url" content="https://nafeu.github.io/2021-03-01/using-react-query-with-react-table/" />
38<meta property="og:site_name" content="Nafeu Nasir" />
39<meta property="og:type" content="article" />
40<meta property="article:published_time" content="2021-03-01T00:00:00-05:00" />
41<meta name="twitter:card" content="summary" />
42<meta property="twitter:title" content="Using React Query with React Table" />
43<script type="application/ld+json">
44{"@context":"https://schema.org","@type":"BlogPosting","dateModified":"2021-03-01T00:00:00-05:00","datePublished":"2021-03-01T00:00:00-05:00","description":"An example on combining react-query with react-table","headline":"Using React Query with React Table","mainEntityOfPage":{"@type":"WebPage","@id":"https://nafeu.github.io/2021-03-01/using-react-query-with-react-table/"},"url":"https://nafeu.github.io/2021-03-01/using-react-query-with-react-table/"}</script>
44
45<!-- End Jekyll SEO tag -->
46
47
48
49  <!-- Google Analytics -->
50
51<script>
52(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
53  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
54  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
55})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
56
57ga('create', '', 'auto');
58ga('send', 'pageview');
59
60</script>
60
61
62
63
64</head>
65
66<body>
67  <div class="content-container">
68    <header>
69  <div class="header-small">
70    <a class="nav-item" href="https://nafeu.github.io">BLOG</a>
71    <a class="nav-item" href="https://nafeu.github.io/about#dev">DEV</a>
72    <a class="nav-item" href="https://nafeu.github.io/about#projects">PROJECTS</a>
73    <a class="nav-item" href="https://nafeu.github.io/about#music">MUSIC</a>
74    <a class="nav-item" href="https://nafeu.github.io/about#contact">CONTACT</a>
75  </div>
76</header>
77<div class="post">
78  <div class="post-title">Using React Query with React Table</div>
79  <span class="post-author">by Nafeu Nasir</span>
80  <span class="post-date">
81    <time>01 Mar 2021</time>
82  </span>
83  <div class="post-tag">
84    <ul>
85      
86      <li>
87        <a href="https://nafeu.github.io/tags#coding">
88          <span>coding</span>
89        </a>
90      </li>
91      
92      
93      <li>
94        <a href="https://nafeu.github.io/tags#dev">
95          <span>dev</span>
96        </a>
97      </li>
98      
99      
100      <li>
101        <a href="https://nafeu.github.io/tags#react-table">
102          <span>react-table</span>
103        </a>
104      </li>
105      
106      
107      <li>
108        <a href="https://nafeu.github.io/tags#react-query">
109          <span>react-query</span>
110        </a>
111      </li>
112      
113      
114    </ul>
115  </div>
116
117  <p><img src="https://res.cloudinary.com/dvivnklwq/image/upload/v1614619166/it1t4ibg1a4bciz7pnik.png" alt="" /></p>
118
119<p><a href="https://react-query.tanstack.com/">React Query</a> and <a href="https://react-table.tanstack.com/">React Table</a> are two incredibly dandy libraries to supplement React Development. React Query provides an appropriately opinionated way of approaching data synchronization and React Table makes the most annoying parts of modernizing HTML tables easy.</p>
120
121<p>In this post, I’ll demonstrate one way to combine the two of them together. This post assumes that you are already somewhat familiar with <code class="language-plaintext highlighter-rouge">react-query</code> and <code class="language-plaintext highlighter-rouge">react-table</code>, 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.</p>
122
123<p>We will follow along with example code which can be found at <a href="https://github.com/nafeu/react-query-table-sandbox">github.com/nafeu/react-query-table-sandbox</a>. You can set it up like so:</p>
124
125<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone https://github.com/nafeu/react-query-table-sandbox.git
126<span class="nb">cd </span>react-query-table-sandbox
127npm <span class="nb">install
128</span>npm start
129</code></pre></div></div>
130
131<p>We will mostly be focusing on the <code class="language-plaintext highlighter-rouge">ReactQueryWithTable.jsx</code> file. Let’s get started.</p>
132
133<h3 id="react-query---key-ideas">React Query - Key Ideas</h3>
134
135<p>One of the main parts of React Query is the <code class="language-plaintext highlighter-rouge">useQuery</code> hook. In the <code class="language-plaintext highlighter-rouge">TableQuery</code> component from <code class="language-plaintext highlighter-rouge">ReactQueryWithTable.jsx</code>, we have the following:</p>
136
137<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="p">{</span>
138  <span class="na">data</span><span class="p">:</span> <span class="nx">apiResponse</span><span class="p">,</span>
139  <span class="nx">isLoading</span>
140<span class="p">}</span> <span class="o">=</span> <span class="nx">useQuery</span><span class="p">(</span><span class="dl">'</span><span class="s1">discussionGroups</span><span class="dl">'</span><span class="p">,</span> <span class="nx">fetchData</span><span class="p">);</span>
141</code></pre></div></div>
142
143<p>This can be broken down as follows:</p>
144<ul>
145  <li><code class="language-plaintext highlighter-rouge">discussionGroups</code> is a <strong>key</strong> 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 <a href="https://react-query.tanstack.com/reference/QueryClient">QueryClient</a> object and it’s cache.</li>
146  <li><code class="language-plaintext highlighter-rouge">fetchData</code> 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 <a href="https://www.npmjs.com/package/axios"><code class="language-plaintext highlighter-rouge">axios</code></a>.</li>
147  <li><code class="language-plaintext highlighter-rouge">data</code> is the response object that we receive from our API which we destructure and rename to <code class="language-plaintext highlighter-rouge">apiResponse</code></li>
148  <li><code class="language-plaintext highlighter-rouge">isLoading</code> is a loading state variable that we can use to inform our UI</li>
149</ul>
150
151<p>
151Essentially, 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.</p>
152
153<h3 id="react-table---key-ideas">React Table - Key Ideas</h3>
154
155<p>One of the main parts of React Table is also a hook, and it is the <code class="language-plaintext highlighter-rouge">useTable</code> hook. We <a href="https://reactjs.org/docs/hooks-reference.html#usememo"><strong>memoize</strong></a> and feed table data into <code class="language-plaintext highlighter-rouge">useTable</code>. 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 <code class="language-plaintext highlighter-rouge">TableLayout</code> component from <code class="language-plaintext highlighter-rouge">ReactQueryWithTable.jsx</code>:</p>
156
157<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">TableLayout</span> <span class="o">=</span> <span class="p">({</span>
158  <span class="nx">getTableProps</span><span class="p">,</span>
159  <span class="nx">getTableBodyProps</span><span class="p">,</span>
160  <span class="nx">headerGroups</span><span class="p">,</span>
161  <span class="nx">rows</span><span class="p">,</span>
162  <span class="nx">prepareRow</span><span class="p">,</span>
163<span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
164  <span class="k">return</span> <span class="p">(</span>
165    <span class="o">&lt;</span><span class="nx">table</span> <span class="p">{...</span><span class="nx">getTableProps</span><span class="p">()}</span><span class="o">&gt;</span>
166      <span class="o">&lt;</span><span class="nx">thead</span><span class="o">&gt;</span>
167        <span class="p">{</span><span class="nx">headerGroups</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">headerGroup</span> <span class="o">=&gt;</span> <span class="p">(</span>
168          <span class="o">&lt;</span><span class="nx">tr</span> <span class="p">{...</span><span class="nx">headerGroup</span><span class="p">.</span><span class="nx">getHeaderGroupProps</span><span class="p">()}</span><span class="o">&gt;</span>
169            <span class="p">{</span><span class="nx">headerGroup</span><span class="p">.</span><span class="nx">headers</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">column</span> <span class="o">=&gt;</span> <span class="p">(</span>
170              <span class="o">&lt;</span><span class="nx">th</span> <span class="p">{...</span><span class="nx">column</span><span class="p">.</span><span class="nx">getHeaderProps</span><span class="p">()}</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">column</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">Header</span><span class="dl">'</span><span class="p">)}</span><span class="o">&lt;</span><span class="sr">/th</span><span class="err">&gt;
171</span>            <span class="p">))}</span>
172          <span class="o">&lt;</span><span class="sr">/tr</span><span class="err">&gt;
173</span>        <span class="p">))}</span>
174      <span class="o">&lt;</span><span class="sr">/thead</span><span class="err">&gt;
175</span>      <span class="o">&lt;</span><span class="nx">tbody</span> <span class="p">{...</span><span class="nx">getTableBodyProps</span><span class="p">()}</span><span class="o">&gt;</span>
176        <span class="p">{</span><span class="nx">rows</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">row</span><span class="p">,</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
177          <span class="nx">prepareRow</span><span class="p">(</span><span class="nx">row</span><span class="p">)</span>
178          <span class="k">return</span> <span class="p">(</span>
179            <span class="o">&lt;</span><span class="nx">tr</span> <span class="p">{...</span><span class="nx">row</span><span class="p">.</span><span class="nx">getRowProps</span><span class="p">()}</span><span class="o">&gt;</span>
180              <span class="p">{</span><span class="nx">row</span><span class="p">.</span><span class="nx">cells</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="nx">cell</span> <span class="o">=&gt;</span> <span class="p">{</span>
181                <span class="k">return</span> <span class="o">&lt;</span><span class="nx">td</span> <span class="p">{...</span><span class="nx">cell</span><span class="p">.</span><span class="nx">getCellProps</span><span class="p">()}</span><span class="o">&gt;</span><span class="p">{</span><span class="nx">cell</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="dl">'</span><span class="s1">Cell</span><span class="dl">'</span><span class="p">)}</span><span class="o">&lt;</span><span class="sr">/td</span><span class="err">&gt;
182</span>              <span class="p">})}</span>
183            <span class="o">&lt;</span><span class="sr">/tr</span><span class="err">&gt;
184</span>          <span class="p">)</span>
185        <span class="p">})}</span>
186      <span class="o">&lt;</span><span class="sr">/tbody</span><span class="err">&gt;
187</span>    <span class="o">&lt;</span><span class="sr">/table</span><span class="err">&gt;
188</span>  <span class="p">);</span>
189<span class="p">}</span>
190</code></pre></div></div>
191
192<p>This may seem daunting at first, but after you understanding the flow of <code class="language-plaintext highlighter-rouge">props</code> from React Table into our component, it’s not that bad. It can be broken down as follows:</p>
193<ul>
194  <li><code class="language-plaintext highlighter-rouge">getTableProps</code> retrieves a set of props necessary for the table to utilize the libraries features</li>
195  <li><code class="language-plaintext highlighter-rouge">getTableBodyProps</code> is similar to <code class="language-plaintext highlighter-rouge">getTableProps</code> but for the <code class="language-plaintext highlighter-rouge">tbody</code> tag</li>
196  <li><code class="language-plaintext highlighter-rouge">headerGroups</code> (which contains it’s own <code class="language-plaintext highlighter-rouge">getHeaderGroupProps</code> and <code class="language-plaintext highlighter-rouge">getHeaderProps</code> helper functions) is responsible for all library features around the <code class="language-plaintext highlighter-rouge">thead</code> and <code class="language-plaintext highlighter-rouge">tr</code> tags</li>
197  <li><code class="language-plaintext highlighter-rouge">rows</code> are the individual rows to be rendered with similar helper methods associated with them</li>
198  <li><code class="language-plaintext highlighter-rouge">prepareRow</code> allows us to lazily prepare a row for rendering</li>
199</ul>
200
201<p>In simpler terms, we use these helpers returned to us from the <code class="language-plaintext highlighter-rouge">useTable</code> hook to inject all of the correct props into our <code class="language-plaintext highlighter-rouge">&lt;table&gt;</code> tag and in doing so, can utilize all of React Table’s incredible features.</p>
202
203<h3 id="understanding-our-mock-data">Understanding Our Mock Data</h3>
204
205<p>In the <a href="https://github.com/nafeu/react-query-table-sandbox/blob/main/index.mjs">example code</a>, I prepared a <strong>mock api</strong> which returns data for an imaginary <strong>software dev discussion group</strong> website. The data is formatted like so:</p>
206
207<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[
208  {
209    "id": 1,
210    "name": "How to use react-table in reporting dashboard",
211    "active": 40,
212    "status": "locked",
213    "upvotes": 30
214  },
215  {
216    "id": 2,
217    "name": "How to use react-query for BI solution",
218    "active": 31,
219    "status": "resolved",
220    "upvotes": 39
221  }
222  ...
223]
224</code></pre></div></div>
225
226<p>Which should generate a table in our UI like so:</p>
227
228<table>
229  <thead>
230    <tr>
231      <th>Topic</th>
232      <th>Active Members</th>
233      <th>Status</th>
234      <th>Upvotes</th>
235    </tr>
236  </thead>
237  <tbody>
238    <tr>
239      <td>How to use react-table in reporting dashboard</td>
240      <td>40</td>
241      <td>locked</td>
242      <td>30</td>
243    </tr>
244    <tr>
245      <td>How to use react-query for BI solution</td>
246      <td>31</td>
247      <td>resolved</td>
248      <td>39</td>
249    </tr>
250    <tr>
251      <td>…</td>
252      <td>…</td>
253      <td>…</td>
254      <td>…</td>
255    </tr>
256  </tbody>
257</table>
258
259<p>The interesting part about our mock API is that it is dynamic. Every time you send an api request to <code class="language-plaintext highlighter-rouge">localhost:8000/api</code> it sends an updated payload. This is meant to simulate a real world scenario where people are actively posting on discu
259ssion 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.</p>
260
261<p>In our <code class="language-plaintext highlighter-rouge">ReactQueryWithTable.jsx</code> file, we define a function <code class="language-plaintext highlighter-rouge">fetchData</code> which sends requests to this API as follows:</p>
262
263<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">fetchData</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">axios</span><span class="p">.</span><span class="kd">get</span><span class="p">(</span><span class="s2">`http://localhost:8000/api`</span><span class="p">);</span>
264</code></pre></div></div>
265
266<h3 id="a-proposal-for-structuring-react-query-with-react-table">A Proposal For Structuring React Query with React Table</h3>
267
268<p><code class="language-plaintext highlighter-rouge">ReactQueryWithTable.jsx</code> is structured into three main components:</p>
269
270<ol>
271  <li><code class="language-plaintext highlighter-rouge">TableQuery</code>, which accesses the QueryClient from React Query and handles our data synchronization logic</li>
272  <li><code class="language-plaintext highlighter-rouge">TableInstance</code>, which memoizes our table data and uses the <code class="language-plaintext highlighter-rouge">useTable</code> hook from React Table</li>
273  <li><code class="language-plaintext highlighter-rouge">TableLayout</code>, which takes all of the helpers provided to us by the <code class="language-plaintext highlighter-rouge">useTable</code> hook, connects them with the necessary JSX (markup) and renders our final table.</li>
274</ol>
275
276<p>This separation works in sequence:</p>
277
278<pre><code class="language-txt">TableQuery
279  -&gt; handles query logic (React Query)
280  -&gt; prepares table data as a prop
281  -&gt; returns TableInstance
282
283TableInstance
284  -&gt; memoizes data
285  -&gt; initiates table instance (React Table)
286  -&gt; prepares table instance props
287  -&gt; returns TableLayout
288
289TableLayout
290  -&gt; utilizes table instance helpers (passed as props)
291  -&gt; injects props into elements
292  -&gt; renders table
293</code></pre>
294
295<h4 id="the-tablequery-component">The TableQuery Component</h4>
296
297<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">TableQuery</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
298  <span class="kd">const</span> <span class="nx">queryClient</span> <span class="o">=</span> <span class="nx">useQueryClient</span><span class="p">();</span>
299
300  <span class="kd">const</span> <span class="p">[</span><span class="nx">tableData</span><span class="p">,</span> <span class="nx">setTableData</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
301
302  <span class="kd">const</span> <span class="p">{</span> <span class="na">data</span><span class="p">:</span> <span class="nx">apiResponse</span><span class="p">,</span> <span class="nx">isLoading</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">useQuery</span><span class="p">(</span><span class="dl">'</span><span class="s1">discussionGroups</span><span class="dl">'</span><span class="p">,</span> <span class="nx">fetchData</span><span class="p">);</span>
303
304  <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
305    <span class="nx">setTableData</span><span class="p">(</span><span class="nx">apiResponse</span><span class="p">?.</span><span class="nx">data</span><span class="p">);</span>
306  <span class="p">},</span> <span class="p">[</span><span class="nx">apiResponse</span><span class="p">])</span>
307
308  <span class="k">if</span> <span class="p">(</span><span class="nx">isLoading</span> <span class="o">||</span> <span class="o">!</span><span class="nx">tableData</span><span class="p">)</span> <span class="p">{</span>
309    <span class="k">return</span> <span class="o">&lt;</span><span class="nx">div</span><span class="o">&gt;</span><span class="nx">Loading</span><span class="p">...</span><span class="o">&lt;</span><span class="sr">/div</span><span class="err">&gt;
310</span>  <span class="p">}</span>
311
312  <span class="k">return</span> <span class="p">(</span>
313    <span class="o">&lt;</span><span class="nx">TableInstance</span> <span class="nx">tableData</span><span class="o">=</span><span class="p">{</span><span class="nx">tableData</span><span class="p">}</span><span class="sr">/</span><span class="err">&gt;
314</span>  <span class="p">);</span>
315<span class="p">}</span>
316</code></pre></div></div>
317
318<p>First we connect to our <code class="language-plaintext highlighter-rouge">queryClient</code> using the <code class="language-plaintext highlighter-rouge">useQueryClient</code>
318 hook. Then we declare a state variable <code class="language-plaintext highlighter-rouge">tableData</code> and its associated setter using the <code class="language-plaintext highlighter-rouge">useState</code> hook. This sets the stage for us to work with our api retrieved table data later on. We then utilize the <code class="language-plaintext highlighter-rouge">useQuery</code> hook as explained earlier and followup with the following:</p>
319
320<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span>
321  <span class="nx">setTableData</span><span class="p">(</span><span class="nx">apiResponse</span><span class="p">?.</span><span class="nx">data</span><span class="p">);</span>
322<span class="p">},</span> <span class="p">[</span><span class="nx">apiResponse</span><span class="p">])</span>
323</code></pre></div></div>
324
325<p>This will set our <code class="language-plaintext highlighter-rouge">tableData</code> with the appropriate API response once it has been retrieved within <code class="language-plaintext highlighter-rouge">useQuery</code>.</p>
326
327<p>Since we also have access to the <code class="language-plaintext highlighter-rouge">isLoading</code> 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 <code class="language-plaintext highlighter-rouge">Loading...</code> on screen.</p>
328
329<p>Now that we have populated our <code class="language-plaintext highlighter-rouge">tableData</code>, we pass it as a prop into the next component in our sequence, the <code class="language-plaintext highlighter-rouge">TableInstance</code> component.</p>
330
331<h4 id="the-tableinstance-component">The TableInstance Component</h4>
332
333<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">TableInstance</span> <span class="o">=</span> <span class="p">({</span> <span class="nx">tableData</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="p">{</span>
334  <span class="kd">const</span> <span class="p">[</span><span class="nx">columns</span><span class="p">,</span> <span class="nx">data</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useMemo</span><span class="p">(</span>
335    <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
336      <span class="kd">const</span> <span class="nx">columns</span> <span class="o">=</span> <span class="p">[</span>
337        <span class="p">{</span>
338          <span class="na">Header</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Topic</span><span class="dl">'</span><span class="p">,</span>
339          <span class="na">accessor</span><span class="p">:</span> <span class="dl">'</span><span class="s1">name</span><span class="dl">'</span>
340        <span class="p">},</span>
341        <span class="p">{</span>
342          <span class="na">Header</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Active Members</span><span class="dl">'</span><span class="p">,</span>
343          <span class="na">accessor</span><span class="p">:</span> <span class="dl">'</span><span class="s1">active</span><span class="dl">'</span>
344        <span class="p">},</span>
345        <span class="p">{</span>
346          <span class="na">Header</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Status</span><span class="dl">'</span><span class="p">,</span>
347          <span class="na">accessor</span><span class="p">:</span> <span class="dl">'</span><span class="s1">status</span><span class="dl">'</span>
348        <span class="p">},</span>
349        <span class="p">{</span>
350          <span class="na">Header</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Upvotes</span><span class="dl">'</span><span class="p">,</span>
351          <span class="na">accessor</span><span class="p">:</span> <span class="dl">'</span><span class="s1">upvotes</span><span class="dl">'</span>
352        <span class="p">}</span>
353      <span class="p">];</span>
354      <span class="k">return</span> <span class="p">[</span><span class="nx">columns</span><span class="p">,</span> <span class="nx">tableData</span><span class="p">];</span>
355    <span class="p">},</span>
356    <span class="p">[</span><span class="nx">tableData</span><span class="p">]</span>
357  <span class="p">);</span>
358
359  <span class="kd">const</span> <span class="nx">tableInstance</span> <span class="o">=</span> <span class="nx">useTable</span><span class="p">({</span> <span class="nx">columns</span><span class="p">,</span> <span class="nx">data</span> <span class="p">});</span>
360
361  <span class="k">return</span> <span class="p">(</span>
362    <span class="o">&lt;</span><span class="nx">TableLayout</span> <span class="p">{...</span><span class="nx">tableInstance</span><span class="p">}</span> <span class="sr">/</span><span class="err">&gt;
363</span>  <span class="p">);</span>
364<span class="p">}</span>
365</code></pre></div></div>
366
367<p>With access to our <code class="language-plaintext highlighter-rouge">tableData</code>, we create and array-destructure two new variables called <code class="language-plaintext highlighter-rouge">columns</code> and <code class="language-plaintext highlighter-rouge">data</code>. These are responsible for defining our table columns and how they access their associated data.</p>
368
369<p>Columns can be formatted as a collection (or a nested collection) where we use <code class="language-plaintext highlighter-rouge">Header</code> as the label for a table header and <code class="language-plaintext highlighter-rouge">accessor</code> to instruct React Table on which key to pick the correct value from out of the <code class="language-plaintext highlighter-rouge">data</code>.</p>
370
371<p>Our <code class="language-plaintext highlighter-rouge">data</code> variable is also structured as a collection (array of objects) and it contains the raw table data as returned from our API.</p>
372
373<p>We then use <code class="language-plaintext highlighter-rouge">columns</code> and <code class="language-plaintext highlighter-rouge">data</code> to instantiate a <code class="language-plaintext highlighter-rouge">tableInstance</code> with the <code class="language-plaintext highlighter-rouge">useTable</code> hook:</p>
374
375<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">tableInstance</span> <span class="o">=</span> <span class="nx">useTable</span><span class="p">({</span> <span class="nx">columns</span><span class="p">,</span> <span class="nx">data</span> <span class="p">});</span>
376</code></pre></div></div>
377
378<p>This contains all of the helpers we need to beef up our boring old <em>regular</em> HTML table. It also contains our <code class="language-plaintext highlighter-rouge">tableData</code> but formatted in a way that React Table can understand and work with. We then spread all of the properties of the <code class="language-plaintext highlighter-rouge">tableInstance</code> as props into the <code class="language-plaintext highlighter-rouge">TableLayout</code> component and move forward from there.</p>
379
380<p>The <code class="language-plaintext highlighter-rouge">TableLayout</code> component was actually one of the first things we explained in this post. As you can see, by breaking down our components into a <code class="language-plaintext highlighter-rouge">query layer</code>, <code class="language-plaintext highlighter-rouge">data processing layer</code> and <code class="language-plaintext highlighter-rouge">render layer</code>, we can effectively prepare our table data for display.</p>
381
382<h3 id="the-result">The Result</h3>
383
384<p><img src="https://res.cloudinary.com/dvivnklwq/image/upload/v1614616466/cs0nmmsz4dat4nsbisji.gif" alt="" /></p>
385
386<p>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.</p>
387
388<p>Happy Coding!</p>
389
390
391  <div class="post-author-blurb">
392  <div class="blurb-left">
393    <div class="author-headshot"></div>
394  </div>
395  <div class="blurb-right">
396    <div class="author-desc">
397      <strong>Nafeu Nasir</strong> is a musician and full-stack web developer from Toronto, Canada who completed an H.B.Sc in Computer Science and Linguistics at the University of Toronto.
398    </div>
399    <div class="social-links">
400
401    
402    <a href="https://github.com/nafeu"><i class="fa fa-github" aria-hidden="true"></i></a>
403    
404
405    
406    <a href="https://www.linkedin.com/in/nafeu-nasir-aa679b60"><i class="fa fa-linkedin" aria-hidden="true"></i></a>
407    
408
409    
410    <a href="https://twitter.com/phrakturemusic"><i class="fa fa-twitter" aria-hidden="true"></i></a>
411    
412
413  
414    <a href="https://www.instagram.com/phrakture"><i class="fa fa-instagram" aria-hidden="true"></i></a>
415    
416
417  
418    <a href="https://www.youtube.com/channel/phrakture"><i class="fa fa-youtube-play" aria-hidden="true"></i></a>
419    
420
421    
422    <a href="mailto:[email protected]"><i class="fa fa-envelope" aria-hidden="true"></i></a>
423    
424
425  </div>
426  </div>
427</div>
428</div>
429
430
431    <!-- Documents about icons are here: http://fontawesome.io/icons/ -->
432<div class="footer">
433  <hr />
434  <div class="footer-link">
435    
436    <a href="https://www.facebook.com/phrakturemusic"><i class="fa fa-facebook" aria-hidden="true"></i></a>
437    
438
439	
440
441	
442    <a href="https://www.youtube.com/channel/phrakture"><i class="fa fa-youtube-play" aria-hidden="true"></i></a>
443    
444
445    
446    <a href="https://twitter.com/phrakturemusic"><i class="fa fa-twitter" aria-hidden="true"></i></a>
447    
448
449    
450    <a href="https://github.com/nafeu"><i class="fa fa-github" aria-hidden="true"></i></a>
451    
452
453	
454    <a href="http://stackoverflow.com/users/nafeu"><i class="fa fa-stack-overflow" aria-hidden="true"></i></a>
455    
456
457	
458
459    
460    <a href="https://www.linkedin.com/in/nafeu-nasir-aa679b60"><i class="fa fa-linkedin" aria-hidden="true"></i></a>
461    
462
463	
464
465	
466
467	
468    <a href="https://www.instagram.com/phrakture"><i class="fa fa-instagram" aria-hidden="true"></i></a>
469    
470
471	
472
473    
474
475    
476
477    
478    <a href="mailto:[email protected]"><i class="fa fa-envelope" aria-hidden="true"></i></a>
479    
480
481  </div>
482  © 2024 Nafeu Nasir.
483</div>
484
485  </div>
486</body>
487</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.