DEV Community

Cover image for Named export를 동적 import() 호출하기
Heetae Kim
Heetae Kim

Posted on • Updated on

Named export를 동적 import() 호출하기

필자는 프로젝트를 진행하면서 page 컴포넌트를 default export 방식으로 컴포넌트를 내보내어 코드를 작성하였다.

// Component default export
function MyPage () => { ... }
export default MyPage;

// Component import
import MyPage from './pages/MyPage';
Enter fullscreen mode Exit fullscreen mode

페이지 컴포넌트에 default export로 굳어진 습관도 무시할 수 없지만, 페이지는 단 한개의 페이지 컴포넌트 뷰의 기능을 담당해야 하기 때문에 default로 작성하였다.

그러나 default export 의 단점으로 import 하는 과정에서 휴먼 에러가 발생할 수 있다는 단점과 import 코드 라인이 늘어나는 단점이 존재하기 때문에 이번에는 named export를 통해 컴포넌트를 export 하였다.

// Component named export
export const MyPage= () => { ... }

// Component import
import { MyPage } from './pages';
Enter fullscreen mode Exit fullscreen mode

named export로 변경 후 import 하는 과정에서 자동으로 컴포넌트 name을 선언해 주며, 여러 export된 컴포넌트 및 함수를 name으로 import 할 수 있는 장점이 생겼다.

 

React.lazy로 import

각 페이지 컴포넌트를 최적화 하기 위해 React.lazy 를 사용하여 동적으로 컴포넌트를 import 하였다.

React v16.6.0의 외부 라이브러리 없이 코드 분할을 할 수 있는 React.lazy를 도입하였다.
react.dev-lazy

즉, React.lazy 함수는 동적 import를 일반 컴포넌트처럼 렌더링할 수 있게 해준다.

Before:

import { MyPage } from './pages';

function AppComponent() {
  return (
    <div>
      <MyPage />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

After:

const MyPage = React.lazy(() => import('./pages/MyPage'));

function AppComponent() {
  return (
    <div>
      <MyPage />
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

그리고 바로 다음에서 문제가 발생, 아래에 다음과 같은 메시지가 있다.

React.lazy takes a function that must call a dynamic import(). 
This must return a Promise which resolves to a module with a default export containing a React component.
Enter fullscreen mode Exit fullscreen mode

번역하면 이렇다.

React.lazy는 동적 import()를 호출하는 함수를 받습니다. 이 함수는 React 컴포넌트를 포함하는 default export 모듈로 해석되는 Promise를 반환해야 합니다.

그래서 아래와 같이 변경하라고 한다.

function MyPage () => { ... }
export default MyPage;
Enter fullscreen mode Exit fullscreen mode

 

해결방법

하지만 default export로 export 하지 않는다면 어떻게 해야 할까 고민 중에 ChatGPT를 통해 그 답을 얻을 수 있었으며 이 경우, 컴포넌트를 가져올 때 import() 코드를 약간 변경해야 한다.

const MyPage = React.lazy(
  () => import('./pages/MyPage/index.tsx').then((module) => ({ default: module.MyPage }))
);
Enter fullscreen mode Exit fullscreen mode

필자는 MyPage라는 폴더를 두고 그 안에 index.tsx 파일로 컴포넌트를 생성해 주었다. 그리고 중요한 점은 확장자 명을 반드시 붙여 주어야 한다.

정리하자면 import()가 반환하는 Promise에 체이닝을 추가하여 default export를 추가하는 작업을 하고 있는 것이다.

이렇게 React.lazy로 가져온 named export된 컴포넌트의 경우 위와 같은 형식으로 lazy 함수를 작성해 주어야 한다.

그리고 기억해야 할 것으로 React.lazy로 가져온 컴포넌트는 반드시 React.Suspense 안에서 렌더링 되어야 한다는 점을 기억해야 한다.

최종적으로 변경된 전체 코드는 아래와 같다.

const MyPage = React.lazy(
  () => import('./pages/MyPage/index.tsx').then((module) => ({ default: module.MyPage }))

function AppComponent() {
  return (
    <div>
      <Suspense fallback="loading..." />
        <MyPage />
      <Suspense/>
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)