Angular에서 리액티브 컨텍스트 이해하기(v21)

발행: (2026년 2월 3일 오전 04:02 GMT+9)
4 min read
원문: Dev.to

Source: Dev.to

Angular Signals에서 Reactive Context

Angular Signal 시스템에서 reactive context는 Angular의 dependency‑tracking engine이 활성화된 특수한 환경입니다. 이는 Signal이 누가 자신을 구독하고 있는지 알 수 있게 해 주는 보이지 않는 버블입니다.

  • Reactive context 내부에서 Signal을 읽으면 자동으로 구독됩니다.
  • Reactive context 외부에서 Signal을 읽으면 일반 함수 호출처럼 동작하며 이후 업데이트가 없습니다.

Reactive Context가 생성되는 위치

위치Reactive context를 생성하는 방법
템플릿HTML에서 mySignal()을 호출하면 Reactive context가 생성됩니다.
computed()computed에 전달된 함수가 Reactive context 안에서 실행됩니다.
effect()effect의 함수 본문이 Reactive context 안에서 실행됩니다.

Effect 내부에서 Signal을 올바르게 사용하기

import { effect } from '@angular/core';

constructor() {
  effect(() => {
    const x = mySignal(); // ✅ 정상적인 사용
  });
}

피해야 할 관행

Reactive Context 내부에서의 부수 효과 및 Signal 변이

// ❌ 안좋은 예: Reactive context 안에서 Signal을 생성하거나 업데이트
readonly x = signal(0);
readonly y = signal(0);

readonly c = computed(() => {
  const total = this.x() + this.y();
  return { sum: signal(total) }; // ❌ BAD practice
});

readonly x = signal(0);

readonly c = computed(() => {
  this.x.update(v => v + 1); // ❌ BAD practice
});

기타 금지 행위

  • Signal을 업데이트할 수 있는 API 호출
  • DOM을 직접 조작
  • 기존 effect 안에서 새로운 effect나 Signal을 생성하는 조건부 effect 사용
// ❌ 안좋은 예: 다른 effect 안에서 effect를 생성
effect(() => {
  if (this.x() > 10) {
    effect(() => console.log(this.x())); // ❌ BAD practice
  }
});

배치 (Zones 없이 Change Detection)

Angular은 여러 Signal 변경을 하나의 배치로 묶어 처리합니다. 이렇게 하면 불필요한 effect 재실행과 재계산을 줄여 성능이 향상됩니다.

  • Angular은 코드를 동기적으로 실행하면서 변경된 모든 Signal을 추적하고, 작업이 끝난 뒤 어떤 effect를 실행할지 체크를 예약합니다.
  • Effect 내부에서 Signal을 수정하는 것은 “너무 늦은” 작업으로 간주되어 순환 의존성이나 무한 루프를 초래할 수 있습니다.

Effect 사용 가이드라인

  • 목적: Effect는 다른 Signal에 영향을 주지 않는 부수 효과(예: 로깅, 렌더링, 로컬 스토리지 업데이트)에 사용합니다.
  • 피해야 할 것: Signal을 변경할 수 있는 비즈니스 로직을 트리거하는 행위. 어떤 서비스나 API가 Signal을 변이시킬지 보장할 수 없기 때문입니다.
  • 렌더링: 모든 Angular 템플릿은 본질적으로 effect처럼 실행됩니다. Signal이 변경되면 템플릿이 자동으로 재평가됩니다.

권장 Effect 패턴

import { effect } from '@angular/core';

// 로깅 예시
effect(() => {
  console.log('Current value of x:', this.x());
});

// 로컬 스토리지 업데이트
effect(() => {
  localStorage.setItem('x', JSON.stringify(this.x()));
});

참고 자료

Back to Blog

관련 글

더 보기 »

TypeScript 또는 눈물

프론트엔드 품질 게이트 또 보기: 백엔드 품질 게이트 백엔드 린터는 async footguns를 잡아냅니다. Type checkers는 runtime explosions를 방지합니다. 이제는 프론트엔드의…

UI 수정 요약

개요: 사용자 경험을 향상하고 깨진 기능을 수정하기 위해 여러 UI 개선을 구현했습니다. 구현된 변경 사항 1. 배경 설정 – “Add Fir...” 제거.

Hybrid developer란 무엇인가?

Hybrid Developer란 무엇인가? 오늘날 빠르게 진화하는 기술 세계에서, Hybrid Developer는 여러 기술이나 플랫폼에 능숙한 소프트웨어 개발자를 의미한다, enab…