Next.js Client Side Data Fetching

Next.js Client Side Data Fetching
Photo by Gabriel Crismariu / Unsplash

Next.js is a popular JavaScript framework for building server-rendered React applications. In Next.js and getting data from the server is a fundamental function. Below are 3 ways to do it depending on your requirements.

Using getInitialProps with isomorphic-unfetch

You can use the getInitialProps method to fetch data on the server-side and pass it down to the client-side as props. Here's an example of how you might use getInitialProps to fetch data in a Next.js component:

import { useRouter } from 'next/router'
import fetch from 'isomorphic-unfetch'

function Post({ post }) {
  const router = useRouter()

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  )
}

Post.getInitialProps = async function(context) {
  const { id } = context.query
  const res = await fetch(`https://my-api.com/posts/${id}`)
  const post = await res.json()

  return { post }
}

export default Post

In this example, the Post component is passed a post prop that contains the data fetched from the API. The getInitialProps method is called on the server-side when the component is first rendered, and the data is passed down to the client-side as props.

You can also use getInitialProps to handle authentication and authorization, redirect users, or set server-side headers.

A little more about isomorphic-unfetch which is a lightweight library for making HTTP requests in both the server-side and client-side of a Next.js application. It is designed to be a drop-in replacement for the fetch API, with the added benefit of being able to be used in both the server-side and client-side environments.

Here's an example of how you might use isomorphic-unfetch to make an HTTP GET request in a Next.js component:

import fetch from 'isomorphic-unfetch'

async function getData() {
  const res = await fetch('https://my-api.com/data')
  const data = await res.json()

  return data
}

In this example, isomorphic-unfetch is used to make a GET request to an API endpoint and retrieve the data as a JSON object. isomorphic-unfetch can also be used to make POST, PUT, DELETE, and other types of HTTP requests, and it supports options such as setting headers and sending a body with the request.

One of the main benefits of using isomorphic-unfetch is that it can be used in both the server-side and client-side environments, allowing you to write code that works seamlessly in both environments without the need for different libraries or APIs. This makes it a convenient choice for building server-rendered React applications with Next.js.

Using useEffect

If you want to fetch data on the client-side, you can use the useEffect hook in your component to make an API call and update the component's state when the data is received. Here's an example of how you might use useEffect to fetch data on the client-side:

import { useEffect, useState } from 'react'
import fetch from 'isomorphic-unfetch'

function Post({ postId }) {
  const [post, setPost] = useState(null)

  useEffect(() => {
    async function fetchPost() {
      const res = await fetch(`https://my-api.com/posts/${postId}`)
      const data = await res.json()
      setPost(data)
    }

    fetchPost()
  }, [postId])

  if (!post) {
    return <div>Loading...</div>
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </div>
  )
}

export default Post

In this example, the useEffect hook is used to fetch the post data from the API when the component is rendered on the client-side. The useState hook is used to store the post data in the component's state, and the component is rendered with a loading message until the data is received.

Using SWR

SWR (stale-while-revalidate) is a strategy for data fetching in React that allows you to keep your UI up-to-date with the latest data from a server, while also allowing for fast performance by using a cache.

To use SWR with Next.js, you'll need to install the swr package from npm:

npm install swr

Once you have SWR installed, you can use the useSWR hook to fetch data in your Next.js component. The useSWR hook takes a key and a function that returns a promise, and it returns the data from the promise as well as some other helpful values such as isValidating and error.

Here's an example of how you might use useSWR to fetch data in a Next.js component:

import { useSWR } from 'swr'

function MyComponent() {
  const { data, error } = useSWR('/api/users', fetch)

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

  return (
    <div>
      {data.map(user => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  )
}

In this example, the useSWR hook is called with the key '/api/users' and the fetch function. The hook will first check its cache to see if it has the data for this key, and if it does, it will return the cached data immediately. If the data is not in the cache, the hook will call the fetch function to request the data from the server, and it will update the cache with the response.

You can also customize the behavior of SWR by passing an options object as the second argument to the useSWR hook. For example, you can use the refreshInterval option to specify how often the data should be refetched from the server, or you can use the dedupingInterval option to specify how long SWR should wait before starting a new request if a request is already in progress.