'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 |
