Thinking in React[React]

SnowCat·2023년 1월 9일
0

React - Main Concepts

목록 보기
11/11
post-thumbnail

※ 공식문서를 읽고 정리한 글입니다.

아래 사진의 디자인을 React로 구현해보자, JSON API는 아래와 같다.

[
  {category: "Sporting Goods", price: "$49.99", stocked: true, name: "Football"},
  {category: "Sporting Goods", price: "$9.99", stocked: true, name: "Baseball"},
  {category: "Sporting Goods", price: "$29.99", stocked: false, name: "Basketball"},
  {category: "Electronics", price: "$99.99", stocked: true, name: "iPod Touch"},
  {category: "Electronics", price: "$399.99", stocked: false, name: "iPhone 5"},
  {category: "Electronics", price: "$199.99", stocked: true, name: "Nexus 7"}
];

Step1 - UI를 컴포넌트 계층 구조로 구분

  • 각각의 컴포넌트를 구분해주는 것으로부터 UI 설계가 시작됨

  • 컴포넌트를 만드는 원칙은 함수나 객체를 만드는 것처럼 단일 책임 원칙에 따라 하면 됨
    단일 책임 원칙: 하나의 컴포넌트는 한가지 역할을 수행해야 하며, 컴포넌트가 커지게 되면 더 작은 컴포넌트로 분리해야 함

  • 각각의 이름을 다음과 같이 지었다 가정하자

  1. FilterableProductTable - 화면 전체
  2. SearchBar - 검색창
  3. ProductTable - 제품을 보여주는 화면
  4. ProductCategoryRow - 카테고리를 보여주는 부분
  5. ProductRow - 상품과 가격을 보여주는 부분
  • 컴포넌트를 계층 구조로 나타내면 다음과 같이 표현할 수 있음 (ProductTable에 다른 기능을 사용하지 않는다 가정)

  • FilterableProductTable

    • SearchBar
    • ProductTable
      • ProductCategoryRow
      • ProductRow

Step2 - React로 정적인 버전 제작

  • 데이터 계층 구조가 완성되면 이를 React 코드로 한번 제작할 필요가 있음
  • 이 과정에서는 state를 사용하지 말고 prop을 사용해 디자인
    state는 상호작용이 있을 때 사용해야함
  • 강의와 리액트 문서로 배운 지식을 총동원해 하나씩 구현해보자, bottom-up 방식으로 하나씩 제작하였다.
    해당 단계까지 진행한 소스코드 링크
  • 컴포넌트 라이브러리 제작을 통해 데이터의 흐름이 어떻게 진행되는지를 알 수 있음
  • 리액트에서는 예제처럼 트리 구조순으로 데이터가 넘어가는데, 이를 단방향 데이터 흐름(one-way data flow)라고 함
  • 단방향 데이터 흐름을 통해 컴포넌트를 모듈화 하고 빠르게 만들어줄 수 있음
  • 하지만 아직 동적인 데이터 구현이 되지 않음 => state 사용 필요

Step3 - State 찾기

  • 동적인 UI를 만들어 상호작용하게 만들려면 데이터 모델을 변경할 수 있어야 함 -> State 사용!
  • state를 만들때에는 앱이 필요로 하는 가장 최소한의 state를 찾고 나머지는 state에 따라 계산되도록 만들어야 함
    Todo List를 만들면 TODO 아이템을 저장하는 array 하나만 가지고 있으면 충분
  • 예제에서 사용되는 데이터 -> 제품의 원본 목록, 유저의 검색어, 체크박스의 값, 필터링 된 제품목록
  • state가 되기 위해서는 다음 3가지 조건에 해당되서는 안됨
    1. 부모로부터 props를 통해 전달되는가?
    2. 시간이 지나도 값이 바뀌지 않는가?
    3. 컴포넌트 내의 다른 state나 props를 통해 계산 가능한가?
  • 이를 통해 생각해보면 제품의 원본 목록은 부모로부터 props를 통해 전달됨으로 state가 아니고, 필터링 된 제품목록은 컴포넌트 내 props와 state로 계산이 가능함으로 state가 아님
  • 따라서 예제에서 state는 유저의 검색어 + 체크박스 값

Step4 - State의 위치 찾기

  • State이 위치를 찾기위해서는 다음의 과정을 거쳐야 함

    1. State를 기반으로 렌더링하는 모든 컴포넌트 찾기
    2. 공통 소유 컴포넌트(common owner component) 찾기
      공통 소유 컴포넌트: 계층 구조 내에서 특정 state가 있어야 하는 모든 컴포넌트들의 상위에 있는 컴포넌트)
    3. 공통 or 더 상위에 있는 컴포넌트가 state를 가져야 함, 적절한 컴포넌트가 없으면 state를 소유하는 컴포넌트를 하나 만들어서 공통 소유 컴포넌트의 상위 계층에 추가
  • 이에따라 예제를 분석해보자

    1. SearchBar는 검색어와 체크박스의 상태를 표시해주고 ProductTable은 state를 기반으로 상품 리스트를 필터링해주어야함
    2. 공통 소유 컴포넌트는 FilterableProductTable
    3. 위치 뿐만 아니라 의미적으로도 FilterableProductTable에 state가 있는것이 적절함
  • 이제 이를 구현해보자. useState hook을 사용하여 FilterableProductTable에 searchData를 구현하고, 배열을 재설정하는 코드가 있는 부분(jsonSort.js)에 state에 맞춰 필터링 하는 코드를 추가하였다.
    소스코드 링크

Step5 - 역방향 데이터 흐름 추가

  • 마지막으로 구현할 것 -> SearchBar에서 FilterableProductTable의 state를 업데이트 할 수 있게해야함
  • 이를 위해서는 예제에서는 다음과 같은 작업이 필요함
    1. input 태그의 value, checked 속성이 FilterableProductTable에서 전달된 속성값과 같게 동기화
    2. onChange()이벤트를 사용해 FilterableProductTable에 콜백을 전달 -> setState()호출
  • 이를 react hook을 사용하여 구현하면 최종 완성본을 얻을 수 있다.
    소스코드
    시연 페이지
profile
냐아아아아아아아아앙

0개의 댓글