DEV Community

Discussion on: Let's Build Web Components! Part 5: LitElement

Collapse
 
jimisdrpc profile image
jimisdrpc

Congratullations! Excellent article! You wrote "Unlike Polymer elements, with their two-way-binding templates, lit elements are particularly well suited to the types of one-way data flows popularized by the React/Redux pattern and others". Do you mean that lit elements isn't well suited for a webcompnent where the user enters data? You mentioned stock. I can imagine easily a webcomponent exposing stock status as an one-way (only from server to front). And if you was webcomponent for a shopping (from front to server)? Wouldn't you recommend lit-html? If so, what do you recomend if I want to create a webcomponent to be part of my corporarte webcomponet library and used for user inputs?

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

Do you mean that lit elements isn't well suited for a webcompnent where the user enters data?

Just the opposite. Because of the one-way data flow, lit-html encourages you to explicitly and declaratively handle user input.

Polymer-Style Two-Way

<my-input value="{{theValue}}"></my-input>

At any given moment, what does theValue represent? Is it the state held by the parent and passing down to the child? Is it the new input being sent up to the parent by <my-input>?

One-Way Binding with lit-html

html`<my-input .value="${theValue}" @input="${onInput}"></my-input>`

Here, the developer knows exactly what's happenning. theValue is only ever passed down to <my-input>. input events are handled by onInput (which might set the state in the parent, or in a state container, or whatever you choose)

So for your company's component library, I recommend either implementing a decorator component:

<my-input>
  <input/>
</my-input>

Or implementing <input> in the root of <my-input>, and listening for the composed change event on that. Make sure to handle your state internally, e.g.

class MyInput extends LitElement {
  @property({type: String}) value = '';
  onInput({ target: { value } }) { this.value = value }
  render() {
    return html`
      <input
          .value="${this.value}
          @change="${this.onInput}"
      ></input>`
  }
}