Hacker News new | ask | show | jobs
by jpangs88 1872 days ago
At my work web components were purposed recently for creating a ui component library of which I was skeptical. On the whole I was skeptical of web components viability and future but this post relieves some of that tension.

The other thing I was worried about was that it was planned to after writing this web component lib, to wrap these components in React. Does anyone have any experience or insights into a React wrapped web component lib?

5 comments

The Lit team has a labs project called @lit-labs/react that will automatically create a react wrapper:

https://www.npmjs.com/package/@lit-labs/react

It works alright with React if you treat it like regular DOM elements, but there's rough edges like SSR event handlers not working: https://github.com/facebook/react/issues/18390

Unfortunately it seems facebook isn't prioritizing fixing issues like this.

I'd suggest using preact if you want a framework that's more compatible with web components but gives you the React experience.

Super easy to incorporate with React. Just use react to pass attributes, like so:

    class App extends React.Component {
      render() {
        return (
          <my-component custom-attribute={value}></my-component>
        )
      }
    }
In your webcomponent just make sure you listen to changes to that attribute like so:

    static get observedAttributes() {
      return ['custom-attribute']
    }
Then you can decide how the component changes whenever that attribute is updated by using the `attributeChangedCallback` function. Alternatively, use a base element that incorporates a render() function which will automatically update everything in the shadowdom.

Main difference is it becomes much harder to pass complex data structures. Passing strings is easy, but passing an array of data isn't feasible with this model.

Issues arise when trying to pass objects or add event listeners for custom events due to how React specifically handles this stuff. You often have to use refs
And even refs aren't enough if the custom element does its initial render asynchronously. I had to add mutation observers to some wrappers to avoid polling the ref.current.
Wrapping React components in Web Components has limits you'll quickly hit. Suppose you have two components (in a parent/child relationship) that share context (e.g., you're wrapping react-beautiful-dnd in Web Components-- <Draggable /> and <Droppable />). Each component has it's own ReactDOM.render call, and therefore is its own React VDOM tree with no shared context.

So you can't take existing React libraries and 1:1 map them to web components. That approach only works for 'leaf' components that accept no children.

In a closed source project I worked for, we used wrapped web components as React components for a UI library. I cannot show something here, only the approach we have used for it: https://www.robinwieruch.de/react-web-components