(React Docs) React 방식으로 생각하기 (1)

주의사항

https://react.dev/learn/thinking-in-react

목표

다음 JSON 데이터를 구현하고 React를 사용하여 목업을 디자인해 봅시다.

-json

(
  { 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" }
)

– 디자인 목업


1단계: UI를 구성요소 계층으로 나누기

디자이너가 목업을 만들 때 참조할 수 있도록 디자인 도구에 이름을 이미 만들었을 수 있습니다.

디자인은 세 가지 관점에서 구성 요소로 나눌 수 있습니다.

1. 프로그래밍: 새 기능이나 개체를 만들 때 수행

– 단일 책임 원칙 개념을 구성 요소에 적용하여 구성 요소는 하나의 역할만 가질 수 있습니다.

2. CSS: 클래스 선택자

– 클래스 선택자를 만드는 방법을 생각할 수 있습니다(이 경우 BEM 방식보다 덜 세분화된 구성 요소를 만듭니다).

3. 디자인: 디자인 레이어

– 디자인 레이어 생성 방법을 따라하시면 ​​됩니다.

물론 데이터(json 파일)가 잘 구조화되어 있다면 이 구조를 빌려 사용자 인터페이스를 만들 수 있습니다.

분할 예시

1. FilterableProductTable: 전체 앱을 포함합니다.

2. SearchBar: 사용자 입력을 받는 부분

3. ProductTable: 사용자 입력에 따라 목록을 필터링하고 표시합니다.

4. ProductCategoryRow: 각 카테고리의 제목

5. ProductRow: 각 제품 행 테이블


완성된 구성 요소 계층

필터링 가능한 제품 표

검색 창
제품 테이블

제품 범주 행
제품 계열

2단계: React에서 정적 버전 만들기

지금은 정적 사이트와 같은 비대화형 버전을 만들 수 있습니다(나중에 대화형 기능을 추가할 수 있음).

– 정적 버전은 상태를 사용하지 않습니다.

– state는 변화하는 데이터를 의미하므로 static 버전에서는 필요하지 않음(props만 사용)

-App.js

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

최상위 구성 요소인 FilterableProductTable 구성 요소는 소품을 수신하고 데이터를 하위 구성 요소에 전달합니다.

– 단방향 데이터 흐름(단방향 데이터 바인딩)

3단계: UI 상태의 최소 및 전체 표현 찾기

UI를 동적으로 만들려면 사용자가 앱의 기본 데이터 모델을 변경할 수 있어야 합니다. 이를 위해 상태를 사용하십시오.

상태: 앱이 기억해야 하는 가장 작은 변경 데이터 세트

상태를 만드는 가장 중요한 원칙: DRY(Don’t Repeat Yourself)

– 예를 들어 쇼핑 목록을 구현하는 경우 상태의 모든 항목 목록을 배열로 저장할 수 있습니다.

– 이 시점에서 총 요소 수에 대한 데이터가 필요한 경우 추가 상태를 생성하는 대신 배열의 길이를 사용할 수 있습니다!

이제 샘플 앱에 필요한 데이터 항목을 고려하십시오.

– 기존 제품 목록

– 사용자가 입력한 검색어 텍스트

– 확인란 값

– 필터링된 제품 목록

아래에서 비상태를 찾으려면…

– 시간이 지나도 변하지 않는 데이터 -> 상태 X

– 부모로부터 전달된 소품 -> 상태 X

– 기존 조건 또는 소품에서 계산하여 생성할 수 있는 데이터 -> 조건 X

당신의 실제 상태는?

오리지널 X 제품 목록(소품)

O 사용자가 입력한 검색어 텍스트(상태)

O 확인란 값(상태)

X 필터링된 제품 목록(소품에서 생성 가능)