Issue with UI event when rendering component inside a web component shadow DOM
Asked Answered
H

1

6

I'm facing some issues when rendering a React component into the shadow DOM of a webcomponent. I wrote a small piece of code to turn a React component into a webcomponent, but I want to render the React component inside the shadow DOM of the webcomponent. But in that case, it seems that React is not able to catch UI events (click, keyPress, etc ...) anymore.

Let's take an example, let say that I have a first webcomponent <awesome-timer /> that render the React component inside the webcomponent node, and another webcomponent <less-awesome-timer /> that render the React component inside the shadow DOM of the webcomponent. Both webcomponents use the same React component. However the one rendered inside the shadow DOM does not work, because click events on the button of the timer component does not trigger the bound function.

I guess React is not designed to handle such case, but I'd love to get more details about it.

The code of the example is available here : https://gist.github.com/mathieuancelin/cca14d31184bf4468bc1

Does anyone have an idea about it ?

Haematozoon answered 24/11, 2014 at 9:6 Comment(7)
Found that a related PR, but not sure how it behaves : github.com/facebook/react/pull/1877/filesHaematozoon
Events that happen inside the shadow DOM do not bubble outside the shadow root unless the custom element explicitly makes that happen. The click event on your React element inside the shadow DOM is not bubbling outside the container. The pull request you found tries to fix the issue by firing React's synthetic events on the shadow root rather than on the actual DOM element so the events can bubble to the normal DOM.Sensor
I misunderstood originally: this is not because the click event is prevented from bubbling, this doesn't work because shadow DOM events that bubble are retargeted to the shadow root. This seems impossible to workaround because the root React event listener receives a click event from a non-React element.Sensor
Thanks. And I guess it's not possible to listen to events on the shadow root and bridge it to the React DOMElement.Haematozoon
Actually, the following patch : github.com/facebook/react/pull/1877/… makes everything works if the React component is rendered in the first child level of the shadow DOM. I hope the PR will be merged at some point ...Haematozoon
Yeah, there's no workaround that I can see working without modifying React core.Sensor
I just want to say, it is possible to listen to event on the shadow DOm, you can also listen to your own custom events. Try using Document.querySelectopr("web-comonent") Then add an event listener there and as long as your shadowDom events BUbble you will be able to listen for the eventMantinea
M
0

I know this is kinda late but, I believe your issue when you pass any attributes to a web component they instantly become strings Because that's all you can pass to a web component. Now of course you can convert or cast them back to there original data type, except functions because once stringified they loose there scoping, lexical and all.

Now to your main question, you are were trying to pass you child element through the Main web components slot. Now you have to remember that once you pass anything to a web component you now have to use the webs components methods and return types to manage whatever you pass. So yes passing react into a web component will not work they you expect.

You will need to go back to whatever tool you use to build your web component and deal with the slot logic there. Since this is a very old post as are web components. You might not have had access to the modern web component build tool's we have today. I found Stenicl allows you to build and manage your web components in Typescript.

A good option is to change your pattern a little bit and just return web components from your react app.

Or you can use another really cool to call Lit-HTML or Lit-element. I believe they may have combined there core libraries. Anyway these tool will allow you to combine Reactjs and web components where lit-html gives you access to methods simial to Reactjs's life cycle methods. Anyway some good stuff to check out if your stuck at this point.

Mantinea answered 31/5, 2022 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.