My react app needs to load dynamic html at runtime. Inside of this html, I need to display small custom components.
At first I tried to render a separate react virtual dom for each of these custom components. But I think it might be cleaner to do this with web components. The components don’t need to react to the app state, I can just add
<my-component> tags to the dynamic html.
While the components don’t react to app state, they do need to communicate “user has interacted with me” to the rest of the app. It’s a one-way information flow, out of the dynamic html.
It seems like there are two ways to implement this:
- use querySelectors to find all the web components and give them a callback as a prop.
- dispatch a custom “user interaction” event
For now, I’m trying to make this second option, with custom events, work. And this is where I run into problems.
It’s not clear to me how to listen to custom events from components inside of the react dom. The react docs do say:
Events emitted by a Web Component may not properly propagate through a React render tree. You will need to manually attach event handlers to handle these events within your React components.
But even when I manually attach event handlers, they don’t react to custom events.
To reproduce the problem, I’ve set up a minimal example. There are two divs in the dom, the outer one listens to custom events, the inner one hosts the react virtual dom. Inside of the virtual dom there are two components. The outer one is also a listener, the inner one dispatches the custom event.
The problem is: Only the outer div catches the event, react components can’t listen to it.
You can see the example here: https://codesandbox.io/s/quirky-cannon-in5u0
Or you can clone and edit a typescript version:
git clone https://github.com/lhk/react_custom_events cd react_custom_events npm i npm run start # browser opens, look at the console output