React vs. Angular components – Part 4

This is a series of posts about comparison between components in Angular and React. The idea of these posts is not to judge which one is best, bur rather to show how these two cope with some typical problems and how we, developers, can use them. In the first three parts (Part 1, Part 2, Part 3) I talked about the starting points – how to create a component, how to attach a template to it, how to do data binding. In this fourth part I am going to deep a bit more into the lifecycle of these components. I will discuss what opportunities and points of extensibility one can find in Angular and React and how one can benefit from them.

What is a lifecycle?

Before I start with the real discussion I want to say a few words about what a lifecycle is. We, humans, live in a specific environment (the surrounding world). We appear as babies and diminish at some point of time. The same process is applied by frameworks: a component lives in a specific context, generated by the framework; a component typically has a beginning and an end, determined again by the framework (which acts based on some events). The whole period from the creation of one component, its life, to its end is the lifecycle of that component. During that period the component can change in one or another way.

Lifecycle diagram

Component lifecycle

We have already seen how to create components in both Angular and React. In the former we would use

, while in the latter –

. Note that by doing this we define a component, i.e. we create a template definition (not to be confused with a HTML template) that the framework can use to create instances of that component.

React

React works with a Virtual DOM so it is very important to be able to do comparisons with the real DOM at any time in order to decide whether to update it. A React component has three main lifecycle phases:

  • Mounting – initializing the component and render it for the first time
  • Updating – updating the component and re-rendering it (f.x., when the state has changed)
  • Unmounting – unloading the component

During these three phases one can inject code at specific points in order to control the behavior of the component. The main such points are:

  • – invoked only once before the initial rendering of the component.
  • – invoked only once after the initial rendering of the component.
  • – invoked before the re-rendering of the component. Warning: you cannot use here.
  • – invoked after the re-rendering of the component, i.e. when the DOM has been updated.
  • – invoked only once before the removal of the component.

The following example demonstrates the order of execution of these points (JSFiddle).

Mounting
  • Parent: getInitialState()
  • Parent: componentWillMount()
  • Parent: render()
    • Child: getInitialState()
    • Child: componentWillMount()
    • Child: render()
    • Child: componentDidMount()
  • Parent: componentDidMount()
Updating
  • Parent: shouldComponentUpdate()
  • Parent: componentWillUpdate()
  • Parent: render()
    • Child: componentWillReceiveProps()
    • Child: shouldComponentUpdate()
    • Child: componentWillUpdate()
    • Child: render()
    • Child: componentDidUpdate()
  • Parent: componentDidUpdate()
Unmounting
    • Child: componentWillUnmount()
  • Parent: componentWillUnmount()

Angular

Angular works directly with the DOM, so that requires a different mechanism. In order to improve performance and memory usage, Angular does a two-phase processing of a directive:

  • Compilation – for each directive definition Angular compiles its template and returns a function that will provide its template – a linking function
  • Linking – binds the created by the compiler DOM element with a scope

One would typically deal with the linking phase by default. The

function of the directive definition provides access to both the DOM element and the scope bound to it. Let’s take a look at a similar example of a parent – child dependence in order to examine the order of execution of the main points of injection (JSFiddle).

Compilation & linking
  • Parent: compile()
    • Child: compile()
  • Parent: pre()
    • Child: pre()
    • Child: post()
  • Parent: post()

Angular does not really have an update phase, as all updates happen locally – at the bindings. If you change the value of a bound property from the scope, then all individual places on UI will be updated. This is due to the Observer pattern implementation of Angular. The

linking function is executed before the linking and the

linking function – after the linking. If you don’t want to override the

function, you could just override the

function, which is by design the post linking function. The removal of a directive happens when both its scope and the associated DOM element are destroyed. One can attach to

in order to perform custom logic on destroy.

Conclusion

Due to their different nature Angular and React manipulate components in a very different way. One must know the precise lifecycle of a component in order to make decisions for where to place a specific piece of code. I hope that I have managed to give you an idea of how two of the most popular JavaScript frameworks deal with that. If you have any questions, you are more than welcome to ask them in the comments below 🙂