4

I was trying to build a tab component in Angular and Vue. Vue screamed (threw an error in the console) when I changed the component's props. Angular seems fine with it.

<tab [active]="true"></tab>

export class TabComponent implements OnInit {
  @Input() name: string;
  @Input() active = false;

  ngOnInit() {
    // Here I am mutatating an input property which is bad because, 
    // further changes to that input doesn't take effect

    this.active = false;
    console.log({name: this.name, active: this.active});
  }
}

I personally think it's not right to modify a component's input property. My question is why the Angular team doesn't enforce that by throwing an error in the console.

Vue will display this message

vue.js:634 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "selected"

David Blay
  • 527
  • 1
  • 3
  • 14
  • Show some code. It’s unclear what you mean..? – MikeOne Apr 18 '20 at 21:52
  • @MikeOne hope this code sample helps. Thanks – David Blay Apr 18 '20 at 23:38
  • Thanks. You cannot compare Vue props with Angular this way, there are valid scenarios in which you want to ‘mutate’ your input inside your component. For example, the input could be a one-off config object or value that can be used to set an inital variable, but can later be changed. The input is only set once by angular (which is not the same as a prop in Vue). Of course - non-mutable is good practise in general, but this definitely should not give a warning in Angular. – MikeOne Apr 19 '20 at 11:48
  • 1
    @MikeOne ohk so it's by design. I realized that during my development. Where mutating an input property prevented it from receiving future changes. Thanks for that clarification – David Blay Apr 20 '20 at 03:38

1 Answers1

3

The advice in the Vue warning applies to the angular component just as well. Inputs should be treated as immutable because you can't keep them from being overwritten by a parent component. If you want to use props to initialize state, you should have a separate internal state field that you initialize in one of the lifecycle hooks (e.g. OnChanges or OnInit).

I've gotten in the habit of marking all my inputs as read-only so I'm not tempted to mutate them.

John Dengis
  • 192
  • 1
  • 8