Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does router.query return an empty object in NextJS on first render?

My url is: http://localhost:3000/company/60050bd166cb770942b1dadd

I want to get the value of the id by using router.query. However when I console log router.query, it returns an empty object first and then return the object with data. This results in bugs in other parts of my code as I need the value of the id to fetch other data.

Console log

This is my code:

import { useRouter } from 'next/router';
import styles from './CompanyId.module.css';

import { useQuery } from '@apollo/client';
import { COMPANY_DETAILS } from '../../queries/company';

const CompanyDetails = () => {
  const router = useRouter();
  console.log(router.query);

  const { loading, data } = useQuery(COMPANY_DETAILS, {
    variables: { _id: companyId },
  });

  return (
    <div className={styles.container}>
      {loading ? <h1>Loading</h1> : <h1>{data.company.name}</h1>}
    </div>
  );
};

export default CompanyDetails;

My program is crashing right now because the companyId variable is empty on the first render. Is there anyway to go around this problem?

like image 878
Aidenhsy Avatar asked Nov 01 '25 18:11

Aidenhsy


2 Answers

In Next.js:

  • Pages that are statically optimized by Automatic Static Optimization will be hydrated without their route parameters provided, i.e query will be an empty object ({}).

  • After hydration, Next.js will trigger an update to your application to provide the route parameters in the query object.

like image 128
georgekrax Avatar answered Nov 04 '25 07:11

georgekrax


I solved it by using useLazyQuery instead of useQuery, and wrapped the function inside useEffect.

The problem was that NextJS's router.query returns an empty object on the first render and the actual object containing the query comes in at the second render.

This code works:

import React, { useEffect } from 'react';
import { useRouter } from 'next/router';
import styles from './CompanyId.module.css';

import { useLazyQuery } from '@apollo/client';
import { COMPANY_DETAILS } from '../../queries/company';

const CompanyDetails = () => {
  const router = useRouter();

  const [getCompany, { loading, data }] = useLazyQuery(COMPANY_DETAILS);

  useEffect(() => {
    if (router.query.companyId) {
      getCompany({ variables: { _id: router.query.companyId } });
    }
  }, [router.query]);

  if (loading) return <h1>Loading....</h1>;

  return (
    <div className={styles.container}>
      {data && <h1>{data.company.name}</h1>}
    </div>
  );
};

export default CompanyDetails;
like image 35
Aidenhsy Avatar answered Nov 04 '25 08:11

Aidenhsy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!