UI 표현하기

React는 사용자 인터페이스(UI)를 렌더링하기 위한 JavaScript 라이브러리입니다. UI는 버튼, 텍스트, 이미지와 같은 작은 요소로 구성됩니다. React를 통해 작은 요소들을 재사용 가능하고 중첩할 수 있는 컴포넌트로 조합할 수 있습니다. 웹 사이트에서 휴대전화 앱에 이르기까지 화면에 있는 모든 것을 컴포넌트로 나눌 수 있습니다. 이 장에서는 React 컴포넌트를 만들고, 사용자화하며, 조건부로 표시하는 방법에 대해서 알아봅시다.

첫 컴포넌트

React 애플리케이션은 컴포넌트라고 불리는 독립된 UI 조각들로 이루어집니다. React 컴포넌트는 마크업을 얹을 수 있는 JavaScript 함수입니다. 컴포넌트는 버튼과 같이 작을 수도 있고 전체 페이지와 같이 큰 경우도 있습니다. 다음의 Gallery 컴포넌트는 세 개의 Profile 컴포넌트를 렌더링하고 있습니다.

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>
  );
}

이 주제를 배울 준비가 되셨나요?

React 컴포넌트를 선언하고 사용하는 방법을 배우려면 첫 컴포넌트 를 읽어보세요.

더 보기

컴포넌트 Import 및 Export 하기

하나의 파일에 많은 컴포넌트를 선언할 수 있지만, 파일이 커지면 탐색하기 어려워집니다. 이를 해결하기 위해 컴포넌트를 별도의 파일로 만들어 export하고 다른 파일에서 해당 컴포넌트를 import할 수 있습니다.

import Profile from './Profile.js';

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

이 주제를 배울 준비가 되셨나요?

컴포넌트를 개별 파일로 분리하는 방법을 배우려면 컴포넌트 Import 및 Export 하기 를 읽어보세요.

더 보기

JSX로 마크업 작성하기

React 컴포넌트는 React가 브라우저에 렌더링하는 마크업을 포함할 수 있는 JavaScript 함수입니다. React 컴포넌트는 그 마크업을 표현하기 위해 JSX라는 확장된 문법을 사용합니다. JSX는 HTML과 매우 유사하지만 조금 더 엄격하며 동적인 정보를 표시할 수 있습니다.

기존의 HTML 마크업을 React 컴포넌트에 그대로 붙여넣으면 동작하지 않을 수도 있습니다.

export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>

만약 이미 만들어진 HTML 마크업이 있다면 converter를 사용하여 변환할 수 있습니다.

export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}

이 주제를 배울 준비가 되셨나요?

올바르게 JSX를 작성하는 방법을 배우려면 JSX로 마크업 작성하기 를 읽어보세요.

더 보기

JSX에서 중괄호를 이용하여 JavaScript 사용하기

JSX를 사용하면 JavaScript 파일에 HTML과 비슷한 마크업을 작성할 수 있어 렌더링 로직과 콘텐츠를 같은 곳에 둘 수 있습니다. 때로는 그 마크업 내부에 JavaScript 로직을 추가하거나 동적인 프로퍼티를 참조해야 하는 경우가 있습니다. 그럴 때 JSX에서 중괄호를 사용하여 JavaScript와 연결된 “창문을 열 수” 있습니다.

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

이 주제를 배울 준비가 되셨나요?

JSX에서 중괄호를 사용하여 JavaScript 데이터에 접근하는 방법을 배우려면 JSX에서 중괄호를 이용하여 JavaScript 사용하기 를 읽어보세요.

더 보기

컴포넌트에 Props 전달하기

React 컴포넌트는 서로 통신하기 위해 props를 사용합니다. 모든 부모 컴포넌트는 자식 컴포넌트에 props를 제공하여 정보를 전달할 수 있습니다. Props는 HTML 어트리뷰트와 유사해 보이지만 객체, 배열, 함수를 포함한 모든 JavaScript 값이 전달될 수 있습니다. 심지어 JSX도 가능합니다!

import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

이 주제를 배울 준비가 되셨나요?

Props를 전달하고 활용하는 방법을 배우려면 컴포넌트에 Props 전달하기 를 읽어보세요.

더 보기

조건부 렌더링

컴포넌트는 조건에 따라 다른 항목을 표시해야 하는 경우가 많습니다. React는 if 문, &&? : 연산자와 같은 자바스크립트 문법을 사용하여 JSX를 조건부로 렌더링할 수 있습니다.

이 예제에서는 JavaScript && 연산자를 사용하여 체크 표시를 조건부로 렌더링합니다.

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✔'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}

이 주제를 배울 준비가 되셨나요?

조건부 렌더링 을 통해 콘텐츠를 조건부로 렌더링하는 다양한 방법을 배울 수 있습니다.

더 보기

리스트 렌더링

데이터 모음으로부터 유사한 컴포넌트를 여러 개 표시하고 싶을 때가 종종 있습니다. React와 JavaScript의 filter()map()을 함께 사용하면 데이터 배열을 필터링하고 컴포넌트 배열로 변환할 수 있습니다.

각 배열 항목마다 key를 지정해야 합니다. 일반적으로 데이터베이스에서 가져온 ID를 key로 사용하게 될 것입니다. Key를 사용하면 리스트가 변경되더라도 React가 각 항목의 위치를 추적할 수 있습니다.

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}

이 주제를 배울 준비가 되셨나요?

컴포넌트 목록을 렌더링하는 방법과 어떻게 key를 선택하는지에 대해 배우려면 리스트 렌더링 을 읽어보세요.

더 보기

컴포넌트 순수하게 유지하기

어떤 JavaScript 함수는 순수합니다. 순수 함수는 다음과 같은 특징이 있습니다.

  • 자신의 일만 처리합니다. 호출되기 전에 존재했던 어떤 객체나 변수도 변경하지 않습니다.
  • 입력이 같으면 출력도 같습니다. 순수 함수는 같은 입력을 받으면 언제나 같은 결과를 반환해야 합니다.

컴포넌트를 엄격하게 순수 함수로만 작성하면 코드 베이스가 커져도 이해하기 어려운 버그와 예측할 수 없는 동작을 피할 수 있습니다. 다음은 순수하지 않은 컴포넌트의 예시입니다.

let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

기존 변수를 수정하는 대신 prop을 전달하여 컴포넌트를 순수하게 만들 수 있습니다.

function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}

이 주제를 배울 준비가 되셨나요?

컴포넌트를 순수하고 예측 가능한 함수로 작성하는 방법을 배우려면 컴포넌트 순수하게 유지하기 를 읽어보세요.

더 보기

What’s next?

첫 컴포넌트 페이지로 이동하여 이 장을 페이지별로 읽어보세요!

이미 이러한 주제에 대해 알고 있다면 상호작용 추가하기를 읽어보는 것은 어떨까요?