Web Components in 2019: Part 3
We round out the exploration of Web Components and identify deficiencies.

This article is part of a series starting with Web Components in 2019: Part 1.
Component Composition
note: The example in this article is available in the part3 branch of the larkintuckerllc/lwc-2019 GitHub repository.
While in this case it is overkill, let us break the functionality of our HelloWorld component into two components. We leave the logic of maintaining and incrementing the value in the HelloWorld component; src/index.ts:
note: In the React world, we would call this a container component
Observations:
- Observe that while we import the helloView module, we do not need to actually use any exported value. This is because the helloView module defines the hello-view tag which we use here
- While, like React, we use HTML attributes to communicate from parent to child components, we use standard browser custom (synthetic) events to communicate from child to parent (as opposed to passing callback functions as attributes with React)
We then implement the view functionality in src/helloView.ts:
note: In the React world, we would call this a presentational component
Observations:
- With the string value being in the returned array from the static observedAttributes method and case handled in the attributeChangedCallback, the displayed count is kept up to date with the component’s value attribute
- Again, we use standard browser custom (synthetic) events to communicate from child to parent component
Stepping Back
Let us step back a moment and consider what we have done (without any third-party libraries) using Web Components:
- We have a component solution; isolated HTML, CSS, and JavaScript
- We use familiar HTML / CSS markup to render the component
- We have component lifecycle events
- We compose components using familiar HTML markup
- We have reactive one-way data binding from parent to child components
- We have a familiar mechanism for child components to communicate up to parent components
Slots
One thing that we did not cover was how a parent component can pass HTML markup to a child component; e.g., in React this is just the children prop. For Web Components there are slots.
The MDN article Using templates and slots — Web Components explains slots in detail.
So What are We Missing?
Now that we have been living with a robust component-based front-end framework, i.e., React, for a number of years, we can make some comparisons to identify things that we are missing with Web Components.
- One-way data binding (component to DOM): In our counter example, we were required to imperatively set a DOM element’s textContent
- Event listener management: In our counter example, we were required to both add and remove listeners
- Virtual DOM Like Pattern: React’s Virtual DOM plays an important role in simplifying development. In our counter example, we rendered the template once and subsequently imperatively set a DOM element’s textContent
- Solutions for Cross-Cutting Concerns: React has advanced patterns, Higher Order Components, Render Props, and Hooks, for handling cross-cutting concerns. With Web Components, it is unclear how approach these sorts of problems
Next Steps
In the next article, Web Components in 2019: Part 4, we explore third-party libraries that address these identified deficiencies.