Data Fetching in Next.js v12.1 Simplified (with use cases)
Tags: javascript, webdev, react, nextjs
Published: 2022-03-09 07:55:55

Data fetching is one of the daunting topics for beginners in Next.js.
Unlike React.js where there is just one way of fetching data, Next.js provides different ways data can be fetched from an external source, which is why beginners find it difficult to understand. 😕

But, don't worry! 🌸😀

At the end of this article, you will be able to use each of the Data Fetching methods effectively in your Next.js web applications.💪

> Data Fetching is the process of getting stored data from an API, headless CMS and database for use in your web application.    

## Data Fetching Methods in Next.js
In Next.js we have 2 data rendering methods, which are:

- [Static-site generation (SSG)](#staticsite-generation) 

- [Server-side rendering (SSR)](#serverside-rendering)

Other features include: 
- [Incremental Static Regeneration (ISR)](#incremental-static-regeneration)

- [Dynamic routing](#dynamic-routing)

- [Client-side Rendering](#clientside-rendering)


### Static-site Generation (SSG)
This generates static HTML pages at build time. SSG is used in webpages where the data doesn't change regularly; such as the service page of a website, FAQ page, About Us page, the home page of your web application. 

> In SSG, [`getStaticProps`](https://nextjs.org/docs/basic-features/data-fetching/get-static-props) is used to pre-render a page at build time.

#### Code Sample:
Let's take a look at this route (code) below:
```jsx
import Link from "next/link"

//getStaticProps 
export const getStaticProps = async () => {
  const API_URL = "https://jsonplaceholder.typicode.com/posts"
  const request = await fetch(API_URL)
  const posts = await request.json()
  return  { props : { posts } }
}

//route 
export default function Home({ posts }) {
  return (
    <div>
      <main>
        {posts.map(post => (
          <Link href={`posts/${post.id}`}>
             <a key={post.id}>
                <h3>{post.title}</h3>
             </a>
          </Link>
        ))}    
      </main>
    </div> 
  )
}

```

> From the code snippet above, the server-side function `getStaticProps` fetches data from the `API URL` and returns an object.    
The object has a compulsory property called `props`. It contains the array of elements from the API.  
The `posts` array is then destructured from the `props` object and passed to the `Home` route.       
**If you delete or add new posts to the API when the application is in production, the changes won't reflect in the web application unless it is rebuild after the changes have been made.**   
     
### Dynamic Routing
It is used in Static-site generation to pre-render multiple pages. These pages are created at build time in production and every request in development mode. 

> In Dynamic Routing, [`getStaticPaths`](https://nextjs.org/docs/basic-features/data-fetching/get-static-paths) must be used with `getStaticProps`. You cannot use `getStaticPaths` with `getServerSideProps`.

#### Code Example:
Let's create the route for each article gotten from the API.   

```jsx
//gets each article according its id.
export const getStaticProps = async ({params}) => {
    const request = await fetch(`https://jsonplaceholder.typicode.com/posts/${params.id}`)
    const data = await request.json()
    return  {
      props : {post : data}
  }
  }
  
//creates a dynamic paths for all the posts
export async function getStaticPaths() {
    const request = await fetch(`https://jsonplaceholder.typicode.com/posts`)
    const data = await request.json()
    const paths = data.map((post) => ({
    params: { id: String(post.id) }
  }))

  return { paths, fallback: false }
}


export default function Post({post}) {
    return(
        <div>
            <h1>{post.id}</h1>
            <h3 className="text-xl">{post.title}</h3>
            <p>{post.body}</p>
        </div>
    )
}
```   
> `getStaticPaths` returns an object containing the property `paths` and `fallback`.
`paths` is an array of object containing the id of each posts. It tells the application how many paths is needed to be created.  
`fallback` is set to false.    
It can be set to `true/false/blocking`. [Learn more about fallback](https://nextjs.org/docs/basic-features/data-fetching/get-static-paths) 
 
### Incremental Static Regeneration
This allows us to use static generation without needing to rebuild the entire site. Request for changes on the static site is made at intervals already set by the developer. It allows us to update static pages after the web application has been built. 

> With ISR, you can retain the benefits of static while scaling to millions of pages.

#### Code Example:
```jsx
import Link from "next/link"

//getStaticProps 
export const getStaticProps = async () => {
const API_URL = "https://jsonplaceholder.typicode.com/posts"
  const request = await fetch(API_URL)
  const posts = await request.json()
  return  { props : { posts }, 
             revalidate : 60  //In seconds
      }
}

//route 
export default function Home({ posts }) {
  return (
    <div>
      <main>
           {posts.map(post => (
            <Link href={`posts/${post.id}`}>
                <a key={post.id}>
                  <h3>{post.title}</h3>
                </a>
          </Link>
          ))}
      </main>
    </div> 
  )
}

```  

> The code snippet above is similar to SSG. The difference is that `getStaticProps` returns a `revalidate` property which tells Next.js to re-generate the page at most once every 60 seconds.      
**If any changes is made to the posts (API) when the application is in production, the changes are reflected in the next 60secs.**         
      
### Server-side Rendering
This builds HTML pages at runtime or request time. Server-side rendering is used in web applications where the page's data changes on every request.

> In SSR, [`getServerSideProps`](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props) is used to pre-render a page whose data must be fetched at request time.

#### Code Example:
```jsx

export async function getServerSideProps() {
   const request = await fetch(<API_URL/>)
  const comments = await request.json()
  return  {
    props : {comments}
}
}


const CommentsPage = () => {// jsx }
export default CommentsPage
```
> From the code snippet above, `getServerSideProps` fetches comments made on each article at runtime during every request. 
**If new comments are added, it appears immediately the web application is refreshed.**     
 

### Client-side Rendering
It is similar to a single-page React app; where the data is not pre-rendered, but the data changes per each request. It is also used on pages where SEO (Search Engine Optimization) is not needed. 
In CSR, data fetching is done when the component or page mounts or when some specific actions, like a button click, are executed on the page.

>  React's `useState()` and `useEffect()` is used. Another alternative is [SWR](https://swr.vercel.app/) hook created by the Next.js team

#### Code Example:
```jsx
//Using React's useState and useEffect hooks
import { useState, useEffect } from "react";

export default function Posts() {
    const [posts, setPosts] = useState([])

    async function fetchPosts() {
        const request = await fetch("https://jsonplaceholder.typicode.com/posts")
        const data = await request.json()
        setPosts(data)
    }

useEffect(()=>{
    fetchPosts()
}, [])

    return (
        <div>
            {posts.map(post => <p key={post.id}>{post.title}</p>)}
        </div>
    )
}
```

## Conclusion
Depending on your application's use case, Next.js provides suitable methods for fetching and utilizing data. 
When requesting data from an external source, you just have to figure out how often data changes in the application, then pick the best rendering method for each call to the external resource.

Thank you for reading!   

{% embed https://dev.to/arshadayvid %}   

## Further Reading

1. [Next.js Complete Tutorial for Beginners (YouTube)](https://www.youtube.com/playlist?list=PLC3y8-rFHvwgC9mj0qv972IO5DmD-H0ZH)

2. [Understanding Next.js Data Fetching (CSR, SSR, SSG, ISR)](https://theodorusclarence.com/blog/nextjs-fetch-method)

3. [Data fetching strategies in NextJS](https://thecodest.co/blog/data-fetching-strategies-in-nextjs)

4. [Next.js Data Fetching Documentation ](https://nextjs.org/docs/basic-features/data-fetching/overview)


### Writer's Corner
Hi, I am open to freelance technical writing gigs and remote opportunities. Let's work together.  📧: asaoludavid234@gmail.com

Feel free to connect with me on [Twitter](https://twitter.com/Arshadayvid) and [LinkedIn](https://www.linkedin.com/in/david-asaolu234/)

<img src="https://media.giphy.com/media/BYoRqTmcgzHcL9TCy1/giphy.gif"/>