Почему router.запрос возвращает пустой объект в NextJS при первом рендеринге?

#javascript #next.js

#javascript #next.js

Вопрос:

Мой URL: http://localhost:3000/company/60050bd166cb770942b1dadd

Я хочу получить значение идентификатора с помощью router.запрос. Однако, когда я консольный лог-маршрутизатор.запрос сначала возвращает пустой объект, а затем возвращает объект с данными. Это приводит к ошибкам в других частях моего кода, поскольку мне нужно значение идентификатора для извлечения других данных.

Журнал консоли

Это мой код:

 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;
 

Моя программа вылетает прямо сейчас, потому что переменная CompanyID пуста при первом рендеринге. Есть ли способ обойти эту проблему?

Комментарии:

1. Попробуйте обернуть вашу функцию выборки внутрь usetEffect и использовать useLazyQuery вместо этого, а затем обновить состояние с помощью useState

2. @Nico спасибо за ваш вклад, я попробовал это с помощью useLazyQuery вместе с useEffect, и это работает 🙂

Ответ №1:

Я решил это, используя useLazyQuery вместо useQuery и обернул функцию внутри useEffect.

Проблема заключалась в том, что маршрутизатор NextJS.запрос возвращает пустой объект при первом рендеринге, а фактический объект, содержащий запрос, появляется при втором рендеринге.

Этот код работает:

 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 amp;amp; <h1>{data.company.name}</h1>}
    </div>
  );
};

export default CompanyDetails;
 

Комментарии:

1. Использование router.query здесь не кажется оптимальным, поскольку оно изменяется несколько раз при повторном рендеринге. Таким образом, у вас будет useEffect бесконечное выполнение. router.isReady является ли подходящей переменной для использования, поскольку она является логическим значением и изменяет только одну гидратацию страницы post.

Ответ №2:

В Next.js:

  • Страницы, которые статически оптимизированы с помощью автоматической статической оптимизации, будут гидратированы без предоставления их параметров маршрута, т.е. query Будут пустым объектом ({}) .
  • После гидратации, Next.js вызовет обновление вашего приложения для предоставления параметров маршрута в query объекте.