본문 바로가기

개발 공부

[리액트 공식 문서] Quick start~ Thinking in React

컴포넌트

  • React 컴포넌트 이름은 항상 대문자로 시작해야 하고 HTML 태그는 소문자로 시작해야 합니다.
  • export default 키워드는 파일의 주요 컴포넌트를 지정합니다
  • <div>...</div> 또는 빈 <>...</> 래퍼와 같이 하나의 공유 부모로 감싸야 합니다.
  • <br />과 같은 태그를 닫아야 합니다.

데이터 표시하기

  • 중괄호를 사용하면 코드에서 일부 변수를 삽입하여 사용자에게 표시할 수 있도록 JavaScript로 “이스케이프”할 수 있습니다.
return (
  <h1>
    {user.name}
  </h1>
);

return (
  <img
    className="avatar"
    src={user.imageUrl}
  />
);
  • JSX 중괄호 안에 문자열 연결과 같이 더 복잡한 표현식을 넣을 수도 있습니다:
  • style={{}}은 특별한 구문이 아니라 style={ } JSX 중괄호 안에 있는 일반 {} 객체입니다.

조건부 렌더링

  • if문을 사용할 수 있다.
let content;
if (isLoggedIn) {
  content = <AdminPanel />;
} else {
  content = <LoginForm />;
}
return (
  <div>
    {content}
  </div>
);
  • 조건부 ? 연산자를 사용할 수 있다.
<div>
  {isLoggedIn ? (
    <AdminPanel />
  ) : (
    <LoginForm />
  )}
</div>
  • else 분기가 필요하지 않은 경우 더 짧은 논리 && 구문을 사용할 수 있다.
<div>
  {isLoggedIn && <AdminPanel />}
</div>

목록 렌더링

  • 컴포넌트 내에서 map() 함수를 사용하여 배열을 반환합니다.
  • 중복되는 태그 안에는 key 속성이 존재하는데, 목록의 각 항목에 대해, 형제 항목 중에서 해당 항목을 고유하게 식별하는 문자열 또는 숫자를 전달해야 합니다.
    • 보통 키는 데이터베이스 ID와 같은 데이터에서 가져와야 합니다.
    • React는 나중에 항목을 삽입, 삭제 또는 재정렬할 때 어떤 일이 일어났는지 이해하기 위해 키를 사용합니다.
const products = [
  { title: 'Cabbage', isFruit: false, id: 1 },
  { title: 'Garlic', isFruit: false, id: 2 },
  { title: 'Apple', isFruit: true, id: 3 },
];

export default function ShoppingList() {
  const listItems = products.map(product =>
    <li
      key={product.id}
      style={{
        color: product.isFruit ? 'magenta' : 'darkgreen'
      }}
    >
      {product.title}
    </li>
  );

  return (
    <ul>{listItems}</ul>
  );
}

이벤트에 응답하기

  • onClick={handleClick}의 끝에 괄호가 없다.
function MyButton() {
  function handleClick() {
    alert('You clicked me!');
  }

  return (
    <button onClick={handleClick}>
      Click me
    </button>
  );
}

화면 업데이트 하기

  • 동일한 컴포넌트를 여러 번 렌더링하면 각각 고유한 state를 갖게 됩니다

훅 사용하기

  • use로 시작하는 함수를 *훅(Hook)*이라고 합니다.
  • 컴포넌트(또는 다른 훅)의 최상위 레벨에서만 훅을 호출할 수 있습니다.

컴포넌트 간 데이터 공유하기

  • 데이터 공유가 이루어지는 최상단 컴포넌트를 제작하고, 최상단 컴포넌트에서 하위 컴포넌트로 공유 클릭 핸들러와 함꼐 state를 전달한다. 이를 state 끌어올리기라고 말할 수 있습니다.
export default function MyApp() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <div>
      <h1>Counters that update together</h1>
      <MyButton count={count} onClick={handleClick} />
      <MyButton count={count} onClick={handleClick} />
    </div>
  );
}

mockup으로 시작하기

UI를 컴포넌트 계층 구조로 나누기

React로 정적인 UI 만들기

  • 정적 버전을 먼저 만든 다음 상호작용을 별도로 추가하는 것이 더 쉬운 경우가 많습니다
  • 데이터 모델을 렌더링하는 앱의 정적 버전을 만들기 위해서는 다른 컴포넌트를 재사용하는 components를 만들고 props를 사용하여 데이터를 전달해야 합니다.
  • 단방향 데이터 흐름이란? 데이터가 최상위 컴포넌트에서 트리 하단에 있는 컴포넌트로 흘러내리는 것이다.
function ProductCategoryRow({ category }) {
  return (
    <tr>
      <th colSpan="2">
        {category}
      </th>
    </tr>
  );
}

function ProductRow({ product }) {
  const name = product.stocked ? product.name :
    <span style={{ color: 'red' }}>
      {product.name}
    </span>;

  return (
    <tr>
      <td>{name}</td>
      <td>{product.price}</td>
    </tr>
  );
}

function ProductTable({ products }) {
  const rows = [];
  let lastCategory = null;

  products.forEach((product) => {
    if (product.category !== lastCategory) {
      rows.push(
        <ProductCategoryRow
          category={product.category}
          key={product.category} />
      );
    }
    rows.push(
      <ProductRow
        product={product}
        key={product.name} />
    );
    lastCategory = product.category;
  });

  return (
    <table>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
        </tr>
      </thead>
      <tbody>{rows}</tbody>
    </table>
  );
}

function SearchBar() {
  return (
    <form>
      <input type="text" placeholder="Search..." />
      <label>
        <input type="checkbox" />
        {' '}
        Only show products in stock
      </label>
    </form>
  );
}

function FilterableProductTable({ products }) {
  return (
    <div>
      <SearchBar />
      <ProductTable products={products} />
    </div>
  );
}

const PRODUCTS = [
  {category: "Fruits", price: "$1", stocked: true, name: "Apple"},
  {category: "Fruits", price: "$1", stocked: true, name: "Dragonfruit"},
  {category: "Fruits", price: "$2", stocked: false, name: "Passionfruit"},
  {category: "Vegetables", price: "$2", stocked: true, name: "Spinach"},
  {category: "Vegetables", price: "$4", stocked: false, name: "Pumpkin"},
  {category: "Vegetables", price: "$1", stocked: true, name: "Peas"}
];

export default function App() {
  return <FilterableProductTable products={PRODUCTS} />;
}

최소한의 완전한 UI state 찾기

  • UI를 상호작용하게 만들려면 사용자가 기반이 되는 데이터 모델을 변경할 수 있도록 해야 합니다. 이를 위해 state를 사용합니다.
  • state를 앱이 기억해야 하는 최소한의 변화하는 데이터 집합을 생각해야한다.
  • state를 구조화할 때 가장 중요한 원칙은 DRY(직접 반복하지 않기)를 유지하는 것이다.

state를 식벽하는 요소

  • 시간이 지나면 변해야 한다.
  • 부모로부터 porps를 통해 전달되지 않아야 한다.
  • 컴포넌트의 기존 state 또는 props를 가지고 계산 할 수 없다면 state이다.

state가 어디에 있어야 할지 파악하기

  • 이 state를 변경하는 데 책임이 있는 컴포넌트, 즉,state를 ‘소유’하는 컴포넌트를 식별해야 합니다.
  1. 해당 state를 기반으로 렌더링하는 모든 컴포넌트를 찾으세요.
  2. 가장 가까운 공통 상위 컴포넌트, 즉,계층상 그 state의 영향을 받는 모든 컴포넌트들의 위에 있는 컴포넌트를 찾으세요.
  3. state가 어디에 위치할지 결정합시다:
  4. 대개 공통 부모에 state를 그대로 둘 수 있습니다.
  5. 혹은 공통 부모보다 더 상위 컴포넌트에 state를 둘 수도 있습니다.
  6. state를 소유할 적절한 컴포넌트를 찾지 못했다면, state를 소유하는 새 컴포넌트를 만들어 공통 부모 컴포넌트보다 상위에 추가하세요.