REACT 데이터의 흐름과 사고
FE BE 개발 메모장/React

REACT 데이터의 흐름과 사고

REACT로 사고하기

 React의 개발 방식의 가장 큰 특징은 페이지 단위가 아닌, 컴포넌트 단위로 시작하는 특징을 가지고 있다. React API 공식문서에서 등록된 내용으로 어떻게 흘러가는지 자세히 확인해 보려고 한다.

 

아래의 목업을 디자이너로 부터 받았다고 가정해보자.

 가장 먼저 컴포넌트를 어떻게 나누어야 할지 찾는 것이다. 이럴 때는 단일책임원칙으로 하나의 컴포넌트에 한 가지 일을 하는 방법으로 고려를 해본다. 하나의 컴포넌트가 커질 경우 보다 작은 하위 컴포넌트로 분리해줘야한다. 

 

 

컴포넌트를 쪼개면 아래처럼 나눌 수 있을 것 같다.

 

  • A (초록색) : 하위 컴포넌트를 담고있는 최상위 컴포넌트이다. 
  • B (빨간색) : 모든 유저의 입력(input)을 받는다.
  • C (검은색) : 모든 상품을 보여주거나유저의 입력을 기반으로 특정 상품을 보여준다.
  • D (파란색) : 각 카테고리의 헤더를 보여준다.
  • E (주황색) : 각각의 제품에 해당하는 행을 보여준다.

이렇게 정리된 목업은 트리 구조를 이미지로 표현해봤다.

 

A컴포넌트에는 State를 지정해주고 자식 컴포넌트 B와 C는 Props로 전달받는 방식으로 진행되었다. 

 

각 UI끼리 상호작용을 하기 위해서는 React에선 state를 이용해 데이터를 변경해주면 된다. 우리가 구현할 애플리케이션에서 각 컴포넌트가 어떤방식으로 동작하는지 구분지어야 하고, 중복배제 원칙에 따라 최소한의 state를 찾고, 나머지는 필요에 따라 계산되게 만들어야 한다.

 

state를 언제 어떻게 사용해야할지 고려하기 위해서는 3가지 가 존재한다. 

1. 부모로 부터 props를 통해 전달된다면 state가 아니다.

2. 시간이 지나도 변하지 않는다면 state가 아니다.

3. 컴포넌트안에서 state나 props를 가지고 계산이 가능하다면 state가 아니다.

 

위 어플리케이션을 가정해 다음과 같은 데이터를 가지게 되고. 어떤게 state여야 할지 구분을 지어야한다.

  • 제품의 전체 원본 목록 : props로 목록만 전달해주면 되기 때문에 X
  • 체크박스 값 : 체크박스를 누를 때마다 값이 바뀌므로(시간에 따라 변한다) O 
  • 사용자가 입력한 검색어 : 어떤 검색어를 입력하는 것에 따라 달라짐(시간에 따라 변한다). O
  • 필터링 된 제품 목록 : 제품의 원본 목록, 검색어, 체크박스의 값을 조합해 계산하기 때문에 X

이제 어떤 데이터를 this.state에 담아주어야 할지 찾았으므로 state를 어느 컴포넌트가 변경 및 소유를 해야할지 정해야한다.

1. A(App)

각 자식컴포넌트를 이어주는 최상위 컴포넌트이다. state를 소유하기 위해서는 state를 기반으로 렌더링하는 컴포넌트를 찾아야 하며, 그 컴포넌트들의 상태가 같다면 상위 컴포넌트를 찾거나 만들어 state를 가져야한다.

 

어떤 컴포넌트는 검색과 체크박스를 통해 상태를 변경하고,

어떤 컴포넌트는 상태에 따라 제품 리스트를 필터링해줘야한다.

 

이 두가지를 고려했을때 state를 가져야할 컴포넌트는 App가 되겠다. 

this.state안에 인스턴스 속성을 명시적으로 작성 후 constructor에 담아주어 애플리케이션의 초기상태를 반영해주었다. 

이제 Props로 전달해주면 된다. 

2. B (검색, 체크박스)

컴포넌트 B는 사용자의 입력(Input)에 따라 결과를 보여주는 컴포넌트이다. 부모 컴포넌트 App의 state를 props로 전달받고, App를 통해 C와 상호작용이 가능하다.

3.C (제품 리스트)

컴포넌트 C는 화면에 전체 제품 리스트를 렌더링 해준다. 코드를 해석하면 다음과 같다.

 

forEach로 제품 정보가 담긴 Product를 순회한다.

 

첫번째 조건, 제품의 이름이 유저가 입력한 이름과 같지 않으면 화면에 띄어주지 않는다. indexOf(target) === -1)

두번째 조건, 제품의 재고가 없고, state에서 false상태 그대로이면, 화면에 띄어주지 않는다.

세번째 조건, 제품 카테고리 헤더의 중복되는 요소를 하나로 출력해준다. 조건에 만족하는 경우 D 컴포넌트로 props를 전달한다. 컴포넌트 D는 카테고리 헤더(종류)를 보여준다.

 

컴포넌트 E 에게 props를 전달해준다. 제품의 정보(재고 유무, 이름, 가격)를 전달한다.  

 

이렇게 동시에 두 컴포넌트를 rows라는 하나의 배열에 담아준다.

 

4. D, E ( 카테고리 헤더, 제품 목록)

D와 E컴포넌트

컴포넌트 D는 C에서 props를 전달받아 각 카테고리 이름을 렌더링한다.

컴포넌트 E는 제품의 이름과 가격, 재고 상태(색상으로 표현)를 렌더링한다.

 

 ReactDom.render()를 통해 조합된 컴포넌트가 위와 같이 출력이 되었다. props는 단순히 상위 컴포넌트에서 하위 컴포넌트로 전달해주는 역활로 써야한다.

역방향으로 데이터 흐름 추가하기.

위의 코드에서는 아래로 흐르는 계층 구조로 제작되었다. 계층구조의 하단에서 상태를 업데이트를 할 수 있어야한다.

 

기존의 상태에서는 검색창에 입력하거나 체크박스를 클릭해도 바뀌지 않는다. Input태그의 value속성이 A 컴포넌트에서 전달받은  state와 동일하도록 설정되어있기 때문이다.

 

우리가 원하는 것은 체크박스, 검색창에 검색어를 입력을 반영하기 위해 state를 업데이트 해줘야한다. 

 

컴포넌트A

이렇게 메소드를 추가해주고, 메소드의 인자값을 받으면 this.setState를 통해 상태에 반영된다. 콜백에서 this가 동작하기 위해서는 항상 바인딩을 해줘야한다. 하위 컴포넌트에 Props로 전달해 주었다.

 

 

이제 하위 컴포넌트는 전달받은 props를 Input값에 전달해 주었다. Input에 onChange를 통해 입력된 값을 A 컴포넌트에 콜백을 전달해주고, setState()를 호출해서 앱이 업데이트 된다.

 

 

'FE BE 개발 메모장 > React' 카테고리의 다른 글

React Hook을 알아보자  (0) 2021.03.01
생명주기(Life-Cycle) 1차  (0) 2021.02.28
State와 Props에 대해서  (0) 2021.02.13
컴포넌트(Component)란?(좀더 이해하기 쉽게 수정해야함)  (0) 2021.02.13
JSX 문법  (0) 2021.02.11