애플리케이션 복잡도 증가에 따라 데이터의 위치, 변경, 반응을 명확히 파악하고 기능 개발에 자신감을 주는 효과적인 상태 관리의 필요성이 커집니다. 📚
Angular 16에 도입된 Signals는 signal(), computed(), effect() 세 가지 핵심 빌딩 블록을 통해 반응형 값을 생성하고, 파생하며, 사이드 이펙트를 실행하여 선언적이고 성능 좋은 컴포넌트 로컬 상태 관리를 가능하게 합니다. 💡
복잡한 비즈니스 로직(API 호출, 에러 처리 등)이 컴포넌트에 직접 포함될 경우, 메서드가 여러 관심사를 처리하게 되어 코드 중복, 강한 결합, 테스트의 어려움 등 문제가 발생하여 컴포넌트 로컬 상태 관리의 한계를 드러냅니다. 🚧
NgRx Signal Store는 컴포넌트 UI와 비즈니스 로직을 분리하는 경량의 기능 수준 상태 컨테이너로, 재사용 가능하고 격리된 테스트가 가능한 상태 관리 로직을 제공하여 컴포넌트를 순수한 표현 계층으로 만듭니다. 📦
withState(), withComputed(), withMethods(), withEntities(), withHooks()와 같은 기능을 조합하여 스토어를 구성하며, 상태 정의, 파생 값, 비즈니스 로직, 엔티티 관리, 생명주기 훅 등을 유연하게 추가할 수 있습니다. 🧩
withComputed를 통해 여러 시그널에 의존하는 복잡한 파생 상태를 자동으로 동기화하고, 필요한 경우에만 계산되는 지연(lazy) 평가 방식으로 효율성을 높입니다. 📊
Signal Store를 사용하면 컴포넌트는 스토어를 주입하고 시그널을 직접 읽으며, 사용자 상호작용은 스토어 메서드를 호출하는 순수한 표현 계층이 되어 코드의 가독성과 유지보수성을 크게 향상시킵니다. ✨
여러 기능(예: 작업 완료 시 포인트 부여, 알림, 분석 추적)이 서로 조율해야 할 때, 메서드 기반 스토어는 직접적인 의존성 주입으로 인해 스토어 간 강한 결합, 순환 의존성, 테스트 복잡성 증가 등의 문제를 야기합니다. 🔗
스토어 간의 직접적인 호출 대신 이벤트를 통해 통신하는 이벤트 기반 아키텍처를 도입하여, 기능들이 서로의 존재를 모르고 독립적으로 반응하게 함으로써 스토어 간의 결합도를 낮추고 확장성을 높입니다. 📡
이벤트 기반 아키텍처는 이벤트 정의(eventGroup), 이벤트 발생 시 상태를 업데이트하는 리듀서, 비동기 작업을 처리하고 결과 이벤트를 디스패치하는 이펙트, 그리고 UI 컴포넌트에서 이벤트를 디스패치하는 4단계로 구현됩니다. 🚀