DEV Community

Cover image for Next.Js Series #3 - How to create dynamic routing with Next.Js component
Dylan Oh
Dylan Oh

Posted on • Updated on

Next.Js Series #3 - How to create dynamic routing with Next.Js component

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.

Alt Text

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'.

Alt Text

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"}
Enter fullscreen mode Exit fullscreen mode

... 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;
}
Enter fullscreen mode Exit fullscreen mode

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>
    )
}
Enter fullscreen mode Exit fullscreen mode

You may add a Loading component before the author data displayed on the page.

The example of author page will look like this:

Alt Text

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.

Discussion (0)