리액트 배우기 - 대단원 Describing the UI

기운찬곰·2023년 9월 22일

원문 참고 : https://react.dev/learn/describing-the-ui

Describing the UI

리액트는 사용자 인터페이스(UI)를 렌더링하기 위한 자바스크립트 라이브러리입니다. UI는 버튼, 텍스트, 이미지와 같은 작은 단위로 만들어집니다. React을 사용하면 재사용 가능하고 중첩 가능한 컴포넌트로 결합할 수 있습니다. 웹 사이트부터 phone 앱까지 화면의 모든 것을 컴포넌트로 분해할 수 있습니다. 이 장에서는 React 컴포넌트를 만들고, customize하고, 조건부로 표시하는 방법에 대해 알아봅니다.

Your first component

리액트 애플리케이션은 컴포넌트라고 불리는 분리된 UI 조각들로 구축됩니다. React 컴포넌트는 마크업과 함께 사용할 수 있는 자바스크립트 함수입니다. 컴포넌트는 버튼만큼 작을 수도 있고, 페이지 전체만큼 클 수도 있습니다. 다음은 세 가지 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>
  );
}

Importing and exporting components

하나의 파일에 많은 컴포넌트를 선언할 수 있지만 큰 파일은 탐색하기가 어려워질 수 있습니다. 이 문제를 해결하려면 컴포넌트를 자체 파일로 내보낸 다음 다른 파일에서 해당 컴포넌트를 가져올 수 있습니다:

// Gallery.js

import Profile from './Profile.js';

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

export default function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

Writing markup with JSX

각 리액트 컴포넌트는 리액트가 브라우저에 렌더링하는 마크업을 포함할 수 있는 자바스크립트 함수입니다. 리액트 컴포넌트들은 그 마크업을 나타내기 위해 JSX라고 불리는 구문 확장을 사용합니다. JSX는 HTML과 많이 닮았지만 조금 더 엄격하고 동적인 정보를 보여줄 수 있습니다.

JavaScript in JSX with curly braces

JSX는 자바스크립트 파일 안에 HTML과 같은 마크업을 작성할 수 있게 해주며, 렌더링 로직과 콘텐츠를 동일한 장소에 유지합니다. 가끔 당신은 자바스크립트 로직을 추가하거나 마크업 내부의 동적 속성을 참조하고 싶을 것입니다. 이 상황에서 JSX에서 곱슬곱슬한 괄호('{', '}')를 사용하여 자바스크립트에 "창을 열" 수 있습니다:

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

Passing props to a component

리액트 컴포넌트들은 서로 소통하기 위해 props을 사용합니다. 모든 부모 컴포넌트는 props을 제공하여 일부 정보를 자식 컴포넌트에 전달할 수 있습니다. props은 HTML 속성을 생각나게 할 수도 있지만 객체, 배열, 함수, 그리고 심지어 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>
  );
}

Conditional rendering

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

이 예제에서 자바스크립트 && 연산자는 조건부로 checkmark를 렌더링하는데 사용됩니다.

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

Rendering lists

데이터 집합에서 유사한 성분을 여러 개 표시하는 경우가 많습니다. 자바스크립트의 filter()map()을 리액트와 함께 사용하여 데이터 배열을 필터링하고 컴포넌트 배열로 변환할 수 있습니다.

각 배열 항목에 대해 key를 지정해야 합니다. 일반적으로 데이터베이스의 ID를 키로 사용하고자 할 것입니다. key를 사용하면 목록이 변경되더라도 목록에서 각 항목의 위치를 추적할 수 있습니다.

// App.js 

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>
  );
}
// data.js 

export const people = [{
  id: 0,
  name: 'Creola Katherine Johnson',
  profession: 'mathematician',
  accomplishment: 'spaceflight calculations',
  imageId: 'MK3eW3A'
}, {
  id: 1,
  name: 'Mario José Molina-Pasquel Henríquez',
  profession: 'chemist',
  accomplishment: 'discovery of Arctic ozone hole',
  imageId: 'mynHUSa'
}, {
  id: 2,
  name: 'Mohammad Abdus Salam',
  profession: 'physicist',
  accomplishment: 'electromagnetism theory',
  imageId: 'bE7W1ji'
}]

// utils.js

export function getImageUrl(person) {
  return (
    'https://i.imgur.com/' +
    person.imageId +
    's.jpg'
  );
}

Keeping components pure

일부 자바스크립트 함수들은 순수합니다. 여기서 순수 함수란 다음과 같습니다.

  • 자기 일이나 신경 쓰라(?). 호출되기 전에 존재했던 객체나 변수는 변경되지 않습니다.
  • 동일한 입력, 동일한 출력. 동일한 입력이 주어지면 순수 함수는 항상 동일한 결과를 반환해야 합니다.

컴포넌트를 순수 함수로만 엄격히 작성함으로써 코드 기반이 커짐에 따라 전체 종류의 당황스러운 버그와 예측할 수 없는 동작을 방지할 수 있습니다.

순수함수가 아닌 컴포넌트의 예는 다음과 같습니다:

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

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

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

마치면서

리액트 기본의 큰 흐름을 알 수 있는 내용이네요.

  • 리액트는 사용자 인터페이스(UI)를 렌더링하기 위한 자바스크립트 라이브러리다.
  • 리액트에서는 컴포넌트라는 작은 UI 조각을 만들어서 이를 조합해서 더 큰 컴포넌트를 만들 수 있다. 이런걸 컴포넌트 주도 개발(CDD)라고 하지요.
  • JSX라는 확장 문법을 통해 자바스크립트와 마크업을 같이 사용할 수 있다. 렌더링 로직과 콘텐츠를 동일한 장소에 유지함으로서 응집도가 높아진다.
  • 리액트 컴포넌트들은 서로 소통하기 위해 props을 사용합니다. 부모에서 자식에게 props로 전달할 수 있다.
  • 컴포넌트는 조건부연산으로 조건에 따라 다른 항목을 렌더링하기 편하다.
  • 각 배열 항목에 대해 key를 지정해서 렌더링하는 이유는 목록이 변경되더라도 목록에서 각 항목의 위치를 추적할 수 있도록 하기 위함이다.
  • 컴포넌트를 순수 함수로만 엄격히 작성함으로써 당황스러운 버그와 예측할 수 없는 동작을 방지할 수 있습니다.

솔직히 굳이 책 사서 볼 필요없이 리액트 공식문서만 봐도 초심자가 이해하는데 무리가 없을거 같네요.

profile
부계정

0개의 댓글