banner



How To Set Custom Html Inside Reactjs Component

Wrapping React Components Inside Custom Elements

This calendar week I had the pleasance of speaking in the ReactNext 2022 conference. My talk was chosen "I'm with Web Components and Web Components are with Me" and it was all about consuming Web Components in React apps and wrapping React components with custom elements. In this post I'll explicate the second function and why yous might want to do it.

React and Web Components

React Documentation mentions that React and Web Components are complementary to each other. React is the view engine that is responsible to keep the DOM in sync with the app'southward data, while Web Components provide a strong encapsulation for the cosmos of reusable HTML components. In real world, however, the two technologies are rarely combined together. For instance, I consult to several companies and none of them is using both React and Web Components. What could be the main reasons for that?

  • Developers are still suspicious about the Web Components API and prefer to use a proven framework/library instead.
  • Spider web Components API is nevertheless not implemented in some of the browsers, which means that in order to employ them nosotros need to load a polyfill code.
  • Every bit developers, we are used to frameworks/libraries goodies such as data binding, reactivity, lazy loading and more. In Web Components we need to craft everything and the boilerplate is sometimes cumbersome.

So why invest in Web Components at all? You tin find the reply in an article I posted back in 2022: "Why I'g Betting on Web Components (and You Should Think About Using Them As well)". To summarize what I wrote — Web Components can help you decouple the implementation of your component from the framework/library and assist you create a boundary between the components and their consuming app. They are also suitable for design system edifice which can exist consumed past any framework/library.

Wrapping React Component inside a Custom Chemical element

At present that we have a meliorate understanding why would we want to use Web Components, let's talk near how to take advantage of the Spider web Components API to wrap a React component.

We will start with a uncomplicated collapsible panel written in React:

The component includes a collapsible section and a header element that when clicked on toggles between collapsed and shown states. If we desire to wrap this component inside a custom HTML element we need to take care of a few things:

  • Pass the title and children props
  • Re-return when the title prop is irresolute

We will start by creating the custom element class and by defining it in the CustomElementRegistry:

                      export default class            CollapsiblePanel            extends              HTMLElement                          {          }                                    window            .customElements.ascertain('collapsible-panel', CollapsiblePanel);        

Our class volition include 2 members the title and mountain signal, which will be responsible to concur the mounting betoken in the DOM:

                      mountPoint: HTMLSpanElement;
title: string;

Now let'due south talk about the main implementation betoken — mounting the React component. We will apply the custom element'south connectedCallback life cycle event to do that:

          connectedCallback() {
this.mountPoint = document .createElement('span');
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(this.mountPoint);

const title = this.getAttribute('title');
ReactDOM.return(this.createCollapsed(title), this.mountPoint);
retargetEvents(shadowRoot);
}

In the connectedCallback, we will create a span which is going to exist our mounting point. Then, nosotros will use the attachShadow function to create a shadow root which volition exist our boundary between the app and the React component. Nosotros will suspend the mounting point to the shadow root. Afterward we set all the footing, we will employ ReactDOM to return the React component (using the createCollapsed function that you will come across in a minute). Last but non least, we will use a role called retargetEvents which is part of the react-shadow-dom-retarget-events module. We will get to why I'k using retargetEvents after in this post and then keep on reading :).

Permit's look at the createCollapsed function:

          createCollapsed(championship) {
render React.createElement(CollapsibleReact, { title }, React.createElement('slot'));
}

The role is getting the championship which will be used by the React component. Then, the function uses React's createElement function to create the CollapsibleReact component instance. The createElement likewise receives the props object every bit a second argument and the children prop equally third argument. In club to pass the children every bit expected I use the HTML slot element to make a bridge between the wrapping component children and the wrapped component children.

Now that we finished the mounting of the wrapper component, the next step is to re-render the component if the title changes. For that, we will use an observed aspect and the attributeChangedCallback custom chemical element life cycle event. Here is how they are used in the component:

                      static get                        observedAttributes() {
return ['title'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'title') {
ReactDOM.render(this.createCollapsed(newValue), this.mountPoint);
}
}

When the title changes we use ReactDOM return office once more. Since we saved the mounting indicate, ReactDOM will exercise all the re-rendering heavy lifting and will calculate the diffs for us.

The custom chemical element's entire implementation:

Re-targeting React Events

Why did I utilize the retargetEvents office? React event organisation is relying on synthetic events, which are wrappers on height of the browser native events. All the events in React are pooled and will exist registered on the document itself. That behavior can be very problematic when you utilise shadow DOM. In shadow DOM, the shadowed DOM fragment exists in its ain DOM fragment. That means that React events won't work inside the adumbral part. The retargetEvents function helps to register the events inside the shadow DOM and to brand them work as expected.

Testing The Wrapper

Now nosotros can exam the wrapper component. I used an Angular application to consume the component and this is the code I used in the awarding main HTML:

The outcome of running the app:

If you are interested in the full session from ReactNext 2022, yous can watch it here:

Summary

You accept but learned how to wrap a React Component as a Spider web Component, and saw how piece of cake information technology is to eat the issue from an Angular app. The approach I presented here is just one way to achieve this. Can you think of a different approach? How would you automate this procedure?
Please experience free to share your thoughts and comment!

Thanks to Adam Klein , Uri Shaked and Ran Wahle for reviewing the post before it was published!

How To Set Custom Html Inside Reactjs Component,

Source: https://gilfink.medium.com/wrapping-react-components-inside-custom-elements-97431d1155bd

Posted by: sellarsmoging.blogspot.com

0 Response to "How To Set Custom Html Inside Reactjs Component"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel