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:
Other features include:
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
is used to pre-render a page at build time.
Code Sample:
Let's take a look at this route (code) below:
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 theAPI URL
and returns an object.
The object has a compulsory property calledprops
. It contains the array of elements from the API.
Theposts
array is then destructured from theprops
object and passed to theHome
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
must be used withgetStaticProps
. You cannot usegetStaticPaths
withgetServerSideProps
.
Code Example:
Let's create the route for each article gotten from the API.
//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 propertypaths
andfallback
.
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 totrue/false/blocking
. Learn more about fallback
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:
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 arevalidate
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
is used to pre-render a page whose data must be fetched at request time.
Code Example:
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()
anduseEffect()
is used. Another alternative is SWR hook created by the Next.js team
Code Example:
//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!
Further Reading
Writer's Corner
Hi, I am open to freelance technical writing gigs and remote opportunities. Let's work together. ๐ง: asaoludavid234@gmail.com
Top comments (1)
Great Tutorial