Nextjs Client Side Data Fetching With Swr Or Useeffect Complete Guide

 Last Update:2025-06-22T00:00:00     .NET School AI Teacher - SELECT ANY TEXT TO EXPLANATION.    7 mins read      Difficulty-Level: beginner

Understanding the Core Concepts of Nextjs Client side Data Fetching with SWR or useEffect

Next.js Client Side Data Fetching with SWR or useEffect

1. Using SWR for Client-Side Data Fetching

SWR (Stale-While-Revalidate) is a React hook for fetching, caching, and revalidating data. It aims to provide a better user experience by showing stale data instantly while fetching the latest data in the background.

Installation: First, you need to install SWR.

npm install swr

or

yarn add swr

Basic Usage: Here's a simple example of fetching user data using SWR.

import useSWR from 'swr';

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

function UserProfile() {
  const { data, error } = useSWR('/api/user', fetcher);

  if (error) return <div>Failed to load</div>;
  if (!data) return <div>Loading...</div>;

  return <div>Hello {data.name}!</div>;
}

How it works:

  1. Initial Load: When the component mounts, SWR fetches the data from the provided URL and displays it.
  2. Stale Data: While the new data is being fetched, the component continues to display the old (stale) data.
  3. Background Revalidation: Once the new data is fetched, SWR updates the state and re-renders the component.

Important Features:

  • Global Cache: SWR maintains a global cache, so if you fetch the same data in multiple components, SWR will only fetch it once.
  • Revalidation: SWR automatically revalidates the data in the background every few seconds, depending on the refreshInterval and refreshWhenHidden options.
  • Error Handling: You can handle errors gracefully with the error returned by useSWR.

Advanced Usage: You can customize SWR with various options, such as refreshInterval, refreshWhenHidden, and loadingTimeout.

const { data, error, isValidating } = useSWR('/api/data', fetcher, {
  refreshInterval: 5000,         // Revalidates every 5 seconds
  refreshWhenHidden: false,      // Stops revalidation while the window is not focused
  loadingTimeout: 5000,          // Timeout for loading state
});

2. Using useEffect for Client-Side Data Fetching

useEffect is a React hook that lets you perform side effects in function components. While it’s not as feature-rich as SWR, it’s still a powerful tool for basic data fetching.

Basic Usage: Here's a simple example of fetching user data using useEffect.

import { useState, useEffect } from 'react';

function UserProfile() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await fetch('/api/user');
        if (!response.ok) {
          throw new Error('Failed to fetch data');
        }
        const json = await response.json();
        setData(json);
      } catch (error) {
        setError(error);
      }
    };

    fetchData();
  }, []);  // Empty dependency array runs the effect only once on mount

  if (error) return <div>Failed to load</div>;
  if (!data) return <div>Loading...</div>;

  return <div>Hello {data.name}!</div>;
}

How it works:

  1. Initial Load: When the component mounts, the useEffect hook is triggered, and the fetchData function is called.
  2. Data Fetching: The fetchData function fetches the data from the provided URL and updates the data state.
  3. Error Handling: If an error occurs, it updates the error state.

Important Features:

  • Customization: You can control when the effect runs and what dependencies it relies on with the dependency array.
  • Cleanup: useEffect lets you specify a cleanup function that runs when the component unmounts or before the effect runs again.
  • Asynchronous Code: You can handle asynchronous code using async/await or callbacks.

Example with Cleanup: To stop a fetch request when the component unmounts:

Online Code run

🔔 Note: Select your programming language to check or run code at

💻 Run Code Compiler

Step-by-Step Guide: How to Implement Nextjs Client side Data Fetching with SWR or useEffect

1. Overview

Client-Side Data Fetching: Client-side data fetching involves fetching data from an external API after the page has been loaded into the browser. This is useful when you need to fetch data based on user interactions or when you want to separate data fetching from the initial page load.

SWR: SWR (Stale While Revalidate) is a React hook library that helps with data fetching and caching. It automatically revalidates data under the hood, ensuring you get fresh data with minimal effort.

useEffect: useEffect is a built-in React hook that lets you perform side effects in function components. You can use it to fetch data after the component mounts.

2. Client-Side Data Fetching with useEffect

Let's start with an example using the useEffect hook.

Example: Fetching Data from a Public API

  1. Create a Next.js Page: Create a new file pages/useEffectExample.js.

  2. Use useEffect to Fetch Data:

    import React, { useEffect, useState } from 'react';
    
    const UseEffectExample = () => {
      const [data, setData] = useState(null);
      const [isLoading, setIsLoading] = useState(true);
      const [error, setError] = useState(null);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
            if (!response.ok) {
              throw new Error('Network response was not ok');
            }
            const result = await response.json();
            setData(result);
          } catch (error) {
            setError(error.message);
          } finally {
            setIsLoading(false);
          }
        };
    
        fetchData();
      }, []);
    
      if (isLoading) return <p>Loading...</p>;
      if (error) return <p>Error: {error}</p>;
    
      return (
        <div>
          <h1>{data.title}</h1>
          <p>{data.body}</p>
        </div>
      );
    };
    
    export default UseEffectExample;
    

3. Client-Side Data Fetching with SWR

Now, let's look at how you can achieve the same thing using SWR.

  1. Install SWR:

    npm install swr
    
  2. Create a Next.js Page: Create a new file pages/swrExample.js.

  3. Use SWR to Fetch Data:

    import useSWR from 'swr';
    
    const fetcher = (url) => fetch(url).then((res) => res.json());
    
    const SwrExample = () => {
      const { data, error, isLoading } = useSWR('https://jsonplaceholder.typicode.com/posts/1', fetcher);
    
      if (isLoading) return <p>Loading...</p>;
      if (error) return <p>Error: {error.message}</p>;
    
      return (
        <div>
          <h1>{data.title}</h1>
          <p>{data.body}</p>
        </div>
      );
    };
    
    export default SwrExample;
    

4. Explanation

useEffect:

  • useState: Manages the state of data, loading, and error.
  • useEffect: Executes the data fetching function when the component mounts. The empty dependency array [] ensures it runs once.
  • Error Handling: Uses try-catch to handle network errors.

SWR:

  • useSWR: Automatically handles fetching, caching, and revalidation.
  • fetcher: A function that takes a URL and returns the JSON response.
  • Error Handling: Automatically manages loading and error states.

5. Conclusion

Both approaches are valid for client-side data fetching in Next.js. useEffect is more flexible and gives you full control over the fetching process, while SWR simplifies fetching with built-in features like automatic revalidation and error handling. Choose the one that best fits your needs.

Top 10 Interview Questions & Answers on Nextjs Client side Data Fetching with SWR or useEffect

Top 10 Questions and Answers on Next.js Client-Side Data Fetching with SWR or useEffect

1. What is SWR in Next.js, and how does it work?

Answer:
SWR stands for "Stale While Revalidate," a data fetching strategy implemented as a hook by Vercel for React apps, including those built with Next.js. It works by returning data from the cache (stale data) while simultaneously fetching the latest data from your server or API (revalidation). Once the fetch request is completed, it updates the cache and re-renders your component with the fresh data. Key advantages include automatic revalidation when window goes online, focus or visibility changes, and polling intervals.

2. How should I install and use SWR in my Next.js project?

Answer:
You can install SWR using npm:

npm install swr

To use SWR, import the useSWR hook and pass your API endpoint to it:

import useSWR from 'swr';

const Component = () => {
  const { data, error } = useSWR('/api/data', fetcher);

  if (error) return <div>Error loading</div>;
  if (!data) return <div>Loading...</div>;

  return <div>{data.result}</div>;
};

const fetcher = async url => {
  const response = await fetch(url);
  return response.json();
};

Here, /api/data is the URL you want to fetch data from, and fetcher is a promise-based fetching function.

3. Can I use useEffect to perform client-side data fetching in Next.js?

Answer:
Absolutely! The useEffect hook allows you to handle side effects in your React components, including data fetching when the component mounts. Here’s how you’d typically use it:

import { useState, useEffect } from 'react';

const Component = () => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    const fetchData = async () => {
      try {
        const response = await fetch('/api/data');
        const result = await response.json();
        setData(result);
      } catch (err) {
        setError(err);
      }
      setLoading(false);
    };
    fetchData();
  }, []); // Empty dependency array means this effect runs only once on mount

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error loading data</div>;
  return <div>{JSON.stringify(data)}</div>;
};

In this example, we call our fetching code inside an anonymous async function that runs within the useEffect.

4. What are the main differences between SWR and useEffect?

Answer:

  • Caching: SWR provides built-in caching of API responses out of the box, whereas with useEffect, you have to manually implement caching logic.
  • Revalidation: SWR automatically handles periodic revalidation and refreshes the stale data without requiring complex state management. With useEffect, developers need to manage this themselves.
  • Error Handling: Both useEffect and SWR provide ways to handle errors. However, SWR offers more granular options like a retry system upon errors.
  • Dependency Simplification: With useEffect, your data fetching logic can become more complex, particularly if multiple dependencies trigger the fetch. In contrast, SWR handles all this seamlessly through its configuration.

5. Should SWR be used for every client-side data fetch in Next.js?

Answer:
No, it isn’t necessarily the best choice for all kinds of data fetching tasks in your components. For instance:

  • If you're dealing with a large dataset where the cost of fetching new data frequently becomes a bottleneck, it might be more efficient to use useEffect.
  • If you need fine-grained control over caching mechanisms, like selectively invalidating parts of your cache, then useEffect coupled with a more advanced caching library like react-query could be preferable.
  • For simple one-time fetches without concern for stale states or revalidations, using useEffect is straightforward enough.

6. Can SWR automatically poll an API endpoint?

Answer:
Yes, one of the advantages of SWR is that you can configure it to periodically poll an API endpoint via the refreshInterval parameter:

const { data, error } = useSWR('/api/data', fetcher, { refreshInterval: 1000 }); // Polls every second

By setting refreshInterval, SWR will revalidate the data at set intervals while your web application remains focused or online.

7. How can I handle network errors more gracefully with SWR?

Answer:
Handling network errors efficiently is made easier with SWR due to its robust error handling mechanism built-in. For example, you can retry fetching data after a specific interval by configuring the refreshIntervalOnReconnect, refreshInterval, and also utilizing onErrorRetry hooks:

const fetcher = async path => {
  const res = await fetch(path)
  if (!res.ok) throw new Error(res.statusText + ": " + res.url)
  return res.json()
}

const { data, error } = useSWR('/api/data', fetcher, {
  onErrorRetry: (error, key, config, revalidate, { retryCount }) => {
    if (retryCount >= 10) {
      return; // stop the retires after the condition is satisfied
    }
    setTimeout(() => revalidate({ retryCount }), 5000);
  },
})

The above onErrorRetry function specifies that SWR should retry fetching "/api/data" every 5 seconds, up to a maximum of 10 retries.

8. Is it possible to customize the SWR cache behavior?

Answer:
Yes, you can customize SWR's cache behavior by using the global swrConfig provider to override default settings such as refreshInterval and dedupingInterval. Here is an example:

import useSWR, { SWRConfig } from 'swr';

const App = () => (
  <SWRConfig value={{ refreshInterval: 3000 }}>
    {/* ... */}
  </SWRConfig>
);

// Child component
const Component = () => {
  const { data, error } = useSWR('/api/data', fetcher);

  // ...
};

In this setup, all SWR hooks under App will have a refreshInterval of 3000 milliseconds unless specifically overridden in individual hooks.

9. Can useEffect be used alongside SWR in the same component?

Answer:
While using both SWR and useEffect in the same component isn't typical, it's certainly plausible depending on your requirements—such as needing additional data from one or more APIs when certain conditions are met or performing non-data-fetching side effects.

For example:

import useSWR from 'swr';
import { useState, useEffect } from 'react';

// Custom fetcher
const customFetcher = async (url, token) => {
  const res = await fetch(url, {
    headers: new Headers({
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    }),
  });

  return res.json();
};

const Component = ({ userToken }) => {
  const [localData, setLocalData] = useState({});

  const { data, error } = useSWR('/api/data', (url) =>
    customFetcher(url, userToken)
  );

  useEffect(() => {
    // Additional local data fetching or side effects
    if (data) {
      setLocalData({ ...data, timestamp: new Date().toISOString() });
    }
  }, [data]);

  // Handle errors
  if (error) return <div>Error loading data</div>;

  return (
    <div>
      SWR Data: {JSON.stringify(data)}
      <br />
      Local Data: {JSON.stringify(localData)}
    </div>
  );
};

10. How do I ensure the fetched data is optimized for performance in both SWR and useEffect?

Answer:
For performance optimization:

  • Selective Fetching: Only fetch the necessary data using query parameters or filtering logic to minimize API payload sizes.
  • Debouncing and Throttling: Especially useful for handling input-driven queries (like search bars), preventing excessive API calls.
  • Prefetching: Use SWR’s mutate method to prefetch and cache data when needed.
  • Pagination: Implement pagination for large datasets; load only what the user currently needs into memory.
  • Batching: Combine multiple API requests into a single call to reduce latency and server load.

With these strategies, you can greatly enhance performance in your Next.js applications using either SWR or useEffect.

You May Like This Related .NET Topic

Login to post a comment.