Basically:
I place the child component inside the parent's html.
The child component has a property title
inside the static get properties()
object.
In the parent component, i assign the child component's title
property to a private variable that is not in the static get properties()
of the parent component.
Later, in a setTimeout
inside the parent component, i change the value of the private variable.
The child component doesn't re-render.
//inside parent component
render(){
return html`
<child-component title="${this._privateVariable}"></child-component>
`
}
constructor(){
super();
this._privateVariable = 'lore ipsum'
setTimeout(()=>{
this._privateVariable = '123455667'
}, 10000)
}
Now, i know that if i put the _privateVariable
in the static get properties()
of the parent component, the child re-renders, but that's because the whole parent is re-rendering.
Once attached to the DOM, the child component is watching his title property, so it should realize that the value assigned to it changed and re-render.
I don't understand why i have to re-render the whole parent to make the child re-render.
Using the developer console and accessing the component in the DOM:
If i change the child component's property with javascript, the child re-renders perfectly fine, without me having to re-render the whole parent element.
If i edit the child component's html and manually change the attribute, the child re-renders perfectly fine, without me having to re-render the whole parent element.
What am I missing here?
I answered on GitHub: https://github.com/Polymer/lit-element/issues/899#issuecomment-592295954
But here's a copy for other readers:
@dvolp the child component is observing its title property, but it's not observing the parent component's _privateVariable property. And without declaring _privateVariable as a LitElement property in the static properties object, the parent component isn't observing that property either.
You need to re-render the parent when you set _privateVariable because re-rendering is what sets the child's title property to the current value of _privateVariable.
The binding in here only runs on a render. If this isn't run, there's nothing else to set the title property:
//inside parent component
render(){
return html`
<child-component title="${this._privateVariable}"></child-component>
`
}
This is exactly why you must include _privateVariable in the static properties object of the parent, so that when you set it, the parent component is notified and re-renders, which in turn sets the title property on the child component.