Angular 5.0 change detection strategy VS React's change detection strategy
React and Angular’s change detection are different, but they have in common one very important thing - making diff of current and previous state from memory (not from DOM) and rendering only what has been changed.
In Angular, on high level it works like this:
- Change detection is triggered by zone.js at the end of each call stack in the zone. It means that after callback to every async action (click, http request, timeout) is executed, change detection is triggered. You can trigger change detection also manually, or even „turn off” zone.js, but let’s stick with most common scenario.
- Change detection starts from the root component and it goes down through the components tree (again, You can trigger it manually on any component, but that’s not the most common case).
- Traversing components tree, it checks which values in component templates need to be updated and updates the DOM.
NOTE: Mind that if You use ChangeDetectionStrategy.OnPush, some components and its descendants might be omitted during tree traversal. It can be great optimization.
In React it looks like this:
- Change detection is not triggered after callbacks of async actions. It’s triggered by calling method setState on component.
- Change detection starts not from the root component, but from component in which
setState
was called. - Reconciliation phase begins - component and it’s descendants are traversed for checking which values needs to be updated in real DOM. So, conceptually, this point is very similar to Angular. However in React 16 it’s a little bit more complicated. Check it.
- Dom is updated.
NOTE: Similar to Angular’s ChangeDetectionStrategy.OnPush, in React we have class React.PureComponent. We can use this class to avoid unnecessary change detection.
Of course there's lot more differences, but on high level, I think those are the most important.
React change detection is more or less the same as Angular, except three things:
1) when to start: the diffing starts whenever a component's setState method is called (whereas Angular does the diffing whenever a Dom event is triggered, whenever a setInterval/setTimeout callback is run, and whenever an ajax callback is run)
2) where to start: the diffing starts from the component that has the setState called, then its children, and down the hierarchy (whereas Angular starts from the very top component)
3) what to compare: the diffing compares the virtual DOM of the current HTML with the virtual DOM after the state change. (whereas Angular uses the data-bound values used in the template, before and after, for comparison)