Как вызвать getServerSideprops с помощью useEffect в Next.js

#reactjs #react-hooks #next.js

#reactjs #реагирующие крючки #next.js

Вопрос:

Я создаю проект, используя next.js но у меня есть проблема, связанная с тем, что getServerSideProps вызывается 6 раз при рендеринге страницы.

Вот код в верхней части страницы.

 const NewFindstay: React.FC<INewFindstayProps> = ({ findstayList }) => {
  const [isMap, setIsMap] = useState(false);
  return (
    <div id="contents">
      <FindstayFilter setIsMap={setIsMap} isMap={isMap} />
      <FindstayList findstayList={findstayList} isMap={isMap} />
    </div>
  );
};

export async function getServerSideProps({ query, req }) {
  let findstayList = null;
  try {
    findstayList = await getPlaceListAsync(
      { ...query },
      req.headers.cookie ? req.headers.cookie : null
    );
  } catch (e) {
    findstayList = null;
  }
  return {
    props: {
      findstayList,
      query,
    },
  };
}

export default NewFindstay;
 

Кажется, это вызвано компонентами, которые импортированы внутри FindstayFilter. (допустим, компоненты A, B, C, D, E, F)

Каждый компонент A, B, C, D, E, F имеет хук useEffect для setState .

 // A
 useEffect(() => {
    if (router.query.city) {
      setSelectedCity(router.query.city);
    };
  }, [router.query.city]);

// B
  useEffect(() => {
    setDateRange({
      startDate: check_in ? moment(check_in) : null,
      endDate: check_out ? moment(check_out) : null
    })
  }, [router.query.check_in, router.query.check_out]);
// C
  useEffect(() => {
    const queryPrice = {
      min: price_min ? (parseInt(price_min as string, 10) / 10000) : 0,
      max: price_max ? (parseInt(price_max as string, 10) / 10000) : 100
    }
    setRangePrice(queryPrice);
  }, [router.query.price_min, router.query.price_max]);

// D, E, F use same pattern as well.
 

Другими словами, когда компонент FindstayFilter выполняет рендеринг, useEffect hook внутри A, B, C, D, E, F повторно отображает компонент всего 6 раз, что также вызывает вызов getServerSideProps 6 раз.

Как я могу минимизировать вызов getServerSideProps? должен ли я использовать хук useEffect только внутри компонента FindstayFilter и набивать много кода setstate в хук?

Ответ №1:

getServerSideProps вызывается только при первой загрузке страницы, потому что он вызовет сервер nodejs nextjs. Это всегда будет иметь место, независимо от того, что, если вы не выполните перезагрузку / обновление страницы. https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering

Ответ №2:

Я нашел, что было не так.

Я помещаю хук useEffect с состоянием массива зависимостей внутри в каждый компонент, чтобы при каждом изменении состояний router.push работал.

   const pushRouter = (renderQuery) => {
    return (
      router.push({
        pathname: "/findstay",
        query: {
          ...router.query,
          ...renderQuery,
          page: 1,
          per: 10
        }
      })
    );
  };

  useEffect(() => {
    const queryCnt = {
      adultCnt: adult_cnt ? parseInt(adult_cnt as string, 10) : 0,
      childCnt: child_cnt ? parseInt(child_cnt as string, 10) : 0,
      babyCnt: baby_cnt ? parseInt(baby_cnt as string, 10) : 0
    };
    pushRouter(queryCnt)
  }, [adult_cnt, child_cnt, baby_cnt]);
 

Однако router.push работает как ssr в моем коде (предполагается, что он работает как csr), что означает, что при рендеринге FindstayFilter функция pushRouter в дочерних компонентах A, B, C, D, E, F также работает, и это приводит к рендерингу getServerSideProps 6 раз.

Теперь я должен найти причину, по которой router.push работает ssr https://github.com/vercel/next.js/issues/9586