Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Because React is good enough. I think that's mostly why.

Here's legacy React's like_button.js, without JSX, from their old documentation:

    'use strict';

    const e = React.createElement;

    class LikeButton extends React.Component {
      constructor(props) {
        super(props);
        this.state = { liked: false };
      }

      render() {
        if (this.state.liked) {
          return 'You liked this.';
        }

        return e(
          'button',
          { onClick: () => this.setState({ liked: true }) },
          'Like'
        );
      }
    }

    const domContainer = document.querySelector('#like_button_container');
    const root = ReactDOM.createRoot(domContainer);
    root.render(e(LikeButton));
Here's the equivalent using the Web Components specification[1]:

    // https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements
    // Create a class for the element
    class LikeButton extends HTMLElement {
      static get observedAttributes() { return ['liked']; }

      constructor() {
        // Always call super first in constructor
        super();

        this.liked = false;

        // Create a shadow root
        /* const shadow = */ this.attachShadow({mode: 'open'});
      }

      get liked() { return this.hasAttribute('liked'); }
      set liked(state) { this.toggleAttribute('liked', Boolean(state)); }

      attributeChangedCallback(name, oldValue, newValue) {
        this.render();
      }

      connectedCallback() {
        this.render();
      }

      render() {
        const shadow = this.shadowRoot;

        if (this.liked) {
          shadow.innerHTML = 'You liked this.'
          return;
        }

        shadow.innerHTML = `<button onclick="this.parentNode.host.liked = true;">
      Like
    </button>`;
      }
    }

    // Define the new element
    customElements.define('like-button', LikeButton);
The React API is slightly nicer to use, especially with JSX.

[1]: https://github.com/andrewmcwatters/custom-elements



Can be reduced

    customElements.define('like-button', class LikeButton extends HTMLElement {
        connectedCallback() {
            this.innerHTML = '<button></button>'
            this.addEventListener('click', this.onClick, true)
        }
        onClick() {
            this.innerText = 'You liked this'
        }
    })


Examples like this bug me. The React example is using a high level abstraction, the web component is directly using the API. A more accurate example would show how those React calls eventually boil down to document.createElement()

I don’t think the Web Components API was meant to be used directly all the time. You can use a framework like StencilJS:

https://stenciljs.com/

When you consider the 100KB of bulk the React example brings with it the web component example is actually pretty impressive.


The latter doesn’t have any dependencies or a build step though right?

That’s a big win that can be easily overlooked. But it depends what you’re optimising for…


I don't know many (any?) people who are greenfielding just-JavaScript, though. If you're using JavaScript in anger, you should probably be using TypeScript, and now you've got a build step regardless.

Which is not a bad thing. Incremental builds have gotten much better and much easier to deal with.


> greenfielding just-JavaScript, though

There are still some frameworks that let you write fancy front-ends without a build-step and associated tooling. And there's people like me who prefer those since they meet our needs.


You now know one person who is doing this.

:)


I use web components in a small project where I don't want a build step (it's plain HTML and I just use web components for re-usability instead of copy+pasting mark-up).


Lit framework provides a bunch of sugar that brings the dev experience closer to JSX

https://lit.dev/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: