컴포넌트의 가장 큰 장점은 재사용성으로 컴포넌트를 조합해 또 다른 컴포넌트를 만들 수 있다는 것입니다. 컴포넌트를 여러 번 중첩하게 되면 다른 파일로 분리해야 하는 시점이 생깁니다. 이렇게 분리하면 나중에 파일을 찾기 더 쉽고 재사용하기 편리해집니다.
학습 내용
- Root 컴포넌트란
- 컴포넌트를 import 하거나 export 하는 방법
- 언제 default 또는 named imports와 exports를 사용할지
- 한 파일에서 여러 컴포넌트를 import 하거나 export 하는 방법
- 여러 컴포넌트를 여러 파일로 분리하는 방법
Root 컴포넌트란
첫 컴포넌트에서 만든 Profile
컴포넌트와 Gallery
컴포넌트는 아래와 같이 렌더링 됩니다.
Error
Extra 185 of 186 byte(s) found at buffer[1]
이 예시의 컴포넌트들은 모두 App.js
라는 root 컴포넌트 파일에 존재합니다. 설정에 따라 root 컴포넌트가 다른 파일에 위치할 수도 있습니다. Next.js처럼 파일 기반으로 라우팅하는 프레임워크일 경우 페이지별로 root 컴포넌트가 다를 수 있습니다.
컴포넌트를 import 하거나 export 하는 방법
랜딩 화면을 변경하게 되어 과학자들이 아니라 과학책으로 변경되거나 프로필 사진을 다른 곳에서 사용하게 된다면 Gallery
컴포넌트와 Profile
컴포넌트를 root 컴포넌트가 아닌 다른 파일로 옮기는 게 좋습니다. 그렇게 변경하면 재사용성이 높아져 컴포넌트를 모듈로 사용할 수 있습니다. 컴포넌트를 다른 파일로 이동하려면 세 가지 단계가 있습니다.
- 컴포넌트를 추가할 JS 파일을 생성합니다.
- 새로 만든 파일에서 함수 컴포넌트를 export 합니다. (default 또는 named export 방식을 사용합니다)
- 컴포넌트를 사용할 파일에서 import 합니다. (적절한 방식을 선택해서 default 또는 named로 import 합니다)
아래 예시를 보면 App.js
파일에서 Profile
과 Gallery
컴포넌트를 빼서 새로운 Gallery.js
파일로 옮겼습니다. 이제 Gallery
는 Gallery.js
에서 import 해서 사용할 수 있습니다.
import Gallery from './Gallery.js'; export default function App() { return ( <Gallery /> ); }
Error
Extra 185 of 186 byte(s) found at buffer[1]
이제 이 예시에서는 컴포넌트들이 두 파일로 나뉘게 되었습니다.
Gallery.js
:Profile
컴포넌트를 정의하고 해당 파일에서만 사용되기 때문에 export 되지 않습니다.- Default 방식으로
Gallery
컴포넌트를 export 합니다.
App.js
:- Default 방식으로
Gallery
를Gallery.js
로부터 import 합니다. - Root
App
컴포넌트를 default 방식으로 export 합니다.
- Default 방식으로
Deep Dive
보통 JavaScript에서는 default와 named export라는 두 가지 방법으로 값을 export 합니다. 지금까지의 예시에서는 default export만 사용했지만 두 방법 다 한 파일에서 사용할 수도 있습니다. 다만 한 파일에서는 하나의 default export만 존재할 수 있고 named export는 여러 개가 존재할 수 있습니다.
Export 하는 방식에 따라 import 하는 방식이 정해져 있습니다. Default export로 한 값을 named import로 가져오려고 하려면 에러가 발생합니다. 아래 표에는 각각의 경우의 문법이 정리되어 있습니다.
Syntax | Export 구문 | Import 구문 |
---|---|---|
Default | export default function Button() {} | import Button from './button.js'; |
Named | export 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 합니다.
- Named 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
파일이 Profile
과 Gallery
를 둘 다 export 해서 헷갈리게 할 수 있습니다.
Profile.js
파일을 생성해서 Profile
컴포넌트를 해당 파일로 옮기고 App
컴포넌트에서는 <Profile />
과 <Gallery />
를 각각 렌더링하도록 변경합니다.
Default 또는 named export를 사용해서 Profile
을 export 할 수 있습니다. 다만 주의할 점은 사용한 export 방식에 맞는 import 문법을 사용해야 한다는 점입니다. 아래 문법 표는 위 deep dive에서 인용했습니다.
Syntax | Export 구문 | Import 구문 |
---|---|---|
Default | export default function Button() {} | import Button from './button.js'; |
Named | export 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 방식 중 하나를 사용했으면 다른 방식으로도 동작하게 시도해 보세요.