Next.js의 dynamic 함수를 사용하여 동적 컴포넌트를 로드할 때 발생하는 문제와 그 원인을 분석해보겠습니다. 이 글에서는 두 가지 방식의 차이점과 이를 사용하는 방법에 대해 설명합니다.
오랜시간 삽질해서 결국 원인을 찾았습니다.
에러로그 등이 없기 때문에 원인 분석이 어려운 관계로 여러분의 시간절약을 위해 포스팅합니다.
혹시라도 제 해석이 틀리거나 분석된 다른 명확한 원인을 보신분은 댓글로 공유 부탁드립니다.
아래 코드와 같이 첫번째 인자를 객체 지정 시, loader 필드에 로더를 할당할 수 있습니다.
두번째는 () => 함수 호출로 로더컴포넌트 직접 할당할 수 있습니다.
두 방식의 동작 매커니즘이 달라서 객체로 할당 시 렌더링 문제가 발생합니다.
export default function dynamic<P = {}>
(
dynamicOptions: DynamicOptions<P> | Loader<P>,
options?: DynamicOptions<P>
): React.ComponentType<P>;
export type DynamicOptions<P = {}> = LoadableGeneratedOptions & {
loading?: (loadingProps: DynamicOptionsLoadingProps) => JSX.Element | null;
loader?: Loader<P> | LoaderMap;
loadableGenerated?: LoadableGeneratedOptions;
ssr?: boolean;
/**
* @deprecated `suspense` prop is not required anymore
*/
suspense?: boolean;
};
export declare type Loader<P = {}> = (() => LoaderComponent<P>) | LoaderComponent<P>;
옵션 객체를 사용하는 방식
const DynamicMapPage = dynamic({
loader: () => import('./components/Map'),
ssr: false
});
단순한 함수 호출 방식
const DynamicMapPage = dynamic(() => import('./components/Map'), { ssr: false });
두 방식 간의 차이점은 dynamic 함수의 첫 번째 인자를 해석하는 방식에서 발생합니다.
옵션 객체 방식 (DynamicOptions):
loader와 ssr 옵션을 포함한 객체를 해석하여 컴포넌트를 로드합니다.loader가 비동기 함수로 실행되고, ssr 옵션이 적용되는 과정에서 문제가 발생할 수 있습니다.단순 함수 방식 (Loader):
loader 함수와 ssr 옵션의 처리 순서:
loader 함수와 ssr 옵션이 함께 객체로 전달되기 때문에, Next.js가 이를 해석하여 처리하는 과정에서 비동기 로드와 SSR 비활성화 설정이 충돌할 가능성이 있습니다.ssr 옵션이 비동기 로드 함수와 동시에 처리되는 방식이 Next.js 내부에서 제대로 처리되지 않을 수 있습니다.Next.js 내부 처리 로직의 차이:
dynamic 함수의 두 가지 형태를 다르게 처리합니다. 단순 함수 형태는 보다 직접적이고 단순한 반면, 객체 형태는 더 복잡한 내부 처리가 필요합니다.Next.js 공식 문서에서도 두 가지 방식의 사용을 설명하지만, 단순 함수 방식이 더 일반적이고 권장되는 방식입니다. 공식 문서에서도 일부 옵션과의 조합이 제대로 작동하지 않을 수 있음을 언급합니다.
따라서, 문제가 발생하지 않는 단순 함수 방식으로 사용하는 것이 권장됩니다. 이는 Next.js 내부의 비동기 로드 처리 로직과 관련된 문제를 피할 수 있기 때문입니다.