【Next.js】Dynamic Import를 사용하여 SSR을 피하는 방법

9385 단어 Reactnext.js

개요



Next.js에서 코드를 작성할 때 이러한 오류를 본 적이 있습니까?Warning XXX did not match. Server: XXX Client XXX이 오류는 서버와 클라이언트에서 렌더링 결과가 다른 경우에 발생합니다. Next.js는 빌드시 (SSG 프로덕션 환경) 또는 요청시 (SSG 개발 환경, SSR)에 서버 측에서 사전 렌더링 (Pre-rendering)이 이루어지고 서버 측에서 코드가 실행됩니다. 처리가 실행됩니다. 그 때의 처리의 렌더링 결과가 다른 경우에는 상기의 에러가 됩니다
이 경우 서버와 클라이언트의 렌더링 결과를 동일하게 하면 되지만, 어쩔 수 없는 경우가 있습니다. 그때는 Dynamic Import를 사용하여 SSR을 피하고 CSR로 만드는 방법이 있습니다.
그러면, 현재 시각을 취득하는 프로그램을 작성해, 이 에러를 일부러 발생시켜 설명해 갑니다

주제



현재 시간을 얻는 프로그램



index.jsx
import { useState } from 'react';

const index = () => {
  const now = new Date();
  const [hour, setHour] = useState(now.getHours());
  const [min, setMin] = useState(now.getMinutes());
  const [sec, setSec] = useState(now.getSeconds());
  setInterval(() => {
    const now = new Date();
    setHour(now.getHours());
    setMin(now.getMinutes());
    setSec(now.getSeconds());
  }, 1000);

  return (
    <div>
      {hour}{min}{sec}</div>
  );
};

export default index;


오류 화면




이렇게 매번 오류가 실행되는 것은 아닙니다. 서버와 클라이언트의 렌더링이 같은 경우도 생각할 수 있습니다 (초수가 같다)
처음 발생한 오류 로그는Warning Text content did not match. Server: 30 Client 31이는 30초 동안 서버 측에서 렌더링되고 31초 동안 클라이언트 측에서 렌더링되었기 때문에 발생한 오류입니다. 실제로 30초 때 다시 로드하는 것을 알 수 있다고 생각합니다.

이 프로그램을 지금부터 다시 작성하겠습니다.

오류를 수정한 프로그램



Dynamic Import



Dynamic Import를 사용하여 SSR을 피하고 CSR로 만드는 프로그램입니다.

index.jsx
import dynamic from 'next/dynamic';

const index = () => {
  const DynamicComponentWithNoSSR = dynamic(() => import('../components/Timer'), {
    ssr: false,
  });

  return <DynamicComponentWithNoSSR />;
};

export default index;


components/Timer.jsx
import { useState } from 'react';

const Timer = () => {
  const now = new Date();
  const [hour, setHour] = useState(now.getHours());
  const [min, setMin] = useState(now.getMinutes());
  const [sec, setSec] = useState(now.getSeconds());
  setInterval(() => {
    const now = new Date();
    setHour(now.getHours());
    setMin(now.getMinutes());
    setSec(now.getSeconds());
  }, 1000);
  return (
    <div>
      {hour}{min}{sec}</div>
  );
};

export default Timer;

이제 여러 번 다시로드를 눌러도 오류가 실행되지 않는 것을 확인할 수 있다고 생각합니다.
이제 Timer.jsx 내의 처리는 클라이언트 전용 처리입니다.

수정 후 데모 화면





결론



뭔가 다른 좋은 방법 알고있는 사람이 있으면 코멘트에서 가르쳐 주시면 기쁩니다

참고



Dynamic Import

좋은 웹페이지 즐겨찾기