Data Fetching in Next.js

ยท

4 min read

Introduction

If you're building a web app with Next.js, you'll inevitably need to fetch data from somewhere - whether it's an API, database, or other source. And Next.js gives you powerful options to handle data fetching on both client and server-side.

In this guide, we'll dive into the various data fetching methods in Next.js and how to use them for different use cases. By the end, you'll be a pro at fetching data in your Next.js apps!

Need for Data Fetching in our applications

Before we jump into the code, it's worth understanding why data fetching is so important for our web apps:

  1. Fetching data is crucial for populating your UI with real information to display to users.

  2. Fetched data makes our application more dynamic and upto date.

  3. Fetching data makes our application more useful to end users.

Client-Side Fetching

The most basic way to fetch data in Next.js is by using the standard browser fetch API or libraries like Axios directly in your React components. Using React Hooks like useState and useEffect

App.tsx

import ClientSideFetch from "./components/ClientSideFetch";

export default function Home() {
  return (
    <>
      <h1>Fetched Data</h1>
      <ClientSideFetch />
    </>
  );
}

Let's create a component folder and under that create a component called ClientSideFetch.tsx

components/ClientSideFetch.tsx

"use client";
import React, { useEffect, useState } from "react";
import { userDataType } from "../types";

const ClientSideFetch = () => {
  const [data, setData] = useState<userDataType[]>();

  const fetchData = async () => {
    const res = await fetch("https://jsonplaceholder.typicode.com/todos");
    const todos = await res.json();
    setData(todos);
  };

  useEffect(() => {
    fetchData();
  }, []);
  return (
    <>
      <div>
        {data?.map((d) => (
          <li key={d.id}>{d.title}</li>
        ))}
      </div>
    </>
  );
};

export default ClientSideFetch;

In my case, I am using Typescript so I had to define types:

Types.tsx

export type userDataType = {
  userId: string;
  id: string;
  title: string;
  completed: boolean;
};

If you are using Javascript, you can skip this step. Coming to explanation of Client-side rendering. This allows you to:

  1. Make requests directly from the client-side

  2. Use any data-fetching library you like

  3. Handle loading states and UI updates

However, client-side rendering isnt the best way of fetching data in Next.js. This makes your application slower and also you have to use too much boilerplate code. To reduce boilerplate that is usage of useState and useEffect we can make use of a library called Tanstack Query which not only used in data fetching but also asynchronous state management. To learn more about data fetching using Tanstack query you can refer to this blog

The recommended way of fetching data in Next.js application is through server side rendering. Why is that? when data is fetched from server-side, it sends very less Javascript to the browser which makes our application load time less and more performant.

Server-side Fetching

By default, all the components in Next.js are server-rendered which makes data fetching on server-side very easy and you dont have to worry about any additional setup.

App.tsx

import ClientSideFetch from "./components/ClientSideFetch";
import ServerSideFetch from "./components/ServerSideFetch";

export default function Home() {
  return (
    <>
      <h1>Fetched Data</h1>
      {/* <ClientSideFetch /> */}
      <ServerSideFetch />
    </>
  );
}

In components create a component called ServerSideFetch.tsx

ServerSideFetch.tsx

import React from "react";
import { userDataType } from "../types";

const ServerSideFetch = async () => {
  const fetchData = async () => {
    const res = await fetch("https://jsonplaceholder.typicode.com/todos");
    return await res.json();
  };

  const data: userDataType[] = await fetchData();

  return (
    <>
      <h2>Server side fetched</h2>
      {data.map((d) => (
        <li key={d.id}>{d.title}</li>
      ))}
    </>
  );
};

export default ServerSideFetch;

If you follow this method, you have successfully fetched data on server-side, which is also what Next.js recommend. Why? Server-side rendering and fetching reduces the data that will come from server to browser which in turn will reduce the load time and increase the performance of the application.

There is one more way to play around data in Next.js, that is through something called as Server actions. It is similar to server-side fetching but it has its own differences and obstacles. Will cover it in one of the upcoming blogs in this Next.js Learning path. This is the fifth blog in the series and if you want to read the previous blogs, then you can read them by clicking here.

Conclusion

This is the fifth blog in the Next.js Learning path series and if you want to read the previous blogs, then you can read them by clicking here. In the upcoming blogs I am planning to cover Next.js server actions, Integration with prisma and MongoDB, NextAuth and many more. If you are interested in such blogs, please make sure to subscribe to my newsletter.

To get access to the code that I have used above, click here. For any query, you can get in touch with me via LinkedIn and twitter. Leave all your comments and suggestions in the comment section. Let's connect and share more ideas.

Happy coding!

ย