Part10_StateManagement
김은정
책 읽기

10장. 상태관리

상태 관리

  • 상태 : 렌더링 결과에 영향을 주는 정보를 담은 순수 자바스크립트 객체

    • 지역 상태

      • 컴포넌트 내부에서 사용되는 상태

      • 예: 체크박스 체크 여부, 폼의 입력값 등

    • 전역 상태

      • 앱 전체에서 송유하는 상태

      • 여러 개의 컴포넌트가 전역 상태를 사용할 수 있으며 상태가 변경되면 컴포넌트들도 없데이트된다.

      • props drilling 문제를 피하고자 지역 상태를 해당 컴포넌트들 사이의 전역 상태로 공유할 수 있다.

    • 서버 상태

      • 외부 서버에 저장해야 하는 상태들 (예: 사용자 정보, 글 목록 등)

      • UI 상태와 결합하여 관리하게 되며 로딩 여부나 에러 상태 등을 포함한다.

  • 상태를 잘 관리하기 위한 가이드

    • 시간이 지나도 변하지 않는다면 상태가 아니다

    • 파생된 값은 상태가 아니다

      • 부모에게서 전달받을 수 있는 props이거나 기존 상태에서 계산될 수 있는 값은 상태가 아니다.

      • SSOT(Single Source Of Truth)는 어떠한 데이터도 단 하나의 출처에서 생성하고 수정해야 한다는 원칙을 의미하는 방법론

  • useState vs useReducer, 어떤 것을 사용해야 할까

    • useState 대신 useReducer 사용을 권장하는 경우는 크게 두 가지가 있다.

      • 다수의 하위 필드를 포함하고 있는 복잡한 상태 로직을 다룰 때

      • 다음 상태가 이전 상태에 의존적일 때

    • useReducer는 ‘무엇을 변경할지’와 ‘어떻게 변경할지’를 분리하여 dispatch를 통해 어떤 작업을 할지를 액션으로 넘기고 reducer 함수 내에서 상태를 업데이트하는 방식을 정의한다.

    • 이로써 복잡한 상태 로직을 숨기고 안정성을 높일 수 있다.

  • 전역 상태 관리와 상태 관리 라이브러리

    상태는 사용하는 곳과 최대한 가까워야 하며 사용 범위를 제한해야만 한다.

    • 전역 상태 관리 방법

      • 컨텍스트 API + useState 또는 useReducer

      • 외부 상태관리 라이브러리(Redux, MobX, Recoil 등)

    • 컨텍스트 API (Context API)

      • 다른 컴포넌트들과 데이터를 쉽게 공유하기 위한 목적으로 제공되는 API

      • 전역적으로 공유해야 하는 데이터를 컨텍스트로 제공하고 해당 컨텍스트를 구독한 컴포넌트에서만 데이터를 읽을 수 있게 된다.

      • 유틸리티 함수를 정의하여 더 간단한 코드로 컨텍스트와 훅을 생성할 수 있다. ⇒ 생산성 증가

      • 엄밀하게 말해 전역 상태를 관리하기 위한 솔루션이라기보다 여러 컴포넌트 간에 값을 공유하는 솔루션에 가깝다.

      • 그러나 useState나 useReducer 같이 지역 상태를 관리하기 위한 API와 결합하여 여러 컴포넌트 사이에서 상태를 공유하기 위한 방법으로 사용되기도 한다.

      • 컨텍스트 API를 사용하여 전역 상태를 관리하는 것은 대규모 애플리케이션이나 성능이 중요한 애플리케이션에서 권장되지 않는 방법이다.

      • 그 이유는 컨텍스트 프로바이더의 props로 주입된 값이나 참조가 변경될 때마다 해당 컨텍스트를 구독하고 잇는 모든 컴포넌트가 리렌더링되기 때문이다.

      • 즉, 애플리케이션이 커지고 전역 상태가 많아질수록 불필요한 리렌더링과 상태의 복잡도가 증가한다.

상태 관리 라이브러리

  • Mobx
    • 객체 지향 프로그래밍과 반응형 프로그래밍 패러다임의 영향을 받은 ㄹ아이브러리
    • 상태 변경 로직을 단순하게 작성할 수 있고, 복잡한 업데이트 로직을 라이브러리에 위임할 수 있다.
    • 다만, 데이터가 언제 어떻게 변하는지 추적하기 어렵기 때문에 트러블슈팅에 어려움을 겪을 수 있다.
  • Redux
    • 함수형 프로그래밍의 영향을 받은 라이브러리
    • 특정 UI 프레임워크에 종속되지 않아 독립적으로 사용할 수 있다.
    • 상태 변경 추적에 최적화되어 있어, 문제의 원인을 파악하는데 용이하다.
    • 다만, 단순한 상태 설정에도 많은 보일러플레이트가 필요하고, 사용 난이도가 높다는 단점이 있다.
  • Recoil
    • 상태를 저장할 수 있는 Atom과 해당 상태를 변형할 수 있는 순수 함수 selector를 통해 상태를 관리하는 라이브러리

      Atom은 상태의 일부를 나타내며 어떤 컴포넌트에서든 읽고 쓸 수 있도록 제공된다.

    • Redux에 비해 보일러플레이트가 적고 난이도가 쉬워 배우기 쉽다

    • 다만, 라이브러리가 아직 실험적인 상태이기 때문에 충분한 검증이 이루어지지 않았다

  • Zustand
    • Flux 패턴을 사용하여 많은 보일러플레이트를 가지지 않는 훅 기반의 편리한 API 모듈을 제공한다.
    • 클로저를 활용하여 스토어 내부 상태를 관리함으로써 특정 라이브러리에 종속되지 않는다.
    • 상태와 상태를 변경하는 액션을 정의하고 반환된 훅을 어느 컴포넌트에서나 임포트하여 원하는대로 사용할 수 있다.

상태관리라이브러리 선택 기준


  • 보일러플레이트 코드가 너무 많지 않으면 좋겠다.
  • 코드를 하나 작성하는 데 너무 많은 게 들어가지 않았으면 좋겠다.

⇒ Recoil 사용