UI 표현하기 - 첫 번째 컴포넌트 (컴포넌트란 무엇인가?)

PYM·2024년 5월 16일
0

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

학습 내용

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

컴포넌트란?

간단히 말하면 UI 구성요소 (사이드바, 모달, 드롭다운, 버튼 등)이다.

React를 사용하면 마크업, CSS, JS를 앱의 재사용 가능한 UI 요소인 사용자 정의 "컴포넌트"로 결합할 수 있다.

아래 코드는 일반적인 HTML 마크업 코드이다.

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

위 코드는 목차를 나타내는 코드로 React에서는 이를 모든 페이지에 렌더링 가능한 (즉, 재사용이 가능한) <TableOfContents /> 컴포넌트로 만들 수 있다.

즉 위 article, h1, ol ,li 등의 HTML태그를 <TableOdContents /> 라는 하나의 덩어리로 묶어서 전체 UI의 한 부분에 배치할 수 있도록 한 게 컴포넌트이다.

이렇게 만든 컴포넌트는 모든 페이지에서 사용이 가능하다. 즉, 재사용할 수 있기 때문에 개발 속도가 빨라진다.

컴포넌트는 React의 핵심 개념으로, React로 개발한 페이지는 여러개의 컴포넌트들로 구성이 되어있다고 볼 수 있다.

컴포넌트를 빌드하는 방법

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

export default 접두사를 사용해서 컴포넌트를 내보낸다. 이렇게 하면 다른 파일에서 해당 컴포넌트를 import 해서 하나의 HTML 태그처럼 사용할 수 있다.

2단계: 함수 정의하기

function Profile () {} 
// or 
const Profile = () => {}

Profile이라는 컴포넌트를 만들기 위해서는 Profile이라는 JS 함수하나를 정의한다. 이 함수 내부에서 JS와 마크업을 작성하게 된다.

주의점: React 컴포넌트는 일반 JS 함수이지만, 이름은 대문자로 시작해야 한다. (필수)

3단계: 마크업 추가하기

해당 컴포넌트가 Profile 컴포넌트로 img 태그를 반환한다고 한다면, 아래처럼 작성할 수 있다.
이는 HTML처럼 보이지만, 실제로는 JavaScript이다. 이러한 구문을 JSX라고 하며, JS안에 마크업을 삽입할 수 있다.

return <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" />;

// 만약 마크업이 모두 return 과 같은 라인에 있지 않다면, 괄호로 묶어야 한다.
// 🚨 괄호가 없다면, return 의 뒷 라인에 있는 모든 코드가 무시된다. 

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

컴포넌트 사용하기

// 프로필 사진을 반환하는 Profile 컴포넌트
function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

// h1 제목과 프로필 사진 3장을 반환하는 Gallery 컴포넌트
export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

위 코드에서 알 수 있듯, 컴포넌트로 정의한 Profile을 다른 컴포넌트인 Gallery 안에 중첩할 수 있다.

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>

태그의 대소문자의 의미

  • <section>은 시작 문자가 소문자. 이때 리액트는 이 태그가 HTML태그라고 판단한다.
  • <Profile />은 시작 문자가 대문자. 이때 리액트는 사용자가 작성한 컴포넌트라고 판단한다.

컴포넌트 중첩 및 구성

컴포넌트는 일반 JS 함수이기 때문에 같은 파일에 여러 컴포넌트를 포함할 수 있다.

만약 한 컴포넌트가 너무 크기가 커진다면, 그 안에서 또 작게 컴포넌트를 쪼개서 파일을 분리할 수 있다.

예를 들어, 위의 Gallery 컴포넌트가 너무 커진다면, Profile 컴포넌트를 위 파일에서 분리해서 Profile.js(tsx)라는 새로운 파일에 작성해준다.

  • 이렇게 분리한 Profile.js(tsx)파일은 Profile 컴포넌트(= Profile 함수 = function Profile () {} 을 내보낸다.( = export한다)

  • export된 Profile 컴포넌트를 사용하고 싶은 곳에서(위 예시로는 Gallery.js) import로 가져와서 사용한다.

이 경우 Profile 컴포넌트는 Gallery 안에서 렌더링되기 때문에 Gallery는 각 Profile을 자식으로 렌더링하는 부모 컴포넌트라고 말할 수 있다.

이렇게 컴포넌트를 한 번 정의만 한다면, 원하는 곳에서 어디서든 사용할 수 있는 것이 React의 마법!

주의점

컴포넌트는 다른 컴포넌트를 렌더링할 수는 있지만, 컴포넌트 안에 또 다른 컴포넌트를 정의하면 안된다! (정의 중첩)

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

위 코드는 매우 느리고 버그를 촉발한다. 이러지 말고 최상위 레벨에서 컴포넌트를 작성해야 한다.

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

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

자식 컴포넌트에서 부모 컴포넌트가 가진 데이터를 사용해야 할 경우, 중첩 정의하지 말고 props롤 전달하도록 하자.

Deep Dive: 컴포넌트의 모든 것

React 어플리케이션은 'root' 컴포넌트에서 시작된다. 이 컴포넌트는 보통 새 프로젝트를 시작할 때 자동으로 생성된다. (Next.js의 경우 src/app/page.tsx)

대부분의 리액트 앱은 모든 부분에서 컴포넌트를 사용한다. 즉, "버튼" 처럼 재사용 가능한 부분 뿐만 아니라 사이드 바, 목록, 그리고 궁극적으로 전체 페이지와 같은 큰 부분에도 컴포넌트를 사용하게 된다.

재사용 가능한 점이 컴포넌트의 장점이라고 계속 언급하고 있지만, 사실 정의된 후로 딱 한번만 사용되더라도 컴포넌트는 UI 코드와 마크업을 정리하는 편리한 방법이다.

출처: 리액트 공식문서 (https://ko.react.dev/learn/your-first-component)

profile
목표는 "함께 일하고 싶은, 함께 일해서 좋은" Front-end 개발자

0개의 댓글