While building applications we might not always need to pre-render the data. If we design a dashboard for the Topcoder platform where users can see analytics of the articles they have published, likes, dislikes, followers, etc, there is no point in pre-rendering. This is because the data is highly specific to each user and there is no need for search engine optimization. Instead, we use client-side data fetching, and in this article we will go through some examples while explaining the concept thoroughly.
To create a next.js application: npx create-next-app next-routing
.
Because the focus of this article is on routing, the folder responsible for this may be the pages folder.
Now create a mock server API using the json-server package. Create a file db.json which contains the dashboard that we will be using in this section.
db.json
1
2
3
4
5
6
7
8
{
"topcoder-dashboard": {
"articles": 24,
"likes": 40,
"dislikes": 10,
"following": 5
}
}
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
{ "name": "pre-rendering", "private": true, "scripts": { "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint", "server-json": "json-server --watch db.json --port 2000" }, "dependencies": { "json-server": "^0.16.3", "next": "12.0.7", "react": "17.0.2", "react-dom": "17.0.2" }, "devDependencies": { "eslint": "8.4.0", "eslint-config-next": "12.0.7" } }
To run: npm run server-json
Now create a file in the pages folder, dashboard.js. Here we fetch and store the data for rendering using the state and the effect hooks.
dashboard.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import {
useState,
useEffect
} from 'react'
function Dashboard() {
const [loading, setloading] = useState(true)
const [dashboard, setdashboard] = useState(null)
useEffect(() => {
async function fetchdashboard() {
const response = await fetch('http://localhost:2000/topcoder-dashboard')
const data = await response.json()
setdashboard(data)
setloading(false)
}
fetchdashboard()
}, [])
if (loading) {
return <h2>Loading...</h2>
}
return (
<div>
<h2>Dashboard</h2>
<ul>
<li>Articles - {dashboard.articles}</li>
<li>Likes - {dashboard.likes}</li>
<li>Dislikes - {dashboard.dislikes}</li>
<li>Followers - {dashboard.followers}</li>
</ul>
</div>
)
}
export default Dashboard
Head over to localhots:3000/dashboard
If we preview the document we can see only the loading text as next.js did pre-render the page. However, the pre-rendered page is based on the initial state of that component. Looking at the code we can observe that loading is true to begin with, which implies the loading text is only visible as next.js doesn’t wait for the API call and update the state of the component. Therefore, the page source will always contain the loading text, though the data is never pre-rendered.
Stale-While-Revalidate (SWR) is an HTTP cache invalidation technique that’s mostly a react hooks library for data retrieval. It covers caching, invalidation, attention tracking, interval reflection, and more.
We’ll get the same result as before, but this time we’ll use SWR. Go to your editor and erase the dashboard’s contents. To use SWR, install it with npm: npm I swr.
The code for the new dashboard is seen below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import useSWR from 'swr'
const fetcher = async () => {
const response = await fetch('http://localhost:2000/topcoder-dashboard')
const data = await response.json()
return data
}
function Dashboard() {
const {
data,
error
} = useSWR('dashboard', fetcher)
if (error) return 'Error Occured'
if (!data) return 'Loading...'
return (
<div>
<h2>Dashboard</h2>
<ul>
<li>Articles - {data.articles}</li>
<li>Likes - {data.likes}</li>
<li>Dislikes - {data.dislikes}</li>
<li>Followers - {data.followers}</li>
</ul>
</div>
)
}
export default Dashboard
Heading over to localhots:3000/dashoard we can observe a similar result.
Using SWR for data fetching is much simpler than using state hooks. If we update the db.json at any point, to get the updated value we have to refresh the browser in the case of fetch API. In the case of SWR its hook will automatically fetch the latest data and update the UI accordingly.