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">=></span> <span class="p">{</span> 164 <span class="k">return</span> <span class="p">(</span> 165 <span class="o"><</span><span class="nx">table</span> <span class="p">{...</span><span class="nx">getTableProps</span><span class="p">()}</span><span class="o">></span> 166 <span class="o"><</span><span class="nx">thead</span><span class="o">></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">=></span> <span class="p">(</span> 168 <span class="o"><</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">></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">=></span> <span class="p">(</span> 170 <span class="o"><</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">></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"><</span><span class="sr">/th</span><span class="err">> 171</span> <span class="p">))}</span> 172 <span class="o"><</span><span class="sr">/tr</span><span class="err">> 173</span> <span class="p">))}</span> 174 <span class="o"><</span><span class="sr">/thead</span><span class="err">> 175</span> <span class="o"><</span><span class="nx">tbody</span> <span class="p">{...</span><span class="nx">getTableBodyProps</span><span class="p">()}</span><span class="o">></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">=></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"><</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">></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">=></span> <span class="p">{</span> 181 <span class="k">return</span> <span class="o"><</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">></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"><</span><span class="sr">/td</span><span class="err">> 182</span> <span class="p">})}</span> 183 <span class="o"><</span><span class="sr">/tr</span><span class="err">> 184</span> <span class="p">)</span> 185 <span class="p">})}</span> 186 <span class="o"><</span><span class="sr">/tbody</span><span class="err">> 187</span> <span class="o"><</span><span class="sr">/table</span><span class="err">> 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"><table></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">=></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 -> handles query logic (React Query) 280 -> prepares table data as a prop 281 -> returns TableInstance 282 283TableInstance 284 -> memoizes data 285 -> initiates table instance (React Table) 286 -> prepares table instance props 287 -> returns TableLayout 288 289TableLayout 290 -> utilizes table instance helpers (passed as props) 291 -> injects props into elements 292 -> 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">=></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">=></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"><</span><span class="nx">div</span><span class="o">></span><span class="nx">Loading</span><span class="p">...</span><span class="o"><</span><span class="sr">/div</span><span class="err">> 310</span> <span class="p">}</span> 311 312 <span class="k">return</span> <span class="p">(</span> 313 <span class="o"><</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">> 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">=></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">=></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">=></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"><</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">> 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.