[part 7] React로 사고하기

누리·2023년 8월 21일
0

Interview

목록 보기
12/13

복습 : VDOM 왜 생겨났나

프론트엔드 성장 과정 HTML : css >> JavaScript >>> DOM API >> XML(비동기통신) >> ajax >> SPA를 위한 angular, Vue, React 등장

  • Single Page Application 쓰려고 하니 DOM API가 사용하기 불편했음
  • DOM을 개발자에게 주지 말고 >> 가상DOM을 주고 라이브러리 내에서 진짜 DOM을 다루도록
  • VDOM 탄생 (VDOM : 키값으로 tag, props, children을 갖는 자바스크립트 객체)
  • createElement라는 헬퍼 함수를 만듦으로써 VDOM에서 진짜 real DOM으로 만들어진다(커밋과정)

💡 React는 UI를 만들기 위한 JavaScript 라이브러리이다 -로 시작

  • 아래의 모든 내용은 "React로 사고하기" 라는 핵심 원칙이 기반이 되어야 비로소 깊은 이해와 빠른 학습이 가능합니다. 이 원칙 없이 다른 내용을 배우는 것은 마치 집을 지을 때 기초 공사 없이 지붕을 먼저 세우려는 것과 비슷합니다.
  • 또, 거의 리액트 코드를 제공해주고 리팩토링 하라고 하는 문제들은 대부분 React로 사고하기라는 대전제를 머리속에 그리면서 개발을 하냐를 보기 위함입니다. memo, useMemo, useCallback등 최적화 관련된 것들도 이 전제가 머리에 잡혀있어야 더 잘 쓸 수 있습니다.
  • 이 원칙을 이해하면 React의 모든 개념과 패턴, 심지어는 문제 해결 방법까지도 더욱 명확하게 이해할 수 있습니다. 이 원칙을 잘 이해하고 활용한다면, React를 이용한 프로젝트를 보다 효과적으로 수행할 수 있습니다.

사고하기

JSON API와 목업을 디자이너로부터 받았다고 가정해 봅시다. 목업은 다음과 같을 것입니다.

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"}
];

어떤식으로 단락을 짤지 먼저 생각을 해봐야 한다.

1단계 :: UI를 컴포넌트 계층으로 나누기

테크닉 : 단일 책임 원칙 (모든 클래스는 하나의 책임만 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함을 일컫는다)

  • 2번 : 사용자와 인터렉션 하는 섹션
  • 3번 : 데이터 보여주는 섹션 (데이터의 헤드)
  • 4번 : 데이터의 카테고리
  • 5번 : 실제 데이터들
  • 1번 : State가 있어야 할 섹션 (2번에 의해 변화된 state가 3번에도 영향을 주기 때문)

2단계 :: React로 정적인 버전 만들기 (psudo 코드)

사용자와 interation 하는 섹션을 빼고 만들면 된다

3단계 :: UI state에 대한 최소한(but, 완전한) 표현 찾기

중복배제원칙
애플리케이션을 올바르게 만들기 위해서는 애플리케이션에서 필요로 하는 변경 가능한 state의 최소 집합을 생각해보아야 합니다. 여기서 핵심은 중복배제원칙입니다. 애플리케이션이 필요로 하는 가장 최소한의 state를 찾고 이를 통해 나머지 모든 것들이 필요에 따라 그때그때 계산되도록 만드세요.
ex) TODO 리스트를 만든다고 하면, TODO 아이템을 저장하는 배열만 유지하고 TODO 아이템의 개수를 표현하는 state를 별도로 만들지 마세요.(이미 배열 안에 담긴 정보임) TODO 갯수를 렌더링해야한다면 TODO 아이템 배열의 길이를 가져오면 됩니다.

예시 : 애플리케이션 내 데이터들을 생각해봅시다. 애플리케이션은 다음과 같은 데이터를 가지고 있습니다.

* 제품의 원본 목록
* 유저가 입력한 검색어
* 체크박스의 값
* 필터링 된 제품들의 목록

각각 살펴보고 어떤 것이 state가 되어야 하는지 살펴 봅시다. 이는 각 데이터에 대해 아래 세 가지 질문을 통해 결정 할 수 있습니다.
  • 부모로부터 props를 통해 전달됩니까? 그러면 확실히 state가 아닙니다.
  • 시간이 지나도 변하지 않나요? 그러면 확실히 state가 아닙니다.(상수데이터)
  • 컴포넌트 안의 다른 state나 props를 가지고 계산 가능한가요? 그렇다면 state가 아닙니다.

4단계 :: State가 어디에 있어야 할 지 찾기

앱에서 최소한으로 필요한 state가 뭔지 찾았으면 다음으로 어떤 컴포넌트가 state를 변경하거나 소유할지 찾아야 합니다.
React는 항상 컴포넌트 계층구조를 따라 아래로 내려가는 단방향 데이터 흐름을 따릅니다.어떤 컴포넌트가 어떤 state를 가질지 바로 결정하기 어려울 수 있습니다. 아래 과정을 따라 결정해 보세요.

어플리케이션이 가지는 각각의 state에 대해서

  • state를 기반으로 렌더링하는 모든 컴포넌트를 찾으세요.
  • 공통 소유 컴포넌트 (common owner component)를 찾으세요. (계층 구조 내에서 특정 state가 있어야 하는 모든 컴포넌트들의 상위에 있는 하나의 컴포넌트).
  • 공통 혹은 더 상위에 있는 컴포넌트가 state를 가져야 합니다.
  • state를 소유할 적절한 컴포넌트를 찾지 못하였다면, state를 소유하는 컴포넌트를 하나 만들어서 공통 소유 컴포넌트의 상위 계층에 추가하세요.

왜 State가 어디에 있어야할지 알아야 하는가

  • Page 역할을 하는 Component에 state를 두면 어디에 있어야할지 몰라도 되는거 아닌가?

No.
만약 모든 state가 App에 묶여있으면 가장 아래에서만 쓰이는 state가 변경되어도 모든 컴포넌트가 리렌더링 되는 현상이 일어나서 매우 비효율적입니다. 이런 경우 state를 필요한 위치, 즉 사용되는 컴포넌트에서 관리하는 것이 더 효율적입니다.
최소한의 state를 가지도록 하라 는 React의 베스트 프랙티스를 따르는 것입니다. 필요 이상으로 많은 state를 가지면 애플리케이션의 복잡성이 높아질 뿐만 아니라, 불필요한 렌더링으로 인한 성능 저하를 초래할 수 있습니다.
그러므로 각 컴포넌트는 자신이 직접 관리해야 하는 state만을 가지고 dl

https://codesandbox.io/s/react-sagohagi-forked-wyxmt5?file=/src/App.js

5단계 :: 역방향 데이터 흐름 추가하기 (state 끌어올리기)

컴포넌트 간의 통신이 필요한 경우, state를 lifting up하는 방식을 사용할 수 있습니다. 이는 상위 컴포넌트가 state를 가지고, state handler 함수를 하위 컴포넌트에 props로 전달하여 공유하는 방식입니다. 이렇게 함으로써 각 컴포넌트는 부모단의 state를 건드릴 수 있고, 상위와 하위 컴포넌트 간에 쉽게 데이터를 공유할 수 있습니다.

어떨때 props vs state?

Component의 데이터 흐름은 단방향이다.

  • 데이터의 출발점이 되는 컴포넌트에서는 state 사용해 데이터를 관리한다. 이 state는 데이터의 변경을 추적하고, 이에 따라 UI를 업데이트 한다.
  • 데이터가 해당 컴포넌트에서 생성되지 않고, 부모 컴포넌트로부터 전달받는 경우, props를 통해 데이터를 관리한다. props는 부모 컴포넌트로부터 전달받은 데이터를 자식 컴포넌트에게 전달하며, 이 값은 변경할 수 없다.

데이터 흐름과 데이터가 어디서 시작 되는지를 기준으로 state와 props를 사용하면 된다

profile
프론트엔드 개발자

0개의 댓글