컴포넌트는 리액트의 중요한 콘셉트 중 하나예요. 컴포넌트는 사용자 인터페이스(UI)의 기초이기 때문에 리액트로의 여행을 시작하기 위한 최적의 장소예요.
이 페이지에서는
- 컴포넌트가 무엇인지
- 리액트 어플리케이션에서 컴포넌트가 어떤 역할을 수행하는지
- 첫 리액트 컴포넌트를 어떻게 작성하는지
를 알아볼 거예요.
Components: UI building blocks | 컴포넌트: UI를 빌드하는 블록
웹에서 HTML은 <h1>
이나 <li>
와 같이 내장된 태그로 풍부하고 구조화된 코드를 작성할 수 있어요.
<article>
<h1>My First Component</h1>
<ol>
<li>Components: UI Building Blocks</li>
<li>Defining a Component</li>
<li>Using a Component</li>
</ol>
</article>
이 마크업은 아티클인 <article>
, 헤딩인 <h1>
그리고 (요약된) 목록을 순서화된 리스트 <ol>
로 보여줘요. 스타일을 구성하는 CSS, 상호작용이 되도록 도와주는 자바스크립트와 결합된 이와 같은 마크업은 모든 사이드바, 아바타, 모달, 드롭다운과 같은 웹에서 보는 UI의 모든 조각의 뒷편에 있어요.
리액트는 마크업, CSS, 자바스크립트가 앱에서 재사용이 가능한 UI 엘리먼트인 커스텀된 "컴포넌트"를 결합해줘요. 위에서 본 목차 코드는 모든 페이지에서 렌더링 될 수 있는 <TableOfContents />
컴포넌트로 전환돼요. 그 안에서는 여전히 <article>
이나 <h1>
같은 HTML 태그를 사용하고 있어요.
HTML 태그와 같이 모든 페이지를 디자인하기 위해 컴포넌트를 구성하고, 순서를 짓고 그리고 중첩할 수 있어요. 예를 들어서 지금 읽고 있는 이 문서 페이지는 리액트 컴포넌트로 만들어졌어요.
<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">Docs</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>
프로젝트의 규모가 커질수록 많은 디자인이 개발 속도를 높여주는 이미 작성된 컴포넌트를 재사용하는 방법으로 구성된다는 것을 알게 될 거예요. 위의 콘텐츠 목차는 <TableOfContents />
로 어떤 화면에든 추가될 수 있어요! Chakra UI나 Material UI와 같은 리액트 오픈소스 커뮤니티에서 공유되는 수천개의 컴포넌트로 프로젝트에 활력을 불어넣을 수도 있어요.
Defining a component | 컴포넌트 정의하기
웹 페이지를 만들 때, 전통인 방법으로는 웹 개발자는 콘텐츠를 마크업으로 작성하고 자바스크립트로 뿌려진 상호작용을 추가했어요. 이것은 웹에서 상호작용이 있으면 좋을 때 잘 작동했어요. 이제는 많은 사이트와 어플에서 상호작용이 사용돼요. 리액트는 여전히 같은 기술을 사용하여 상호작용성을 먼저 추가해요. 리액트 컴포넌트는 마크업으로 뿌릴 수 있는 자바스크립트 함수예요. 컴포넌트가 어떻게 생겼는지 아래 예시에서 확인하세요. (원한다면 수정을 해볼 수도 있어요.)
이제 컴포넌트를 빌드하는 방법을 알아보아요.
Step 1: Export the Component | 컴포넌트 내보내기
export default
라는 접두사는 (리액트에만 특정된 것이 아닌) 자바스크립트 표준 문법이에요. 이 접두사는 파일의 주 함수를 표시해주어서 다른 파일에서 이 함수를 불러올 수(임포트할 수) 있게 도와줘요. (컴포넌트 불러오고 내보내기에서 불러오기에 대해 더 알아보세요!)
Step 2: Define the function | 함수 정의하기
function Profile() { }
을 사용해서 Profile
이라는 이름의 자바스크립트 함수를 정의하세요.
함정
리액트 컴포넌트는 일반적인 자바스크립트 함수지만 컴포넌트의 첫 글자는 대문자로 이루어져야만 해요. 그렇지 않다면 동작하지 않아요!
Step 3: Add markup | 마크업 추가하기
컴포넌트는 src
와 alt
속성을 가진 <img />
태그를 반환해요. <img />
는 HTML처럼 작성되었지만 실제로는 자바스크립트예요. 이러한 문법을 JSX라고 하고 이를 통해 자바스크립트 안에 마크업을 임베드할 수 있어요.
반환 구문은 아래 컴포넌트처럼 한 줄로 작성될 수 있어요.
return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;
그러나 만약 마크업이 return
키워드처럼 같은 라인에 있지 않다면 괄호로 감싸주어야 해요.
return (
<div>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</div>
);
함정
괄호가 없다면 return 이후의 모든 코드는 무시될 거예요.
Using a component | 컴포넌트 사용하기
이제 Profile
컴포넌트를 정의했고 다른 컴포넌트 안에 중첩할 수 있어요. 예를 들어, 여러개의 Profile
컴포넌트를 사용하는 Gallery
컴포넌트를 내보낼 수 있어요.
What the browser sees | 브라우저가 보는 것
대소문자에 따른 차이를 주목하세요.
<section>
은 소문자이기 때문에 리액트는 이 태그가 HTML 태그를 참조했다고 인지해요.<Profile />
은 대문자P
로 시작하기 때문에 리액트는Profile
이라는 컴포넌트를 사용하고 싶다는 사실을 알게 돼요.
그리고 Profile
은 <img />
와 같은 더 많은 HTML을 포함해요. 결론적으로 브라우저는 아래와 같은 코드를 읽게 돼요.
<section>
<h1>Amazing scientists</h1>
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
<img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />
</section>
Nesting and organizing components | 컴포넌트 중첩하고 조직하기
컴포넌트는 일반적인 자바스크립트 함수기 때문에 같은 파일에 여러개의 컴포넌트를 추가할 수 있어요. 이 특성은 컴포넌트가 비교적 작거나 서로 긴밀하게 연관되어 있을 때 편리해요. 만약 이 파일이 먼잡해지면 Profile
을 분리된 파일로 이동할 수 있어요. 불러오기(임포트)에 대한 페이지에서 어떻게하는지를 간단히 배울 수 있어요.
Profile
컴포넌트는 Gallery
안에서 렌더링 되기 때문에 Gallery
컴포넌트는 "자식"으로 각각의 Profile
컴포넌트를 렌더링하는 부모 컴포넌트라고 불러요. 이 부분이 리액트의 마법 같은 부분인데, 컴포넌트를 한 번 정의하면 원하는 곳에서 원하는 만큼 이 컴포넌트를 사용할 수 있어요.
함정
컴포넌트는 다른 컴포넌트에서 렌더링 될 수는 있지만 그들의 정의를 중첩할 수는 없어요.
export default function Gallery() { // 🔴 다른 컴포넌트 내부에서 컴포넌트를 정의하지 마세요! function Profile() { // ... } // ... }
위의 스니펫은 굉장히 느리고 버그를 발생시켜요. 대신, 모든 컴포넌트를 최상위에서 정의하세요.export default function Gallery() { // ... } // ✅최상위에서 컴포넌트를 정의하세요. function Profile() { // ... }
자식 컴포넌트가 부모 컴포넌트에게서 정보를 받아야할 필요가 있다면. 정의를 중첩하는 대신 prop으로 전달하세요.
모든 것은 컴포넌트다.
리액트 어플리케이션은 "루트" 컴포넌트에서 시작해요. 보통은 새 프로젝트를 시작하면 자동적으로 생성돼요. 예를 들어 만약 CodeSandbox나 Next.js라는 프레임워크를 사용할다면 루트 컴포넌트는 pages/index.js
에서 정의돼요. 예시들에서는 루트 컴포넌트를 내보냈어요.
대부분의 리액트 앱은 컴포넌트를 모든 곳에 사용해요. 이는 리액트가 버튼과 같이 재사용이 가능한 조각만을 컴포넌트로 사용한지 않고 사이드바, 목록, 그리고 궁극적으로는 한 페이지 자체와 같은 더 큰 조각들도 컴포넌트로 사용한다는 것을 의미해요. 컴포넌트는 한 번만 사용되더라도 UI 코드와 마크업을 조직하는 간편한 방법이에요.
리액트에 기반한 프레임워크는 이 방법을 사용해요. 빈 HTML 파일을 사용하고 리액트가 자바 스크립트로 페이지를 조직하는 것을 리액트로 "넘기는" 대신 리액트 컴포넌트에서 HTML을 자동적으로 생성하기도 해요. 이 방법은 자바스크립트 코드가 로딩되기 전에 컴포넌트가 앱에 보이도록 만들어줘요.
여전히 많은 웹사이트는 존재하는 HTML 페이지에 상호작용을 추가하기 위해 리액트만을 사용해요. 그들은 전체 페이지에 단일 루트 컴포넌트를 사용하는 대신 많은 루트 컴포넌트를 사용해요. 필요하다면 최대로 또는 최소로 리액트를 사용할 수 있어요.
Recap | 요약
이제 여러분은 리액트의 맛을 보았어요! 키 포인트 몇 개를 요약해보아요.
- 리액트는 앱에서 재사용 가능한 UI 요소인 컴포넌트를 생성해줘요.
- 리액트 앱에서 모든 UI는 컴포넌트에요.
- 리액트 컴포넌트는 일반적인 자바스크립트 함수지만 아래 부분은 달라요.
- 컴포넌트는 대문자로 시작해야만 해요.
- 컴포넌트는 JSX 마크업을 반환해요.
Challenges | 도전 과제
1. Export the component | 컴포넌트 추출하기
이 샌드박스는 루트 컴포넌트가 내보내지지 않았기 때문에 작동하지 않아요.
정답을 보기 전에 스스로 고쳐보세요!
아래와 같이 함수 정의 앞에 export default
를 추가하세요.
export
만을 작성하는 것만으로는 이 예시를 고치기에 충분하지 않은지 궁금할 거예요. 컴포넌트 불러오고 내보내기에서 export
와 export default
의 차이를 알아보세요.
2. Fix the return statement | 반환 구문 수정하기
이 return
구문에서는 무언가 이상해요. 고칠 수 있나요?
이 문제를 고치면서 "Unexpected Token"이라는 에러를 보게 될 거예요. 이 경우에는 닫는 괄호 뒤에 세미콜론이 있는지 살펴보세요. 세미콜론을 return ()
안에 남겨두면 에러가 발생해요.
아래와 같이 반환구문을 한 줄로 작성하세요.
또는 retun
오른쪽에 괄호를 열고 JSX 마크업으로 반환구문을 감싸세요.
3. Spot the mistake | 실수 찾아내기
Profile
컴포넌트를 전언하고 사용하는 방법에 문제가 있어요. 실수를 찾아낼 수 있나요? (리액트가 컴포넌트를 일반적인 HTML 태그와 어떻게 구분하는지를 생각해보세요!)
리액트 컴포넌트는 대문자로 시작해야만해요.
function profile()
을 function Profile()
로 변경하고 <profile>
을 <Profile>
로 바꾸세요.
4. Your own component | 여러분만의 컴포넌트를 만들어보세요.
스크래치에서 컴포넌트를 작성해보세요. 원하는유효한 이름을 부여할 수 있고 어떤 마크업도 반환할 수 있어요. 만약 아이디어가 없다면 <h1>잘했어요!</h1>
을 보여주는 Congratulations
컴포넌트를 작성해보세요. 내보내는 것(export)도 잊지 마세요!