Sorry for being long since the last update on this Next.Js series.
In last part of the series (Next.Js Series #2 - How to use getInitialProps to fetch external data and populate the data into pre-rendered Next.Js page), we have created the demo of getting initial props (calling an external API) and populate into the component for use.
In series #3, we would like to create individual author page with route /author/[authorId] by using Dynamic Routing feature in Next.Js.
First, we create a folder named "author", and create a file named "[authorId].js" in the "author" folder. Take note of the bracket in the file name in order to indicate dynamic route. 'author/[authodId].js' will match any URL like 'author/1', 'author/abc'.
In the [authorId].js, we can use 'useRouter()' hook to get the url path (for example, '1' of '/author/1') as part of the query object. The query object will look like this if the route is '/author/1':
{"authorId": "1"}
... which the 'authorId' is our file name.
After getting the authorId from the URL, we are going to fetch the data from API by passing in this authorId to the API URL:
let fetchData = async (authorId) => {
const response = await fetch(`https://reqres.in/api/users/${authorId}`);
const data = await response.json();
return data.data;
}
This 'fetchData' function will be called in the useEffect hook of the component when the component is first mounted. 'fetchData' function will return a Promise object back in the useEffect hook, then we resolve the promise to get the author data from the Promise object.
Finally we can populate the author data into React component:
import Link from 'next/link'
import { useEffect, useState } from 'react'
import fetch from 'isomorphic-unfetch'
import { useRouter } from 'next/router'
const Author = () => {
const router = useRouter()
const { authorId } = router.query
const [author, setAuthor] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
let componentMounted = true
if(authorId != null)
{
fetchData(authorId).then(author => {
if(componentMounted)
{
setAuthor(author)
setLoading(false)
}
})
}
return () => { componentMounted = false }
}, [authorId])
return (
<div className='container'>
{!loading && (
<>
<h1>{author.first_name}-{author.last_name}</h1>
<div>
<img alt={author.id} src={author.avatar} />
<p>{author.email}</p>
</div>
</>
)}
</div>
)
}
You may add a Loading component before the author data displayed on the page.
The example of author page will look like this:
The reason that we implemented this with useEffect hook is because pages are statically optimized by 'Automatic Static Optimization' in Next.Js and thus no route parameter was provided before the static page hydration.
After the hydration, Next.Js will trigger an update to the app and provide the router parameter that we mentioned earlier and then only we fetch the data in the useEffect hook. 'Automatic Static Optimization' is a feature of Next.Js that determines (by the presence of 'getServerSideProps' or 'getInitialProps') whether a page can be preloaded into static HTML.
Hope this article helps you to understand briefly on how dynamic routing in Next.Js works. We shall continue to publish more articles for this series to introduce the features in Next.Js and how you can implement them. Stay tune.
Do follow me for more future articles on web design, programming and self-improvement 😊
Top comments (1)
Well documented, how do I use this in nextjs 13