전역상태관리와 지역상태관리의 장단점

·2025년 6월 29일
0

개요

회사에서 서비스에 대한 신규 기능을 만들던 중, pinia store를 두어 도메인별로 전역상태관리를 활용하는 로직을 구성해보았다. 그동안 부모, 자식 컴포넌트 간 prop 처리 로직이 번거롭다는 것이 그 이유였다.

다만 아이디어와는 다르게, 전역상태관리에서 의도하지 못한 문제들이 발생하며 해당 로직은 롤백시키고 기존의 prop 으로 전달하는 방식으로 바꾸기로 결정했는데, 그 이유들을 서술하는 김에 이론 공부도 할 겸, 전역상태관리와 지역상태관리의 장단점을 비교해보았다.

전역상태관리

전역 상태관리는 여러 컴포넌트에서 공유해야 하는 데이터(상태)를 한 곳에서 중앙 집중적으로 관리하는 방법이다. 앱 전체(혹은 여러 페이지, 여러 컴포넌트)에서 접근하고 수정할 수 있는 공통 저장소를 만드는 것이 핵심이다.

장점

중앙집중식 관리

여러 컴포넌트에게 필요한 관리를 한 곳에서 집중적으로 관리하기 때문에, 컴포넌트에서 중복되는 이벤트나 상태 정의를 줄일 수 있다.

일반적으로 지역상태관리는 도메인의 최상위 부모 컴포넌트(aka. page 영역)에서 상태를 컨트롤 하며 자식에서 props 를 전달하는 방식을 사용하는데, 전역상태관리를 사용하면 Page 컴포넌트의 역할은 자식 컴포넌트를 렌더링 하는 일만 담당한다.

props drilling 개선

props drilling 은 부모 컴포넌트를 기점으로 N개의 detph 를 가지는 자식 컴포넌트가 있다고 할 때, 부모 컴포넌트의 상태를 전달하기 위해서는 N번의 props 전달하는 것을 의미한다.

이러한 props drilling 이 가져오는 문제는 크게 다음과 같다.

  • 개발자의 손이 바쁘다. 부모 → 자식 → 자식의 자식 → 자식의 자식의 자식 … 등이 이어질 때마다 개발자는 반복적인 prop 작업을 계속 해줘야 한다. 더불어 유지보수도 매우 힘들다. 사용하던 prop 의 변수가 변경되면 부모 부터 N번째의 자식까지 모두 변경이 필요하다.
  • 성능적으로 좋지 않다. SPA 프레임워크에서 prop 이 변경된다는 건, 컴포넌트 라이프사이클에 영향을 미친다. 단순히 prop 전달을 진행하는 자식 컴포넌트도 원하지 않는 변경이 이뤄질 수 있다.

단점

라이프사이클의 분리

전역상태는 컴포넌트의 라이프사이클에서 완전히 분리 된다. 즉, 임의의 컴포넌트가 unmount 되더라도, 전역상태는 계속 남아있게 된다. 즉, 만약 임의의 컴포넌트가 사라질 때 전역상태의 변경이 필요하다면, 개발자가 직접 로직을 구성해줘야한다는 것이다.

N개의 컴포넌트 중, 언제 초기화를 진행해야할지, 언제 삭제시켜야할지, 임의의 이벤트나 변경사항마다 타 컴포넌트에 영향을 미치므로 개발자가 예측하지 못한 오류가 발생할 가능성이 크다.

해당 문제가 기존의 전역상태관리를 지역상태관리로 전환하게 된 가장 큰 이유가 되었다.

지역상태(prop)의 경우, 컴포넌트가 unmount 가 되면 그 상태도 함께 사라지므로, 개발자가 지역상태관리의 소멸에 대해 신경 쓰지 않아도 된다.

디버깅 어려움

전역상태에서 의도하지 못한 변경점이 발생했을 때, 해당 변경 이벤트를 여러 컴포넌트에서 활용하는 경우라면 문제의 원인을 추적하기가 어렵다.

개선방향을 찾는 것도 어렵다. 전역상태이기 때문에 코드를 수정하면 다른 사이드 이펙트가 발생할 위험이 있다.

설정 복잡성

최근의 전역상태 라이브러리에서는 많이 사라진 부분이지만, store 에 대한 설정이 필요하며, 각 라이브러리 별 사용방식에 대한 러닝커브가 어느정도 필요하다.

지역상태관리

각 컴포넌트(혹은 특정 범위의 컴포넌트) 내부에서만 관리되는 데이터를 의미한다. 해당 컴포넌트가 렌더링될 때 생성되고, 언마운트될 때 사라지며, 부(다른 컴포넌트)에서는 접근, 수정이 불가능하다.

장점

라이프사이클 관리가 쉬움

컴포넌트가 마운트 될 때, 상태가 초기화되며 컴포넌트가 언마운트 될 때 상태가 사라진다. 개발자가 지역상태의 생명주기에 특별히 신경 쓰지 않아도, 페이지 이동이나 닫기 등의 언마운트 시 자체적으로 제거된다는 보장이 있다.

단순함 (예측하기 쉬움)

컴포넌트 내부에서 상태를 관리하므로, 전역상태관리 대비 로직이 단순하며 관리가 쉽다 항상 상태의 흐름이 트리 안에서 부모 → 자식으로만 전달됨으로 개발자가 의도한대로 구성하기가 쉽다. 행여 에러가 나더라도, 해당 state 혹은 prop를 사용하느 컴포넌트만 분석하면 되기 때문에 전역상태관리 대비 디버깅이 한결 수월하다.

의존성 감소

전역상태관리의 경우, 외부 라이브러리에 대한 의존성이 필요하지만 지역상태관리는 React, Vue 만 사용하면 자체적으로 지원해준다. 더불어, 특별한 설정도 필요하지 않다.

단점

props drilling

전역상태관리에서도 언급한 것처럼, 지역상태 컴포넌트 내부에서만 사용하는 만큼 반복적인 코드를 작성해야한다. 자식 컴포넌트를 여러 단계 prop을 전달하게 되는 경우 코드가 지저분해지며, 유지보수가 어려워진다.

부모-자식 간의 데이터 전달만 가능

전역상태는 store 를 통해 자신이 필요할 때, 적절히 호출하여 사용하는 것이 자유롭다. 그러나 prop 을 통한 전달방식은 인접한 부모-자식 관계에 대해서만 가능하며, 자식 → 부모에게 데이터를 전달하거나 depth 가 깊다면 그만큼 전달하는데 작업이 많이 필요하다.

타협방안

전역상태관리 사용방식

물론 "전역상태관리를 아예 사용하지 말자"는 아니다. 기능별로 전역상태관리를 진행하는 것보다는 지역상태관리가 더 용이하다는 것이지, 전역상태관리가 어울리는 상태들도 존재한다.

  • 처음 데이터 값을 가져왔을 때, 모든 도메인에서 참조하는 값의 경우 전역상태관리로 관리하는 것이 용이하다.
  • 단, 대체적으로 잘 변하지 않는 값 일수록 좋다고 판단했다. (ex. 직원정보, 권한정보 등)

지역상태관리 전략

기존 지역상태관리의 불편함을 개선하고자, 사수와 함께 기존 지역상태관리에 대한 색다른 전략을 모색해보았다.

  • 기능에 대한 최상위 부모 컴포넌트는 페이지로, 자식 컴포넌트는 컴포넌트로 분류한다.
  • 부모 컴포넌트 역할은, api 요청 이벤트와 자식 컴포넌트에게 결과를 전달하는 것이다.

    지역상태관리이지만, 최상위 부모에서 중앙 관리를 이루기 위한 전략이다. 부모 컴포넌트는 상태를 변경할 수 있고, 자식 컴포넌트는 이를 전달만 받는다는 형태를 통해, 부모/자식 별 업무 책임을 명확히 분리하기 위한 전략이다.

  • 자식 컴포넌트는 부모 컴포넌트의 prop을 읽기형태로 가져가며, 상태 수정을 원하는 경우, 전달받은 prop을 복제하여 수정하도록 한다.

    원본 데이터를 그대로 수정하는 것을 막기 위함이다. 만약 전달받은 prop을 바로 수정한다면, 예상치 못한 상태관리가 일어날 수 있다.

profile
새로운 것에 관심이 많고, 프로젝트 설계 및 최적화를 좋아합니다.

0개의 댓글