본문 바로가기
Angular.js

[Angular] ChangeDetectionStrategy & ChangeDetectorRef

by 찬찬2 2023. 1. 20.

(추가_공식문서) https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/

 

1. ChangeDetectionStrategy 

- 데이터의 변경/업데이트/수정 내용을 감지하고 컴포넌트의 상태를 업데이트한다.

 

@Component 데코레이터에서 사용하는 메타데이터는 다양하다. 그 중 changeDetection에 대해 알아보자.

우선 해당 프로퍼티에 대한 값으로면 @angular/core에서 제공하는 ChangeDetectionStrategy 객체만 올 수 있다. 그리고 이 객체에는 OnPush, Default 두 개의 키와 값이 들어있다.

 

OnPush : (CheckOnce) 컴포넌트에서 실제 레퍼런스(객체 비교)가 변경되었는지를 확인하고 변경되었을 경우에는 하위 컴포넌트에게 변경감지 프로세스를 수행시키도록 하는 역할을 한다.

Default : (CheckAlways) 하위 컴포넌트들에 대한 변경감지 프로세스를 항상 수행하도록 한다.

 


 

OnPush의 동작방식을 이해하기 위한 예제 코드는 참고링크를 참고.

 

여기서 핵심은 객체의 비교방식에 대한 이해가 있어야 한다. (shallow comparison & deep comparision, 얕은 비교 & 깊은 비교)OnPush가 정상적으로 작동되기 위해서는 데이터(객체)의 참조값이 변경되어야 한다. 즉, 기존 객체를 복사하고 새로운 객체를 만들어 복사한 값을 넣어주는 방식으로 진행되어야 한다. (React의 state 업데이트 시 주의해야할 부분과 동일)

 

/* 기존 객체의 키값 변경 */
const person = {
    name: "chanki",
    age: 24
};
person.age = 35;


/* 새로운 객체 생성 */
const person = {
    name: "chanki",
    age: 24
};
const newPerson = {
    ...person,
    age: person.age + 10
}

 


 

2. ChangeDetectorRef

ChangeDetectorRef는 변경감지를 세밀하게 할 수 있도록 Angular에서 지원하는 도구이다.

 

"Base class that provides change detection functionality. A change-detection tree collects all views that are to be checked for changes. Use the methods to add and remove views from the tree, initiate change-detection, and explicitly mark views as dirty, meaning that they have changed and need to be re-rendered."

 

Angular는 change-detection tree라는 개념이 있다. 데이터가 변경되었을때 어떻게 처리할지 tree형식으로 구조를 만들어내어 감지/처리하는 것 같다. (React의 재조정단계와 비슷한 개념인 것 같다.)

tree 구조이기 때문에 Angular는 데이터가 변경될 경우 변경된 데이터를 업데이트하기 위해서 위에서 부터 아래로 감지하는 프로세스가 실행된다. 그렇기 때문에 성능저하가 발생할 수 있다.

아하~ 그래서 리렌더링될 컴포넌트를 "mark view as dirty" 하는구나. (dirty라는 표현은 좀...)

 

abstract class ChangeDetectorRef {
  abstract markForCheck(): void
  abstract detach(): void
  abstract detectChanges(): void
  abstract checkNoChanges(): void
  abstract reattach(): void
}

 

ChangeDetectorRef 클래스에는 5가지 메서드가 존재한다. 이 중 detach, reattach, detectChanges를 먼저 알아보자.

 

기본적으로 ChangeDetection 전략은 동적으로 작동될 수 없지만, ChnageDetectorRef를 사용해 on/off 하여 change detection tree에 붙이고 땔 수 있다.

우선 ChangeDetectorRef가 사용되어지기 위해서는 @Component에 changeDetection 메타 데이터가 설정되어 있어야 한다. (ChangeDetectionStrategy.OnPush)

 

① detach는 change-detection tree에서 때어내는 역할

② reattach는 change-detection tree에 다시 붙이는 역할

③ detectChanges는 detach와 같이 사용되어지며, detach에 의해 tree에서 제외되어 있지만, 자식들에게 컴포넌트의 데이터 변경은 감지하여 view에서는 변경된 데이터가 보여진다. 다시말해, 변경감지 프로세스를 작동시킨다.

④ markForCheck

"Components are normally marked as dirty (in need of rerendering) when inputs have changed or events have fired in the view. Call this method to ensure that a component is checked even if these triggers have not occurred."

input이 바뀌거나 이벤트가 발생하지 않았더라도 markForCheck를 실행시키면 해당 컴포넌트는 "marked as dirty"다. 즉, 변경감지 트리에 포함시킨다는 말이다.

 


 

ChangeDetectionStrategy는 언제 사용할까?

데이터가 변경되는 경우는 크게 3가지이다.

 

① @Input으로 부모로 부터 데이터를 전달받았을때

② Observable, stream에 의해

③ event가 발생했을때

 

** 다른 블로거님 글 보기

 

 

 

 

댓글