에러 백과

허용되지 않은 컨텍스트에서 시그널 값 쓰기

computed나 템플릿을 평가하는 동안 set 또는 update로 시그널에 값을 쓰면 Angular가 이 오류를 발생시킵니다. 두 컨텍스트는 시그널을 읽기만 해야 하므로 여기서 쓰기를 수행하면 계산 도중 상태가 바뀝니다.

오류 메시지에 두 경우 중 어느 상황인지 표시됩니다.

computed에서는 시그널에 값을 쓸 수 없습니다

computed는 부수 효과 없이 다른 시그널에서 값을 도출해야 합니다.

count = signal(1);
total = signal(0);

doubled = computed(() => {
  this.total.set(this.count() * 2); // not allowed
  return this.count() * 2;
});

값이 다른 시그널에만 의존한다면 별도로 저장하지 말고 그 자체를 computed로 만드세요.

count = signal(1);
total = computed(() => this.count() * 2);

값을 직접 쓸 수도 있어야 한다면 linkedSignal을 사용하고, 쓰기가 변경에 따른 부수 효과라면 effect를 사용하세요.

linkedSignal 계산 안에서 값을 쓸 때도 같은 오류가 발생합니다.

Angular가 템플릿을 렌더링하는 동안에는 시그널에 값을 쓸 수 없습니다

템플릿 표현식은 렌더링 중 실행되므로 템플릿에서 호출하는 메서드도 시그널에 값을 쓰면 안 됩니다.

@Component({
  selector: 'app-example',
  template: '<p>{{ label() }}</p>',
})
export class Example {
  views = signal(0);

  label() {
    this.views.update((v) => v + 1); // not allowed
    return `Viewed ${this.views()} times`;
  }
}

실제로 변경이 일어나는 위치로 쓰기 작업을 옮기세요. 이벤트 리스너, 라이프사이클 훅, 출력 핸들러, 이펙트 함수에서는 시그널에 값을 쓸 수 있습니다.

untracked 사용하기

untracked로 감싼 쓰기 작업은 오류를 발생시키지 않습니다. 의도적인 쓰기이며 다른 곳으로 옮길 수 없을 때만 사용하세요. untracked 안에서 읽은 시그널도 추적되지 않는다는 점에 유의하세요.

오류 디버깅하기

스택 트레이스는 set 또는 update 호출을 가리킵니다. 여기서 해당 호출을 실행한 computed, linkedSignal, 템플릿 표현식을 찾으세요.