In some places mixing JS code with XML values is a mess.

A matter of taste.

Round III: Change detection

Let's state here one important thing - DOM update (after change was detected) is handled similarly in both frameworks. They update only the parts that actually should be changed. We'll see now what is the difference in detecting if a change have occurred.

React

React basic mechanics are simple. If state or props of component where changed - change handlers are called:

state triggers change when setState() method is called

props change occurs when parent component re-renders

There is also possibility to trigger change by calling forceUpdate() . Change detectors are triggered only in subtree where change occurred. Simple and optimal. The only little downside is that we would have to setState() manually in the root vertex of our arborescence.

You probably have noticed a key={todo.id} prop in examples. It's the mechanism used for detecting changes of list elements. If a value passed to key property has changed - the HTML representing a related element is re-rendered. Quite verbose, but sane. Downside - when using a strict typing in your projects, you'll be forced to define a key: string; additional property on all your "listed" components.

Angular

Angular team decided to choose a slightly different approach. They have incorporated zone.js to plug into asynchronous browser callbacks (setTimeout, setInterval, event handlers and XMLHttpRequest events). And when any of these is called Angular runs change detection. You can find great in-depth explanation here. What is more interesting - you can decide to choose a change detection strategy on any component of your application tree.

In the example application I used an OnPush strategy so all my components check for updates only when any of their @Input() properties have changed. So a change detection in my Angular application acts almost exactly as in React one. There are actually few more strategies: CheckOnce , Checked , CheckAlways , Detached , OnPush and Default . For some explanation see ChangeDetectionStrategy docs.