Angular: why does view get re-rendered even when change detection detects no change?

Viewed 85

Component:

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  //name = 'Angular';

  onClick(){
    //this.name = 'hey';
  }

  check(){
    console.log('wow');
  }
}

Template:

<button (click)="onClick()">Click</button>
{{check()}}

When I run this, 'wow' gets printed on the console initially 4 times (not sure why 4 times, but let's leave that). The main thing is that when I click on the button, 'wow' gets printed (twice) even though I have changed nothing in the template expressions.

As I understand it, when an event, etc occurs, change detection takes place which compares fields used in expressions and property binding in template. If a change is detected, the view is re-rendered. But in this case, the view is being re-rendered (as shown by the calling of check method) even when no change should have been detected

Stacklitz here

1 Answers

In the angular documentation for the ChangeDetectorRef it mentions

Components are normally marked as dirty (in need of rerendering) when inputs have changed or events have fired in the view.

So in this case, since you have triggered the click event, the view is marked as dirty and will re-render.

If you are looking for a fix then you can use changeDetection: ChangeDetectionStrategy.OnPush or you can dive a little deeper into the ChangeDetectorRef and turn off change detection on certain components.

If you are looking for more of an overview of change detection I would recommend this article.

If you want to know the lifecycles that are causing this to happen they are AfterViewChecked and AfterContentChecked

Related