DEV Community

Arthur Christoph
Arthur Christoph

Posted on • Updated on

Vue, Angular, React Comparison Series: computed property

Alt Text

Versions used are:
Vue 2.x , React 16.8.x, Angular 9.x

What is a computed property

When rendering value of a property on template, it can be either a simple value like string, number, a single expression or a result of a more complex computation that can be expensive to perform. A computed property does caching when the input stays the same so that the performance can be much better in a heavy computation scenario.

In the example below, there are two values that we want to display:

  • name property which is initialized to a value
  • fullname property is the computed property that depends on name property. Every time name is updated, the updated fullname should be rendered.
  • getFullname() method is a regular method that shows what would happen without caching
  • count property triggered by Count button is used to trigger template rendering every time the count value is incremented, so that we can see what happens to fullname property when rendering happens outside of its dependency scope.
  • counter property is an object with a primitive value property called count. This is to show the case where the dependent is an object
  • Change Name button is used to modify name property once, to show that a computed property is recalculated when its dependents modified.

Vue

In Vue, to display complex expression, we can use: computed, methods, filters
A method defined in computed is cached and only called again when the dependents are changed; a method defined in methods and filters are always called every time the render happens - every time count is incremented. Vue computed property is either doing a deep comparison or recreate this.counter to compare by reference for object type, as we can see that this.counter.count is just simply updated on the template without any issue.

computed: {
    fullname() {
      console.log("render fullname");
      return `${this.name} framework`;
    }
  },

React

In React, we have: useMemo and regular function
useMemo only recomputes when its dependency: name is changed.
Since useState assign a counter object with the incremented count, the object change by reference can be performed and render the updated value of this.counter.count

const fullname = useMemo(() => {
    console.log("render fullname");
    return `${name} library`;
  }, [name]);

Angular

In Angular, we have: Pipe which is the equivalent of Vue's filters but has caching feature. Angular pipe is pure by default, so if the input is an object instead of primitive type like string, the comparison by reference is performed.
Using impure pipe, we can detect object mutation. As we can see in the example, if the pure is set to false, then the counter pipe can detect the counter object change.

@Pipe({ name: "getFullNamePipe" })
export class getFullNamePipe implements PipeTransform {
  transform(name: string): string {
    console.log(`Pipe as Angular's computed property`);
    return `${name} framework`;
  }
}

Top comments (0)