본문 바로가기
Frontend/Angular

[Angular] 02. Signal

by jyc_ 2025. 1. 31.
 Angular 공식 문서를 실습하고 정리하는 글입니다.

 

Signal

  • Angular에서는 시그널을 이용해 state를 생성하고 관리한다.
  • 로컬 상태를 유지하는 함수를 생성하기 위해 시그널 함수를 사용한다.

특징

  1. 반응성: 시그널 값이 변경되면 이를 참조하는 부분이 자동으로 업데이트된다.
  2. set과 update 메서드를 통해 상태를 쉽게 관리할 수 있다.
  3. update메서드는 콜백 함수를 인자로 받는다. 콜백함수는 이전 값을 받아 새로운 값으로 반환한다.
  4. 시그널은 변경 사항을 효율적으로 추적하고, 불필요한 렌더링을 방지한다.
import {signal} from '@angular/core';

// 시그널 생성, 초기값을 인자로 전달
const firstName = signal('Morgan');

// 함수처럼 호출하여 현재 값을 읽을 수 있다. 'Morgan'이 반환된다.
console.log(firstName());

// set 메서드를 이용해 시그널의 값을 직접 변경
firstName.set('Jaime');

// 이전 값을 기반으로 한 시그널 값 업데이트
// update메서드는 콜백 함수를 인자로 받는다. 콜백함수는 이전 값을 받아 새로운 값으로 반환한다.
firstName.update(name => name.toUpperCase());

 

Computed Expessions

computed 는 다른 시그널을 기반하여 값을 생성하는 시그널이다.

import {signal, computed} from '@angular/core';

const firstName = signal('Morgan');
const firstNameCapitalized = computed(() => firstName().toUpperCase());
console.log(firstNameCapitalized()); // MORGAN

 

computed 시그널은 읽기 전용이기 때문에 set, update 메서드를 가지고 있지 않다.

대신, 참조하는 시그널이 변경되면 자동으로 변경된다.

import {signal, computed} from '@angular/core';

const firstName = signal('Morgan');
const firstNameCapitalized = computed(() => firstName().toUpperCase());
console.log(firstNameCapitalized()); // MORGAN

firstName.set('Jaime');
console.log(firstNameCapitalized()); // JAIME

 

컴포넌트에서의 신호 사용

컴포넌트 내부에서 signal, computed 시그널을사용하여 상태를 생성하고 관리할 수 있다.

@Component({/* ... */})
export class UserProfile {
  isTrial = signal(false);
  isTrialExpired = signal(false);
  showTrialDuration = computed(() => this.isTrial() && !this.isTrialExpired());
  
  activateTrial() {
    this.isTrial.set(true);
  }
}

 

실습

클릭 시 전구의 ON/OFF 상태가 바뀌는 토글 기능 구현

1. bulb-toggle.components.ts 생성

import { Component, computed, signal } from "@angular/core";

@Component({
    selector: 'bulb-toggle',
    template: `
    <p>Current Status: {{ bulbStatus() }} </p>
    <button (click)="toggleStatus()">Bulb Switch</button>
    `,
})
export class BulbToggleComponent {
    isOn = signal(false)
    bulbStatus = computed(() => this.isOn() ? 'ON' : 'OFF')

    // 상태 토글
    toggleStatus() {
        this.isOn.update((status) => !status)
    }
}

 

2. app.component.ts 파일의 imports 배열에 해당 클래스 추가

 

실행 결과