Two Ways You Can fetch client-side data in Next.Js
In Next.js, sometimes pre-rendering the page doesn't make sense and, it is the need of the hour to fetch the data on the client-side. For ex- the frequently updating data like the stock data, or the currency exchange prices, or the commodities prices.
We'll understand client-side data fetching with the help of an example.
Before we jump into the code, first understand the problem that we're solving here.
Problem Statement
Show JSON API of the ToDo list on our web page.
API Location - https://jsonplaceholder.typicode.com/todos/
Note: THIS API IS FROM THE INTERNET AND ONLY FOR TESTING. PLEASE RESPECT IT AND DON'T BOMBARD IT WITH REQUESTS.
Solution-1
Under the pages folder, create a new file "todo.js" and, for the starting, add the following code.
import { useEffect, useState } from "react";
function ToDoPage() {
return (
<div>
<h1>ToDO LIST</h1>
</div>
)
}
export default ToDoPage
Nothing special in the above code. We import useEffect() and useState() directly from the react.
To solve the above problem, we'll use the imported function useEffect() with fetch API to get the ToDo list.
What do we need to do?
Let's initialize constants first under the ToDoPage() function.
const [ toDos, setToDos ] = useState()
const [isLoading, setIsLoading] = useState(false)
The isLoading and setIsLoading() variables are required to show the "Loading..." if the data fetching from the API is still pending.
Next is to use the fetch API under the useEffect().
useEffect(() => {
setIsLoading(true)
fetch('https://jsonplaceholder.typicode.com/todos/')
.then(response => response.json())
.then(data => {
setToDos(data) // Set the toDo variable
setIsLoading(false)
})
}, [])
The code still has problems if the API is still fetching the result, then the app crashes.
To avoid this, add the following:
if (isLoading) {
return <p>Loading....</p>
}
if (!toDos) {
return <p>No List to show</p>
}
Finally, we need to map the result and return the result to the app
return (
<div>
<h1>TODO List</h1>
<ul>
{toDos.map( toDo =>
<li key={toDo.id}>
{toDo.title} - <span>( {toDo.completed ? 'Completed' : 'Not Completed'} )</span>
</li>
)}
</ul>
</div>
)
The function will look like:
function ToDoPage() {
const [ toDos, setToDos ] = useState()
const [isLoading, setIsLoading] = useState(false)
useEffect(() => {
setIsLoading(true)
fetch('https://jsonplaceholder.typicode.com/todos/')
.then(response => response.json())
.then(data => {
setToDos(data)
setIsLoading(false)
})
}, [])
if (isLoading) {
return <p>Loading....</p>
}
if (!toDos) {
return <p>No List to show</p>
}
return (
<div>
<h1>TODO List</h1>
<ul>
{toDos.map( toDo =>
<li key={toDo.id}>
{toDo.title} - <span>( {toDo.completed ? 'Completed' : 'Not Completed'} )</span>
</li>
)}
</ul>
</div>
)
}
Visit the URL http://localhost:3000/todo and, you will the results like the below illustration.
Solution-2
The previous solution is sufficient to solve the problem. However, it is the React way of fetching the data from an API.
In this solution, we discuss the Next.js way of getting the data from an API.
We'll use the "SWR" package to fetch the data from an API.
Before using it, we need to install it using the npm.
npm install swr
And wait till the installation completes.
Under the pages folder, add another file todo-alt.js and add the following code.
import useSWR from 'swr'
function TodoAltPage() {
const{ data, error } = useSWR('https://jsonplaceholder.typicode.com/todos/')
if (error) {
return <p>Failed to load Data</p>
}
if (!data) {
return <p>Loading....</p>
}
return (
<div>
<h1>TODO List</h1>
<ul>
{data.map( toDo =>
<li key={toDo.id}>
{toDo.title} - <span>( {toDo.completed ? 'Completed' : 'Not Completed'} )</span>
</li>
)}
</ul>
</div>
)
}
export default TodoAltPage
Initially, we import the useSWR() from the "swr" package. And the use it in our function.
const{ data, error } = useSWR('https://jsonplaceholder.typicode.com/todos/')
That's all we need to do to get the data. And then
if (error) {
return <p>Failed to load Data</p>
}
We're checking if there is an error, then show it on the page.
if (!data) {
return <p>Loading....</p>
}
If the data is not loaded then, show "Loading" on the web page.
After that, we're mapping the data just like we did in our first solution.
Visit the URL, http://localhost:3000/todo-alt and, you will see the same results as in the previous solution.
This solution is cleaner and suited more for the Next.js applications. Though we can use, in react and other applications, there are no boundaries.
Visit for other Next.js articles.