Alfred
Alfred

Reputation: 447

Nextjs dynamic route is rendered twice

I have a dynamic route in pages/user/[id].jsx my [id].jsx contains console.log(useRouter().query.id); if I go to url/user/5 When I check console once I get undefined and then the correct id (5 in this case). What is going on here, is there a way to fix it?

Upvotes: 7

Views: 5041

Answers (2)

JSGuru
JSGuru

Reputation: 329

I don't know the content of your page, but if you don't have getStaticProps or getServerSideProps (or old getInitialProps) then NextJS handles your page as the static page and does the automatic static optimization (https://nextjs.org/docs/advanced-features/automatic-static-optimization#how-it-works)

In there you can read that:

During prerendering, the router's query object will be empty since we do not have query information to provide during this phase. After hydration, Next.js will trigger an update to your application to provide the route parameters in the query object.

To overcome the double render, you can do:

// pages/user/[id].jsx

import { useRouter } from 'next/router';

const UserPage = () => {
    const { query, isReady } = useRouter()

    // wait until there is a query with the data; or `!query.id`
    if (!isReady) {
        return null;
    }

    return query.id;
}

export default UserPage;

Or if you have some useEffect:

// pages/user/[id].jsx

import { useEffect } from 'react';
import { useRouter } from 'next/router';

const UserPage = () => {
    const { query, isReady } = useRouter()
    
    useEffect(() => {
        if (isReady) {
            // fetch(`your.domain/user/${query.id}`)...;
        }
    }, [isReady])

    if (!isReady) {
        return null;
    }

    return query.id;
}

export default UserPage;

Upvotes: 4

You can use getInitialProps for this.

// sample usage
// file /pages/user/[id].jsx

export default function User({id}){ 
  return <div>{id}</div>
}
    
User.getInitialProps = (appContext) => {
  return {id: appContext.query.id}
}

Upvotes: 3

Related Questions