polymerweb-componentlit-elementpolymer-3.xlit-html

Polymer/Lit-element, child component doesn't re-render when the property is modified by the parent



live example

Basically:

//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:

What am I missing here?


Solution

  • 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.