첫 번째 컴포넌트

컴포넌트는 React의 핵심 개념 중 하나입니다. 컴포넌트는 사용자 인터페이스(UI)를 구축하는 기반이 되므로 React 여정을 시작하기에 완벽한 곳입니다!

학습 내용

  • 컴포넌트가 무엇일까
  • React 애플리케이션에서 컴포넌트의 역할
  • 첫 번째 React 컴포넌트를 작성하는 방법

컴포넌트: 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, 상호작용을 위한 JavaScript와 결합하여 웹에서 볼 수 있는 모든 사이드바, 아바타, 모달, 드롭다운 등 모든 UI의 기반이 됩니다.

React를 사용하면 마크업, CSS, JavaScript를 앱의 재사용 가능한 UI 요소인 사용자 정의 “컴포넌트”로 결합할 수 있습니다. 위에서 본 목차 코드는 모든 페이지에 렌더링할 수 있는 <TableOfContents /> 컴포넌트로 전환될 수 있습니다. 내부적으로는 여전히 <article>, <h1> 등과 같은 동일한 HTML태그를 사용합니다.

HTML 태그와 마찬가지로 컴포넌트를 작성, 순서 지정 및 중첩하여 전체 페이지를 디자인할 수 있습니다. 예를 들어, 여러분이 읽고 있는 문서 페이지는 React 컴포넌트로 구성되어 있습니다.

<PageLayout>
<NavigationHeader>
<SearchBar />
<Link to="/docs">Docs</Link>
</NavigationHeader>
<Sidebar />
<PageContent>
<TableOfContents />
<DocumentationText />
</PageContent>
</PageLayout>

프로젝트가 성장함에 따라 이미 작성한 컴포넌트를 재사용하여 많은 디자인을 구성할 수 있으므로 개발 속도가 빨라집니다. 위의 목차는 <TableOfContents />를 사용하여 어떤 화면에도 추가할 수 있습니다! Chakra UI, Material UI.와 같은 React 오픈 소스 커뮤니티에서 공유되는 수천 개의 컴포넌트로 프로젝트를 빠르게 시작할 수도 있습니다.

컴포넌트 정의하기

기존에는 웹 페이지를 만들 때 웹 개발자가 컨텐츠를 마크업한 다음 JavaScript를 뿌려 상호작용을 추가했습니다. 이는 웹에서 상호작용이 중요했던 시절에 효과적이였습니다. 이제는 많은 사이트와 모든 앱에서 상호작용을 기대합니다. React는 동일한 기술을 사용하면서도 상호작용을 우선시합니다. React 컴포넌트는 마크업으로 뿌릴 수 있는 JavaScript 함수입니다. 그 모습은 다음과 같습니다.(아래 예시는 편집할 수 있습니다.)

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

컴포넌트를 빌드하는 방법은 다음과 같습니다.

1단계: 컴포넌트 내보내기

export default 접두사는 표준 JavaScript 구문입니다(React에만 해당되지 않습니다). 이 접두사를 사용하면 나중에 다른 파일에서 가져올 수 있도록 파일에 주요 기능을 표시할 수 있습니다. (더 자세한 내용은 컴포넌트 Importing 및 Exporting을 참고하세요!)

2단계: 함수 정의하기

function Profile() { }을 사용하면 Profile이라는 이름의 JavaScript함수를 정의할 수 있습니다.

주의하세요!

React 컴포넌트는 일반 JavaScript 함수이지만, 이름은 대문자로 시작해야 하며 그렇지 않으면 작동하지 않습니다!

3단계: 마크업 추가하기

이 컴포넌트는 srcalt 속성을 가진 <img /> 태그를 반환합니다. <img />는 HTML처럼 작성되었지만 실제로는 JavaScript입니다! 이 구문을 JSX라고 하며, JavaScript 안에 마크업을 삽입할 수 있습니다.

반환문은 이 컴포넌트에서처럼 한 줄에 모두 작성할 수 있습니다.

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 뒷 라인에 있는 모든 코드가 무시됩니다!

컴포넌트 사용하기

이제 Profile 컴포넌트를 정의했으므로 다른 컴포넌트 안에 중첩할 수 있습니다. 예를 들어 여러 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>
  );
}

브라우저에 표시되는 내용

대소문자의 차이에 주목하세요.

  • <section>은 소문자이므로 React는 HTML태그를 가리킨다고 이해합니다.
  • <Profile />은 대문자 p로 시작하므로 React는 Profile이라는 컴포넌트를 사용하고자 한다고 이해합니다.

그리고 Profile은 더 많은 <img />가 포함되어 있습니다. 결국 브라우저에 표시되는 내용은 다음과 같습니다.

<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>

컴포넌트 중첩 및 구성

컴포넌트는 일반 JavaScript함수이므로 같은 파일에 여러 컴포넌트를 포함할 수 있습니다. 컴포넌트가 상대적으로 작거나 서로 밀접하게 관련되어 있을 때 편리합니다. 이 파일이 복잡해지면 언제든지 Profile을 별도의 파일로 옮길 수 있습니다. 이 방법은 바로 다음 챕터인 컴포넌트의 importing과 exporting 페이지에서 확인할 수 있습니다.

Profile 컴포넌트는 Gallery안에서 렌더링되기 때문에(심지어 여러번 렌더링됩니다!), Gallery는 각 Profile을 “자식”으로 렌더링하는 부모 컴포넌트라고 말할 수 있습니다. 컴포넌트를 한 번 정의한 다음 원하는 곳에서 원하는 만큼 여러 번 사용할 수 있다는 점이 바로 React의 마법입니다.

주의하세요!

컴포넌트는 다른 컴포넌트를 렌더링할 수 있지만, 그 정의를 중첩해서는 안 됩니다.

export default function Gallery() {
// 🔴 절대 컴포넌트 안에 다른 컴포넌트를 정의하면 안 됩니다!
function Profile() {
// ...
}
// ...
}

위 스니펫은 매우 느리고 버그를 촉발합니다. 대신 최상위 레벨에서 컴포넌트를 정의하세요.

export default function Gallery() {
// ...
}

// ✅ 최상위 레벨에서 컴포넌트를 선언합니다
function Profile() {
// ...
}

자식 컴포넌트에 부모 컴포넌트의 일부 데이터가 필요한 경우, 정의를 중첩하는 대신 props로 전달하세요.

Deep Dive

컴포넌트의 모든 것

React 애플리케이션은 “root”컴포넌트에서 시작됩니다. 보통 새 프로젝트를 시작할 때 자동으로 생성됩니다. 예를 들어, CodeSandbox 또는 Next.js를 사용하는 경우, root 컴포넌트는 pages/index.js에 정의됩니다. 이 예제에서는 root 컴포넌트를 내보내고 있습니다.

대부분의 React 앱은 모든 부분에서 컴포넌트를 사용합니다. 즉, 버튼과 같이 재사용 가능한 부분뿐만 아니라 사이드바, 목록, 그리고 궁극적으로 전체 페이지와 같은 큰 부분에도 컴포넌트를 사용하게 됩니다! 컴포넌트는 한 번만 사용되더라도 UI 코드와 마크업을 정리하는 편리한 방법입니다.

React 기반 프레임워크들은 이를 한 단계 더 발전시킵니다. 빈 HTML파일을 사용하고 React가 JavaScript로 페이지 관리를 “다룰 수 있게” 하도록 하는 대신, React 컴포넌트에서 HTML을 자동으로 생성하기도합니다. 이를 통해 JavaScript 코드가 로드되기 전에 앱에서 일부 컨텐츠를 표시할 수 있습니다.

그렇지만 여전히 많은 웹사이트들은 React를 약간의 상호작용을 추가하는 용도로만 사용합니다. 이러한 웹사이트에는 전체 페이지에 하나의 root 컴포넌트가 아닌 여러 개의 root 컴포넌트가 있습니다. 필요한 만큼 React를 많이 또는 적게 사용할 수 있습니다.

요약

이제 막 React를 처음 사용해 보았습니다! 몇 가지 핵심 사항을 요약해 보겠습니다.

  • React를 사용하면 앱의 재사용 가능한 UI 요소인 컴포넌트를 만들 수 있습니다.

  • React 앱에서 모든 UI는 컴포넌트입니다.

  • React 컴포넌트는 다음 몇 가지를 제외하고는 일반적인 JavaScript 함수입니다.

    1. 컴포넌트의 이름은 항상 대문자로 시작합니다.
    2. JSX 마크업을 반환합니다.

챌린지 1 of 4:
컴포넌트 내보내기

root 컴포넌트를 내보내지 않았기 때문에 이 샌드박스는 작동하지 않습니다.

function Profile() {
  return (
    <img
      src="https://i.imgur.com/lICfvbD.jpg"
      alt="Aklilu Lemma"
    />
  );
}

정답을 확인하기 전에 직접 해결해 보세요