'react-select in web-component | onChange Event

I need to use react-select in a shadow-root web-component like in this example.

How can I pass the onChange event from the <Select>component in my react environment to use it in the state:

web component:

import * as React from "react";

import ReactDOM from "react-dom";
// import { useState } from "react";
import Select from "react-select";
import retargetEvents from "react-shadow-dom-retarget-events";
import { CacheProvider } from "@emotion/react";
import createCache from "@emotion/cache";


export class ReactSelect extends HTMLElement {
  createMountPoint() {
    this.mountPoint = document.createElement("div");
    this.attachShadow({ mode: "open" });

    this.shadowRoot.appendChild(this.mountPoint);
  }

  createCache() {
    return createCache({
      container: this.shadowRoot,
      key: "test",
      prepend: false,
    });
  }

  connectedCallback() {
    // Step 1: Create Shadow and Mountpoint
    this.createMountPoint();

    // Step 2: Create emotion Cache
    const cache = this.createCache();

    // Step 3: Render component with `CacheProvider`
    setTimeout(() => {
      ReactDOM.render(
        <CacheProvider value={cache}>
          <Select
            isMulti
            name="time"
            options={timeOptions}
            className="basic-multi-select"
            classNamePrefix="select"
            placeholder={<div>Time</div>}
            onChange={(e) => console.log("select:", e)}
          />
        </CacheProvider>,
        this.mountPoint
      );

      retargetEvents(this.shadowRoot);
    }, 1);

    this.shadowRoot.addEventListener("click", function (e) {
      console.log(this);
    });
  }
}

customElements.get("react-select") ||
  customElements.define("react-select", ReactSelect);

react:

import { Styled } from "direflow-component";
import PropTypes from "prop-types";
import React, { useEffect, useState } from "react";
import Select from "react-select";
import styles from "./App.css";
import "./ReactSelectElement";

function App(props) {


  return (
    <Styled styles={styles}>
       <react-select onClick={(e) => console.log(e.target)}></react-select>
    </Styled>


Solution 1:[1]

You can't add a custom event on the same way you add properties or natives event on elements, but you can add custom events, and listen for them:

Lets see an example with onChange:

web-component.js

/* dispatch a custom event called onChange*/
dispatchCustomEvent(evenName) {
  const event = function (arg) {
      this.mountPoint.dispatchEvent(
        new CustomEvent(evenName, {
          bubbles: true,
          composed: true,
          detail: arg,
        })
      );
    };
  return event.bind(this);
}

then pass that event:

ReactDOM.render(
  <CacheProvider value={cache}>
    <Select
      isMulti
      name="time"
      options={timeOptions}
      className="basic-multi-select"
      classNamePrefix="select"
      placeholder={<div>Time</div>}
      onChange={dispatchCustomEvent("onChange")}
    />
  </CacheProvider>,
  this.mountPoint
);     

Listen for that event on your react app:

app.js

function App(props) {
  const ref = useRef();

  useEffect(() => {
    ref.current.addEventListener("onChange", (e) => {
      console.log(e.target);
    });
  });

  return (
    <Styled styles={styles}>
      <react-select ref={ref}></react-select>
    </Styled>
  );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1