Я следовал документации React о том, как использовать React внутри веб-компонента (https://reactjs.org/docs/web-components.html)), но обнаружил, что синтетическая система событий просто не работает для дерева React внутри этого компонента React.
Вот JS Fiddle , где вы можете попробовать:
- Компонент React, встроенный естественным образом без веб-компонентов
- Тот же компонент React, встроенный в веб-компонент (события не срабатывают)
- Другой компонент React, который подключает прослушиватели событий вручную, внутри веб-компонента
class CounterWithSyntheticEvents extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
};
}
handleClick() {
this.setState(prevState => ({ counter: prevState.counter + 1 }));
}
render() {
return (
<div>
Count {this.state.counter} <button onClick={this.handleClick.bind(this)}>+</button>
</div>
);
}
}
class CounterWithDOMEvents extends React.Component {
constructor(props) {
super(props);
this.buttonRef = React.createRef();
this.state = {
counter: 0,
};
}
componentDidMount() {
const listenerFn = this.handleClick.bind(this);
this.buttonRef.current.addEventListener("click", listenerFn);
this.removeListener = () => this.buttonRef.current.removeEventListener('click', listenerFn);
}
componentWillUnmount() {
this.removeListener();
}
handleClick() {
this.setState(prevState => ({ counter: prevState.counter + 1 }));
}
render() {
return (
<div>
Count {this.state.counter} <button ref={this.buttonRef}>+</button>
</div>
);
}
}
ReactDOM.render(<CounterWithSyntheticEvents />, document.getElementById("container"));
class ReactSyntheticEvents extends HTMLElement {
connectedCallback() {
const mountPoint = document.createElement("div");
const shadow = this.attachShadow({ mode: "open" });
shadow.appendChild(mountPoint);
ReactDOM.render(<CounterWithSyntheticEvents />, mountPoint);
}
}
customElements.define("react-synthetic-events", ReactSyntheticEvents);
class ReactDOMEvents extends HTMLElement {
connectedCallback() {
const mountPoint = document.createElement("div");
const shadow = this.attachShadow({ mode: "open" });
shadow.appendChild(mountPoint);
ReactDOM.render(<CounterWithDOMEvents />, mountPoint);
}
}
customElements.define("react-dom-events", ReactDOMEvents);
<div id="container"></div>
<react-synthetic-events ></react-synthetic-events>
<react-dom-events ></react-dom-events>
Подход с ручной привязкой слушателей работает, но я хочу избежать переписывания каждого компонента реакции, который должен быть интегрирован.
Кто-нибудь знает о быстром исправлении, которое я мог бы сделать, чтобы события распространялись на компоненты? (чтобы 2-й корпус скрипки работал)
Я слышал о Реакция полимера , но еще не попробовал. И я хотел бы не вводить другой слой, если это возможно.