Angular 프로젝트에서 RxJS를 활용한 상태 관리 패턴

문제 상황

다중 스텝 폼을 구현하는데 각 스텝 간 데이터 공유와 유효성 검증이 복잡해졌다. NgRx를 도입하기엔 과한 감이 있었고, 컴포넌트 간 Input/Output으로만 처리하기엔 뎁스가 깊어 코드가 지저분해졌다.

해결 방법

RxJS의 BehaviorSubject를 활용한 간단한 상태 관리 서비스를 만들었다.

@Injectable()
export class FormStateService {
  private formDataSubject = new BehaviorSubject<FormData>(initialState);
  public formData$ = this.formDataSubject.asObservable();

  updateFormData(data: Partial<FormData>) {
    const current = this.formDataSubject.getValue();
    this.formDataSubject.next({ ...current, ...data });
  }

  get currentValue(): FormData {
    return this.formDataSubject.getValue();
  }
}

각 스텝 컴포넌트에서는 다음과 같이 사용했다.

export class Step1Component implements OnInit {
  formData$: Observable<FormData>;

  constructor(private formState: FormStateService) {
    this.formData$ = this.formState.formData$;
  }

  onSubmit(stepData: any) {
    this.formState.updateFormData({ step1: stepData });
  }
}

장점

  • NgRx 대비 보일러플레이트가 적다
  • RxJS의 강력한 Operator들을 그대로 활용 가능
  • 컴포넌트 간 결합도가 낮아진다

주의점

BehaviorSubject를 직접 노출하면 외부에서 next()를 호출할 수 있어 캡슐화가 깨진다. 반드시 Observable로 변환해서 제공해야 한다.

프로젝트가 커지고 상태 로직이 복잡해지면 결국 NgRx 같은 정식 상태 관리 라이브러리가 필요하겠지만, 중소규모 기능에는 이 정도로도 충분했다.