※ 공식문서를 읽고 정리한 글입니다.
아래 사진의 디자인을 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 설계가 시작됨
-
컴포넌트를 만드는 원칙은 함수나 객체를 만드는 것처럼 단일 책임 원칙에 따라 하면 됨
단일 책임 원칙: 하나의 컴포넌트는 한가지 역할을 수행해야 하며, 컴포넌트가 커지게 되면 더 작은 컴포넌트로 분리해야 함

-
각각의 이름을 다음과 같이 지었다 가정하자
- 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가지 조건에 해당되서는 안됨
- 부모로부터 props를 통해 전달되는가?
- 시간이 지나도 값이 바뀌지 않는가?
- 컴포넌트 내의 다른 state나 props를 통해 계산 가능한가?
- 이를 통해 생각해보면 제품의 원본 목록은 부모로부터 props를 통해 전달됨으로 state가 아니고, 필터링 된 제품목록은 컴포넌트 내 props와 state로 계산이 가능함으로 state가 아님
- 따라서 예제에서 state는 유저의 검색어 + 체크박스 값
Step4 - State의 위치 찾기
-
State이 위치를 찾기위해서는 다음의 과정을 거쳐야 함
- State를 기반으로 렌더링하는 모든 컴포넌트 찾기
- 공통 소유 컴포넌트(common owner component) 찾기
공통 소유 컴포넌트: 계층 구조 내에서 특정 state가 있어야 하는 모든 컴포넌트들의 상위에 있는 컴포넌트)
- 공통 or 더 상위에 있는 컴포넌트가 state를 가져야 함, 적절한 컴포넌트가 없으면 state를 소유하는 컴포넌트를 하나 만들어서 공통 소유 컴포넌트의 상위 계층에 추가
-
이에따라 예제를 분석해보자
- SearchBar는 검색어와 체크박스의 상태를 표시해주고 ProductTable은 state를 기반으로 상품 리스트를 필터링해주어야함
- 공통 소유 컴포넌트는 FilterableProductTable
- 위치 뿐만 아니라 의미적으로도 FilterableProductTable에 state가 있는것이 적절함
-
이제 이를 구현해보자. useState hook을 사용하여 FilterableProductTable에 searchData를 구현하고, 배열을 재설정하는 코드가 있는 부분(jsonSort.js)에 state에 맞춰 필터링 하는 코드를 추가하였다.
소스코드 링크
Step5 - 역방향 데이터 흐름 추가
- 마지막으로 구현할 것 -> SearchBar에서 FilterableProductTable의 state를 업데이트 할 수 있게해야함
- 이를 위해서는 예제에서는 다음과 같은 작업이 필요함
- input 태그의 value, checked 속성이 FilterableProductTable에서 전달된 속성값과 같게 동기화
- onChange()이벤트를 사용해 FilterableProductTable에 콜백을 전달 -> setState()호출
- 이를 react hook을 사용하여 구현하면 최종 완성본을 얻을 수 있다.
소스코드
시연 페이지