본문 바로가기

개발 공부/Angular

Angular computed()

 

computed()

computed()는 하나 이상의 signal() 값에 의존하여 계산된 값을 자동으로 업데이트해주는 함수입니다.

computed()는 파생된 상태를 선언적으로 정의할 수 있는 핵심 도구로, 코드의 복잡도를 낮추고 예측 가능성을 높여줍니다.

const count = signal(2);

const doubled = computed(() => count() * 2);

console.log(doubled()); // 4
count.set(4);
console.log(doubled()); // 8 (자동 업데이트)
  • count라는 상태가 바뀔 때마다 doubled라는 값이 자동으로 다시 계산된다는 걸 보여줍니다.

 

왜 computed()를 쓰는가?

get currentTabKey() {
  return this.tabList()[this.currentTabIndex()].key;
}
  • 이것도 동작하지만, getter는 호출될 때마다 무조건 계산을 다시 합니다.
  • 반면 computed()는 의존한 signal이 바뀌지 않으면 캐싱된 값을 반환하기 때문에 성능 측면에서 효율적입니다.

 

항목 getter computed()
호출 시 무조건 계산 O X(변화 있을 때만)
반응형 연결 X O
템플릿에서 직접 사용 계산만 가능 signal로 연결 가능

 

 


 

구성 요소 비교

구분 역할 예시
signal() 상태 저장 const count = signal(1);
computed() 상태를 기반으로 파생된 값 계산 const double = computed(() => count() * 2);
effect() signal 또는 computed가 바뀔 때 부수효과 실행 effect(() => console.log(count()));

 

 

 

 


 

예제: 탭 키 동기화

컴포넌트에 여러 탭이 있다고 해볼게요. 우리는 선택된 탭의 key 값을 계산해서 어딘가에 표시하거나 로직에 활용하고 싶습니다.

이걸 RxJS로 하면 BehaviorSubject랑 combineLatest 같은 걸 써야 했지만, Signal을 사용하면 이렇게 간단하게 처리됩니다

export class TabComponent {
  // 탭 리스트
  tabList = signal([
    { key: 'home' },
    { key: 'settings' },
    { key: 'profile' }
  ]);

  // 현재 탭 인덱스
  currentTabIndex = signal(0);

  // 현재 탭의 key를 자동으로 계산
  public currentTabKey: Signal<string> = computed(() => {
    return this.tabList()[this.currentTabIndex()].key;
  });

  // 탭 변경 메서드
  nextTab() {
    const next = (this.currentTabIndex() + 1) % this.tabList().length;
    this.currentTabIndex.set(next);
  }
}

 

 

HTML 템플릿

<p>현재 탭 키: {{ currentTabKey() }}</p>
<button (click)="nextTab()">다음 탭</button>
  • currentTabKey는 signal이기 때문에, currentTabKey() 처럼 함수처럼 호출해서 값을 읽습니다.

 

 

실수하는 패턴

아래처럼 사용하는 건 권장되지 않습니다

const wrong = signal(computed(() => count() * 2)); // 의미 없음

 

  • 이렇게 되면 wrong()을 호출하면 Signal<number> 객체가 나오고, 실제 값은 wrong()()처럼 이중 호출해야 얻을 수 있어서 매우 비직관적입니다.