컴포넌트 import 및 export 하기

컴포넌트의 가장 큰 장점은 재사용성으로 컴포넌트를 조합해 또 다른 컴포넌트를 만들 수 있다는 것입니다. 컴포넌트를 여러 번 중첩하게 되면 다른 파일로 분리해야 하는 시점이 생깁니다. 이렇게 분리하면 나중에 파일을 찾기 더 쉽고 재사용하기 편리해집니다.

학습 내용

  • Root 컴포넌트란
  • 컴포넌트를 import 하거나 export 하는 방법
  • 언제 default 또는 named imports와 exports를 사용할지
  • 한 파일에서 여러 컴포넌트를 import 하거나 export 하는 방법
  • 여러 컴포넌트를 여러 파일로 분리하는 방법

Root 컴포넌트란

첫 컴포넌트에서 만든 Profile 컴포넌트와 Gallery 컴포넌트는 아래와 같이 렌더링 됩니다.

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

이 예시의 컴포넌트들은 모두 App.js라는 root 컴포넌트 파일에 존재합니다. 설정에 따라 root 컴포넌트가 다른 파일에 위치할 수도 있습니다. Next.js처럼 파일 기반으로 라우팅하는 프레임워크일 경우 페이지별로 root 컴포넌트가 다를 수 있습니다.

컴포넌트를 import 하거나 export 하는 방법

랜딩 화면을 변경하게 되어 과학자들이 아니라 과학책으로 변경되거나 프로필 사진을 다른 곳에서 사용하게 된다면 Gallery 컴포넌트와 Profile 컴포넌트를 root 컴포넌트가 아닌 다른 파일로 옮기는 게 좋습니다. 그렇게 변경하면 재사용성이 높아져 컴포넌트를 모듈로 사용할 수 있습니다. 컴포넌트를 다른 파일로 이동하려면 세 가지 단계가 있습니다.

  1. 컴포넌트를 추가할 JS 파일을 생성합니다.
  2. 새로 만든 파일에서 함수 컴포넌트를 export 합니다. (default 또는 named export 방식을 사용합니다)
  3. 컴포넌트를 사용할 파일에서 import 합니다. (적절한 방식을 선택해서 default 또는 named로 import 합니다)

아래 예시를 보면 App.js 파일에서 ProfileGallery 컴포넌트를 빼서 새로운 Gallery.js 파일로 옮겼습니다. 이제 GalleryGallery.js에서 import 해서 사용할 수 있습니다.

import Gallery from './Gallery.js';

export default function App() {
  return (
    <Gallery />
  );
}

이제 이 예시에서는 컴포넌트들이 두 파일로 나뉘게 되었습니다.

  1. Gallery.js:
    • Profile 컴포넌트를 정의하고 해당 파일에서만 사용되기 때문에 export 되지 않습니다.
    • Default 방식으로 Gallery 컴포넌트를 export 합니다.
  2. App.js:
    • Default 방식으로 GalleryGallery.js로부터 import 합니다.
    • Root App 컴포넌트를 default 방식으로 export 합니다.

중요합니다!

가끔 .js와 같은 파일 확장자가 없을 때도 있습니다.

import Gallery from './Gallery';

React에서는 './Gallery.js' 또는 './Gallery' 둘 다 사용할 수 있지만 전자의 경우가 native ES Modules 사용 방법에 더 가깝습니다.

Deep Dive

Default와 Named Exports

보통 JavaScript에서는 default와 named export라는 두 가지 방법으로 값을 export 합니다. 지금까지의 예시에서는 default export만 사용했지만 두 방법 다 한 파일에서 사용할 수도 있습니다. 다만 한 파일에서는 하나의 default export만 존재할 수 있고 named export는 여러 개가 존재할 수 있습니다.

Default and named exports

Export 하는 방식에 따라 import 하는 방식이 정해져 있습니다. Default export로 한 값을 named import로 가져오려고 하려면 에러가 발생합니다. 아래 표에는 각각의 경우의 문법이 정리되어 있습니다.

SyntaxExport 구문Import 구문
Defaultexport default function Button() {}import Button from './button.js';
Namedexport function Button() {}import { Button } from './button.js';

Default import를 사용하는 경우 원한다면 import 단어 후에 다른 이름으로 값을 가져올 수 있습니다. 예를 들어 import Banana from './button.js' 라고 쓰더라도 같은 default export 값을 가져오게 됩니다. 반대로 named import를 사용할 때는 양쪽 파일에서 사용하고자 하는 값의 이름이 같아야 하기 때문에 named import라고 불립니다.

보편적으로 한 파일에서 하나의 컴포넌트만 export 할 때 default export 방식을 사용하고 여러 컴포넌트를 export 할 경우엔 named export 방식을 사용합니다. 어떤 방식을 사용하든 컴포넌트와 파일의 이름을 의미 있게 명명하는 것은 중요합니다. export default () => {} 처럼 이름 없는 컴포넌트는 나중에 디버깅하기 어렵기 때문에 권장하지 않습니다.

한 파일에서 여러 컴포넌트를 import 하거나 export 하는 방법

전체 갤러리가 아니라 하나의 Profile만 사용하고 싶을 때 Profile 컴포넌트만 export 하면 됩니다. 하지만 Gallery.js 파일에는 이미 하나의 default export가 존재하기 때문의 두 개의 default export를 정의할 수 없습니다. 이런 경우 새로운 파일 하나를 더 생성해서 default export를 사용하거나 named export로 Profile 컴포넌트를 export 할 수 있습니다. 한 파일에서는 단 하나의 default export만 사용할 수 있지만 named export는 여러 번 사용할 수 있습니다.

먼저 named export 방식을 사용해서 Gallery.js 파일에서 Profile 컴포넌트를 export 합니다. (default 키워드를 사용하지 않습니다)

export function Profile() {
// ...
}

그 다음엔 named import 방식으로 Gallery.js 파일에서 Profile 컴포넌트를 App.js 파일로 import 합니다. (중괄호를 사용합니다)

import { Profile } from './Gallery.js';

마지막으로 <Profile />App 컴포넌트에서 렌더링합니다.

export default function App() {
return <Profile />;
}

이제 Gallery.js에는 default Gallery export랑 named Profile export라는 두 가지의 export가 존재합니다. App.js에서는 두 컴포넌트를 import 해서 사용합니다. 아래의 예시에서 <Profile /><Gallery />를 교차해서 사용해 보세요.

import Gallery from './Gallery.js';
import { Profile } from './Gallery.js';

export default function App() {
  return (
    <Profile />
  );
}

이제 default와 named export 방식 둘 다 사용할 수 있게 됐습니다.

  • Gallery.js:
    • Named export 방식으로 Profile이라는 이름의 컴포넌트를 export 합니다.
    • Default export 방식으로 Gallery 컴포넌트를 export 합니다.
  • App.js:
    • Gallery.js에서 named import 방식으로 Profile 컴포넌트를 import 합니다.
    • Gallery.js에서 default import 방식으로 Gallery 컴포넌트를 import 합니다.
    • Default export 방식으로 App 컴포넌트를 export 합니다.

요약

이 페이지에서 배우게 된 것들입니다.

  • Root 컴포넌트란 무엇인지
  • 컴포넌트를 import 하거나 export 하는 방법
  • 언제 default 또는 named imports와 exports를 사용할지
  • 한 파일에서 여러 컴포넌트를 export 하는 방법

챌린지 1 of 1:
컴포넌트를 한 단계 더 분리하기

현재 Gallery.js 파일이 ProfileGallery를 둘 다 export 해서 헷갈리게 할 수 있습니다.

Profile.js 파일을 생성해서 Profile 컴포넌트를 해당 파일로 옮기고 App 컴포넌트에서는 <Profile /><Gallery />를 각각 렌더링하도록 변경합니다.

Default 또는 named export를 사용해서 Profile을 export 할 수 있습니다. 다만 주의할 점은 사용한 export 방식에 맞는 import 문법을 사용해야 한다는 점입니다. 아래 문법 표는 위 deep dive에서 인용했습니다.

SyntaxExport 구문Import 구문
Defaultexport default function Button() {}import Button from './button.js';
Namedexport function Button() {}import { Button } from './button.js';
// Move me to Profile.js!
export function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

Export 방식 중 하나를 사용했으면 다른 방식으로도 동작하게 시도해 보세요.