Web Component: Why You Should Stick to React

By Nathan Sebhastian

Nathan Sebhastian
Image for post

There’s an interesting discussion on the Internet about how , and that popular tools like React and Vue will slowly become obsolete like MooTools and jQuery.

Maybe you want to use React for your web application projects, but fear that it’s going to be replaced by Web Components. This article will help you alleviate that fear by learning the difference between Web Components and React.

The purpose of Web Components

Web Components is a set of different technologies that are used together to help developers write UI elements that are semantic, reusable, and properly isolated.

  • A custom element is a way of defining an HTML element by using the browser’s JavaScript API. A custom element has its own semantic tag and lifecycle methods, similar to a React component
  • Shadow DOM is a way of isolating DOM elements and scoping CSS locally to prevent breaking changes from affecting other elements.
  • HTML template is a way of writing invisible HTML elements that acts as a template that you can operate on using JavaScript’s query selector.

Let’s learn how each of these technology actually works with code examples.

A custom element example

Web Component’s custom elements are created by using the browser’s JavaScript API. A custom element is defined using JavaScript’s class keyword that extends HTMLElement. Once defined, the custom element can be reused as many times as you need in your application:

A custom element name must include a dash or the browser will complain that you have an invalid element name. You need to name a button as <primary-button> or <button-component> instead of just <button>.

Custom elements also have for running code during specific times of its existence. These lifecycle callbacks work in a similar way to .

As of today, you need to write custom elements

The shadow DOM example

Shadow DOM allows you to write HTML elements that were scoped from the actual DOM tree. It’s attached to the parent element, but won’t be considered as its child element by the browser. Here is an example:

Any code you write inside the shadow DOM will be encapsulated from the code outside of it. One of the benefits of using shadow DOM is that any CSS code you write will be local and won’t affect any element outside of it.

When you inspect the shadow element, you’ll see it marked with #shadow-root:

Image for post

The browser will return null when you try to select the shadow button with document.getElementById(‘shadow-button’) . You need to select the parent element and grab its object first:

const el = document.getElementById('example').shadowRoot
el.getElementById('shadow-button')

HTML template example

HTML template allows you to write invisible HTML elements that you can iterate through with JavaScript in order to display dynamic data. To write one, you need to wrap the elements inside a <template> tag:

<template id="people-template">
<li>
<span class="name"></span> &mdash;
<span class="age"></span>
</li>
</template>
<ul id="people"></ul>

Then you can iterate through the template above with JavaScript selector and append it into the <ul> element :

const fragment = document.getElementById('people-template');
const people = [
{ name: 'Daniel', age: 22 },
{ name: 'Jessie', age: 29 },
{ name: 'Andy', age: 32 }
];
people.forEach(person => {
const instance = document.importNode(fragment.content, true);

instance.querySelector('.name').innerHTML = person.name;
instance.querySelector('.age').innerHTML = person.age;

document.getElementById('people').appendChild(instance);
});

By using the template, you can fetch data from an API server and use the template to serve the data in a structured way.

Now that you know what and how Web Components work, it’s time to answer the question.

Will Web Components replace React?

A modern front-end application needs more than just components. The great thing about React is that it keeps your components in sync with your data.

When compared with Web Components, React has the following advantages:

  • Allows you to change the underlying data model with state
  • Trigger UI changes based on the state
  • Writing components using functions and hooks
  • A ready to use unidirectional data flow
  • A greater ecosystem of third-party libraries and guides

React’s eco-system is incredibly vast — so much so that it is now possible to use React for everything: Dynamic SPAs, Static pages, Native Android/iOS apps, Windows/Mac desktop apps, CLI apps, etc.

That means two things:

  1. You can learn once and build for multiple platforms
  2. You can build once and reuse across different apps

Sharing components (and reusing them across apps) is now easier than ever with tools like () that allow you to track components independently and share them, from any project, to a single component hub.

Image for post
Exploring shared React components on

React’s underlying data model with state and props allows its components to change the rendered elements on the screen without imperatively manipulating the DOM or changing attributes manually. When you change the state, React will automatically re-render the components to trigger UI changes.

React also allows you to write components using functions and hooks. When it first came out, hooks are a big improvement to React because it reduces the complexity of managing a component’s lifecycle. It also enables you to write stateful components using functions, completely removing the need to use classes, which confuses both people and machines.

Furthermore, functional components in React are easier to maintain because of the way useEffect hook gather related logic under one function. For example, when using class components in React, :

class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}

But with hooks, you can have a useEffect function in a single function:

import React, { useState, useEffect } from 'react';function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

When using class components, you need to group unrelated code under the same lifecycle method because that’s the only place where you can run the code reasonably, such as fetching data and setting up listener on componentDidMount:

componentDidMount() {
// Putting data fetching and listener in the same function
axios.post();
DataSource.addChangeListener(this.handleChange);
}

With useEffect hook, you can separate this unrelated code but run them on the same lifecycle:

// separating functions to minimize confusionuseEffect(() => {
axios.post();
});
useEffect(() => {
DataSource.addChangeListener(this.handleChange);
});

As a library for building complete web applications, React also offers a , where data is passed down from parent components to children components with props. Web Components currently requires you to write your own data binding pattern.

Finally, React has a big collection of third party libraries to help developers with the most common application features like:

Of course, Web Components may replace React when there is enough support for all of these development needs, but I’m certain by then Web Components won’t be what we know today. Just like React, it will have supporting libraries and even visual builders to allow developers to build applications easier.

Even then, don’t forget that . It’s more likely that Web Components will one day become an alternative option for developing web applications, rather than replace the need for libraries entirely.

Conclusion

Web Components is a set of different technology being used together to help you write reusable elements that are encapsulated from the rest of your code. On the other hand, React is a JavaScript library meant to help you write user interface in a declarative way.

A scalable modern front-end development requires many other things besides components. That’s why you don’t have to be afraid to use React and its ecosystem of tools and libraries. It surely won’t be replaced by Web Components anytime soon.

Learn More