Angular 16 이후 Signals가 도입되면서, 기존에 RxJS Observable을 쓰던 패턴을 대체할 수 있는가에 대한 논의가 많습니다.
하지만 실제로는 두 기술이 대체재라기보다는 보완재에 가깝습니다.
Signals
- 주요 특징
- 단순한 state 저장소
- 변경 시 자동으로 UI 반영
- 동기적으로 동작 (값을 즉시 읽을 수 있음)
// counter.signal.ts
import { signal } from '@angular/core';
export const counter = signal(0);
export function increment() {
counter.update(c => c + 1);
}
- 장점
- 러닝 커브가 거의 없음 (변수처럼 쓰면 됨)
- async pipe 불필요 → 템플릿에서 바로 값 사용 가능
- 작은 규모의 상태 관리에 매우 적합
RxJS
- 주요 특징
- 비동기 스트림을 다루는 라이브러리
- 복잡한 이벤트 흐름, 네트워크 호출, 멀티 캐스팅 등에 강력
// user.service.ts
private user$ = new BehaviorSubject<User | null>(null);
fetchUser(id: number) {
this.http.get<User>(`/api/users/${id}`).subscribe(user => {
this.user$.next(user);
});
}
get userChanges$() {
return this.user$.asObservable();
}
- 장점
- 다양한 오퍼레이터 (map, switchMap, merge, …)로 복잡한 데이터 흐름 제어 가능
- 멀티 이벤트/스트림 조합에 최적화
Signals vs RxJS 예시 비교
(1) 단순 상태 관리 → Signals가 적합
// dark-mode.service.ts
@Injectable({ providedIn: 'root' })
export class DarkModeService {
darkMode = signal(false);
toggle() {
this.darkMode.update(v => !v);
}
}
- UI 버튼 클릭 시 바로 UI 반영
- 특별한 비동기 처리 필요 없음 → RxJS는 오히려 오버스펙
(2) API 호출 및 비동기 스트림 → RxJS가 유리
// search.service.ts
@Injectable({ providedIn: 'root' })
export class SearchService {
private query$ = new Subject<string>();
results$ = this.query$.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(q => this.http.get(`/api/search?q=${q}`))
);
search(q: string) {
this.query$.next(q);
}
}
- 연속 입력(검색어 자동완성) 같은 이벤트 스트림 제어에는 RxJS가 강력
- Signals로 구현하기엔 복잡성이 커짐
(3) Signals + RxJS 조합
실무에서는 두 기술을 함께 쓰는 경우가 많습니다.
RxJS로 비동기 데이터 처리 → Signals로 상태 저장/반영
@Injectable({ providedIn: 'root' })
export class UserStore {
user = signal<User | null>(null);
loading = signal(false);
constructor(private http: HttpClient) {}
loadUser(id: number) {
this.loading.set(true);
this.http.get<User>(`/api/users/${id}`).subscribe({
next: u => this.user.set(u),
complete: () => this.loading.set(false)
});
}
}
또는 RxJS Observable을 Signal로 변환:
const userSignal = toSignal(this.http.get<User>('/api/me'), { initialValue: null });
정리
| 상황 | Signals | RxJS |
| 단순한 UI 상태 (토글, 카운터, 폼 입력값 등) | O | X |
| 복잡한 비동기 처리 (검색, WebSocket, 멀티 이벤트) | X | O |
| API 호출 결과를 UI에 반영 | O (RxJS + Signal 조합) | O |
| 상태를 전역으로 공유 | O | O (둘 다 가능, 규모에 따라 선택) |
- Signals: 로컬 상태 관리와 UI 반영 최적화
- RxJS: 비동기 스트림 처리와 복잡한 흐름 제어
- 결국 둘 다 필요한 기술이며, 조합해서 쓰는 게 실무에서는 가장 현실적입니다.
'개발 공부 > Angular' 카테고리의 다른 글
| 앵귤러 메타데이터 관리 (1) (0) | 2025.11.30 |
|---|---|
| Angular inject() (0) | 2025.09.01 |
| Angular에서 signal을 써야 하는 이유 (1) | 2025.08.15 |
| Angular의 내장 파이프(Built-in Pipes) (2) - Custom (1) | 2025.07.27 |
| Angular의 내장 파이프(Built-in Pipes) (1) (0) | 2025.07.25 |