Two Ways You Can fetch client-side data in Next.Js
Tags: nextjs, javascript, frontend
Published: 2021-05-02 17:55:55

<img src="https://github.com/akuks/Misc/blob/main/Next.js.png?raw=true" />



Originally posted [here](https://ashutosh.dev/blog/post/2021/05/two-ways-fetch-client-side-data-nextjs)

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](https://jsonplaceholder.typicode.com/todos/) 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.


```javascript
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.

```javascript
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().


```javascript
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:


```javascript
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

```javascript
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:


```javascript
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.

```javascript
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.


```javascript
const{ data, error } = useSWR('https://jsonplaceholder.typicode.com/todos/')
```

That's all we need to do to get the data. And then


```javascript
if (error) {
    return <p>Failed to load Data</p>
}
```

We're checking if there is an error, then show it on the page. 


```javascript
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](https://ashutosh.dev/?category=8) for other Next.js articles.