티스토리 뷰

코딩/코드스테이츠

[React] 상태 관리

김기지 2023. 2. 23. 21:17

1. 전역 상태 관리

React가 상태 관리를 위한 라이브러리는 아니다.
그러나 상태 관리의 주요 원칙을 배우고 이를 따라간다면, 컴포넌트간 서로 느슨하게 결합된(loose coupled), 구조적으로 아름다운 코드를 작성할 수 있다.

📍 프론트엔드 개발에서의 상태 관리

  • 상태란?
    • 변하는 데이터로 UI, 프론트엔드 개발에서는 “동적으로 표현되는 데이터”이다.

➰ UI에서 상태 찾기 연습 : 장바구니 페이지

이 장바구니 페이지에 몇 개의 상태가 있을까?

  • “장바구니에 담기”와 같은 버튼을 눌러 해당 물품을 장바구니에 추가할 수 있음
  • → 동적인 데이터이므로 상태
  • 상단에 [일반구매/ 정기배송] 중 현재 선택된 탭이 무엇인지 나타내는 상태가 있을 수 있음
  • 상품 선택 여부에 따라 주문 금액이나 배송비가 달라짐
    • 선택 여부는 변할 수 있으므로 상태
  • 상품수량도 변하므로 상태

 

 

 

상태에 따라 어떤 화면이 영향을 받는지도 알 수 있다.

페이지를 컴포넌트로 분리해서 컴포넌트가 서로 어떤 상태를 공유하고, 주고 받는 지를 찾아 확인할 수 있다.

 

 

📍 프론트엔드 개발에서의 Side Effect

상태를 다룰때 Side Effect는 주요 고려대상이다.
  • Side Effect
    • 함수(또는 컴포넌트)의 입력 외에도 함수의 결과에 영향을 미치는 요인
      • 대표적인 예 : 네트워크 요청, API호출
 📌 React의 주요 개발 원칙 중 하나는 UI를 페이지 단위가 아닌 컴포넌트 단위로 보는 것

만약, <CartItem>이라는 컴포넌트를 만드는 경우 fetch와 같은 API요청이 없이도

컴포넌트는 작동되어야한다.

어떤 데이터가 들어오는지 상관하지 않고, 설사 데이터가 fake(가짜) 데이터라 할지라도 컴포넌트는 표현(presentation)할 수 있어야 한다.

→ 이러한 컴포넌트를 presentation 컴포넌트라함

하지만, 앱을 만들다보면 API호출도 해야하는 경우가 많기 때문에 side effect가 불가피하게 생길 수 있다.

또, 이러한 side effect에 의존적인 상태가 있을 수 있다.

예를들어, “로딩 중”을 나타낼것인지 아닌지는 데이터 전송 여부에 달려있다.

  • 데이터 로딩 여부가 true → 나타남
  • 데이터 로딩 여부가 false → 사라짐

 

 

 

➡︎ UI를 구성할 때는 항상 이러한 로딩 중 상태도 고려해야 한다.

✚ 장바구니 데이터가 서버에 있다면, 네트워크 요청 때문에 오래 걸릴 수도 있음

📍 상태의 적절한 위치

상태를 구분하는 데 절대적인 기준이나 법칙이 있는것은 아니지만, 로컬 상태, 전역 상태로 나누어 보자.
  • 로컬 상태

특정 컴포넌트 안에서만 관리되는 상태

보통 컴포넌트 내에서만 영향을 끼치는 상태

<CartItem>컴포넌트의 경우 ‘선택한 수량’이 로컬 상태

➡︎ 컴포넌트 내에 표시되는 주문 금액은 원래 가격에 상태를 곱해 업데이트

다른 컴포넌트와 데이터를 공유하지 않는 폼(form) 데이터도 대부분 로컬 상태

input box, select box 등과 같이 입력값을 받는 경우

 

  • 전역 상태

다른 컴포넌트와 상태를 공유하고 영향을 끼치는 상태

프로덕트 전체 혹은 여러 컴포넌트에서 관리되는 상태

장바구니에 담긴 물품의 경우, 상품 선택 여부에 따라 총 주문 금액을 업데이트

장바구니에 담긴 물품은 그 개수 등을 다른 컴포넌트에 전달해야함

데이터 로딩 여부(로딩 중) 상태 역시 앱 전반에 영향을 미침

 

 

 

➰ 각 컴포넌트가 따로따로 상태를 갖고 있으면 안될까?

JavaScript를 배울때 전역변수를 남용하는 것은 좋지 않다고 했지만, 경우에 따라 전역 상태가 필요하다.

  • 서로 다른 컴포넌트가 사용하는 상태의 종류가 다른 경우에는 전역 상태일 필요는 없음
    • 서로 출처가 달라도 됨
  • 서로 다른 컴포넌트가 동일한 상태를 다룰경우 출처는 한 곳이여야함
    • 만일 사본이 있는 경우, 두 데이터는 서로 동기화(sync)하는 과정이 필요
    • 하지만 이는 문제를 어렵게 만듬
    ➡︎ 한 곳에서만 상태를 저장하고 접근해야 한다.
  • (여기서 ‘하나의 출처’는 ‘전역 공간’이라고 볼 수 있음)

📍 전역 상태에서의 무결성

  • 데이터 무결성
    • 데이터의 정확성을 보장하기 위해 데이터의 변경이나 수정 시 제한을 두어 안정성을 저해하는 요소를 막고 데이터 상태들을 항상 옳게 유지하는 것
📌 동일한 데이터는 항상 같은 곳에서 데이터를 가지고 온다.
Single source of truth(신뢰할 수 있는 단일 출처)
  • 데이터 무결성을 위해 동일한 데이터는 항상 같은 곳에서 데이터를 가지고 와야 한다.
  • 데이터가 존재하고, 그 데이터를 보여줘야 하는 프론트엔드의 경우 의도한 대로 예외 상황 없이 데이터를 잘 보여주어야한다.

📍 상태 관리를 위한 각종 툴

  • React Context
  • Redux
  • MobX

⚙️ 위와 같은 상태 관리 툴은 어떤 문제를 해결해줄까?

  1. 전역 상태를 위한 저장소를 제공
  2. Props drilling 이슈를 해결

⚠️ 상태 관리 툴이 반드시 필요한 것은 아니다.

대부분의 경우 “React 사고하기”를 통해 문제를 해결할 수 있다.

먼저 ‘상태가 어디에 위치해야 하는지’를 익혀보자

 


2. Props Drilling

props drilling(프로퍼티 내려꽂기)
상위 컴포넌트의 state를 props를 통해 전달하고자 하는 컴포넌트로 전달하기 위해 그 사이는 props를 전달하는 용도로만 쓰이는 컴포넌트들을 거치면서 데이터를 전달하는 현상

<A>라는 컴포넌트에 상태가 있고, <I>라는 컴포넌트가 해당 상태를 사용한다고 하면,

그 중간에 존재하는 <C>, <G> 등은 굳이 name이라는 상태가 필요하지 않음에도, 컴포넌트에 props를 만들어 자식 컴포넌트에 넘겨주는 것을 의미한다.

📍 Props Drilling의 문제점

props의 전달 횟수가 5회 이내로 많지 않다면 props drilling은 큰 문제가 되지 않는다.

하지만, 규모가 커지고 구조가 복잡해 지면서 props의 전달 과정이 늘어난다면 문제가 발생한다.

  • 코드의 가독성이 매우 나빠진다.
  • 코드의 유지보수가 힘들어진다.
  • state 변경시 props 전달 과정에서 불필요하게 관여된 컴포넌트들 또한 리렌더링이 발생한다.
  • → 웹 성능에 악영향을 줄 수 있다.

📍 Props Drilling 문제점의 해결 방법

과도한 props drilling을 방지하기 위한 방법으로는

  • 컴포넌트와 관련있는 state는 될 수 있으면 가까이 유지하기
  • 상태관리 라이브러리 사용하기
    • 전역으로 관리하는 저장소에서 직접 state를 꺼내쓸 수 있음
    • Redux, Context api, Mobx, Recoil 등이 있음
728x90

'코딩 > 코드스테이츠' 카테고리의 다른 글

[Redux] - Cmarket Redux  (0) 2023.02.27
[React] - 상태 관리 (Redux)  (0) 2023.02.24
[React] -useRef  (0) 2023.02.22
[React] - CDD 개발도구  (0) 2023.02.21
[React] - Component Driven Development (CDD)  (0) 2023.02.20