To be more explicit, the child component creates a property which is dependent on the argument passed by the parent component. I am not using the parent argument directly in the child template (this case works just fine).
Coming from a React background, my mental model suggests new arguments passed to a component will trigger re-render. But I am aware Glimmer does things differently with its @tracked
decorator.
Okay, here is the contrived example. For a demo, head to the Glimmer Playground.
// parent-template.hbs
<button onclick={{action doubleNumber}}>Double Number</button>
<div>
Parent - {{number}}
</div>
<Child @number={{number}} />
// parent-component.ts
import Component, { tracked } from '@glimmer/component';
export default class extends Component {
@tracked number = 2;
doubleNumber() {
this.number = this.number * 2;
}
}
// child-template.ts
<div>
Child will render double of parent {{doubleOfParent}}
</div>
// child-component.ts
import Component, { tracked } from "@glimmer/component";
export default class extends Component {
args: {
number: number;
}
get doubleOfParent () {
return 2 * this.args.number;
}
};
Here the parent displays the doubled number on every click of the button. But the child never re-renders?
My question is do we always need to have the tracked
variable inside the template. In this case number
. And express the child template like this
<div>
Child will render double of parent {{double @number}}
</div>
Here double
is helper which doubles the number.
If it is so what is the reason behind having the tracked
properties/argument in the template?
It looks like your doubleOfParent()
method is missing a @tracked
annotation since its output depends on the args
property:
import Component, { tracked } from "@glimmer/component";
export default class extends Component {
args: {
number: number;
}
@tracked('args')
get doubleOfParent() {
return 2 * this.args.number;
}
};
you can find more information on this topic at https://glimmerjs.com/guides/tracked-properties