Catch, Optimize Client-Side Data Fetching in Next.js Using SWR

Sh Raj - Jun 27 - - Dev Community

How to Optimize, Memorise Client-Side Data Fetching in Next.js Using SWR

In modern web applications, efficient data fetching is crucial for providing a smooth and responsive user experience. Next.js, a popular React framework, offers several ways to fetch data. One effective method is using the SWR (stale-while-revalidate) library, which provides a powerful and flexible approach to data fetching and caching. In this article, we'll explore how to use SWR for client-side data fetching in a Next.js application, and we'll compare it with traditional React hooks for data fetching.


GitHub logo SH20RAJ / nextbuild

Deploying Next JS Static Website on GH PAGES

This is a Next.js project bootstrapped with create-next-app.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying app/page.js. The page auto-updates as you edit the file.

This project uses next/font to automatically optimize and load Inter, a custom Google Font.

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more details.




Why Use SWR?

SWR is a React Hooks library for data fetching developed by Vercel, the team behind Next.js. SWR stands for stale-while-revalidate, a cache invalidation strategy. It provides several benefits:

  1. Optimized Performance: SWR caches the data and revalidates it in the background, ensuring the user always has the most up-to-date information without waiting.
  2. Automatic Revalidation: Data is automatically revalidated at intervals, keeping it fresh.
  3. Focus on Declarative Data Fetching: SWR abstracts away much of the boilerplate associated with data fetching.

Setting Up the Next.js Project

First, create a new Next.js project if you haven't already:

npx create-next-app@latest swr-example
cd swr-example
Enter fullscreen mode Exit fullscreen mode

Install the SWR library:

npm install swr
Enter fullscreen mode Exit fullscreen mode

Basic Routing Setup

Let's set up basic routing with a Home page and two additional pages to demonstrate data fetching using SWR and traditional React hooks.

app/page.js

import Link from "next/link";

export default function Home() {
  return (
    <>
      <div>
        <Link href="/new">New</Link>
        <br />
        <Link href="/new2">New2</Link>
      </div>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Fetching Data with SWR

Create a new page that uses the SWR library to fetch data from an API.

app/new/page.js

'use client';
import Link from 'next/link';
import useSWR from 'swr';

const fetcher = (url) => fetch(url).then((response) => response.json());

export default function Page() {
  const { data, error } = useSWR('https://jsonplaceholder.typicode.com/posts/1', fetcher);

  if (error) return 'Failed to load';
  if (!data) return 'Loading...';

  return (
    <>
      <Link href="/">Main</Link>
      <br />
      <div>Data Title: {data.title}</div>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Fetching Data with React Hooks

Create another page that fetches the same data using traditional React hooks.

app/new2/page.js

'use client';
import Link from 'next/link';
import { useEffect, useState } from 'react';

export default function Page() {
  const [data, setData] = useState({});
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/posts/1')
      .then((response) => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        return response.json();
      })
      .then((json) => {
        setData(json);
        setLoading(false);
      })
      .catch((error) => {
        setError(error);
        setLoading(false);
      });
  }, []);

  if (loading) return 'Loading...';
  if (error) return `Error: ${error.message}`;

  return (
    <>
      <Link href="/">Main</Link>
      <br />
      <div>Data Title: {data.title}</div>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

Comparison: SWR vs. React Hooks

SWR:

  • Pros:
    • Automatic caching and revalidation.
    • Easier to manage and less boilerplate code.
    • Better performance due to background revalidation.
  • Cons:
    • Requires additional dependency.

React Hooks:

  • Pros:
    • Native to React, no additional dependencies required.
    • More control over the data fetching process.
  • Cons:
    • More boilerplate code for handling loading and error states.
    • No built-in caching or revalidation.

Conclusion

Using SWR for data fetching in a Next.js application offers several advantages, including automatic caching, revalidation, and reduced boilerplate code. While traditional React hooks provide more control, they require more effort to handle common scenarios like caching and error handling. Depending on your application's needs, SWR can be a powerful tool to enhance performance and user experience.

For more detailed information, you can also refer to the SWR documentation and the Next.js official documentation.

Troubleshooting

GitHub logo SH20RAJ / nextjs-loading-problem

NextJS Reloading Problem

vercel/next.js#64822

Summary if i click and navigate to about from the main page after loading of data in main page and then i come from about to the main page using navigation i see the loading once or req too the api is sent once more time, I don't want that if the user already loaded the api and navigated then come back it should show the previous data ( even it should show the scroll loc until I scrolled on the main page)

"When a user navigates from the main page to the about page after the data has loaded on the main page, and then returns to the main page using navigation, I want to ensure that the data isn't reloaded unnecessarily. I want the previously fetched data to be displayed without triggering another API request. Additionally, I'd like the scroll position of the main page to remain…

https://nextjs.org/docs/pages/building-your-application/data-fetching/client-side

If you encounter issues such as loading problems, check out the Next.js loading problem issue on GitHub for community-driven solutions and discussions.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .