反应综合事件在Web组件中不起作用

时间:2019-05-13 09:09:13

标签: javascript reactjs web-component react-dom

我遵循了React的文档,了解如何在Web组件(https://reactjs.org/docs/web-components.html)中使用React,但是发现综合事件系统不适用于该React组件内部的React树。

Here is a JS Fiddle,您可以在其中尝试:

  • 无需Web组件自然嵌入的React组件
  • 嵌入在Web组件内部的相同React组件(事件不会触发)
  • 另一个React组件,它在Web组件内部手动附加事件侦听器
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>

使用手动侦听器绑定的方法行得通,但是我想避免重写将要集成的每个单独的React组件。

有人知道我可以做的快速修复,以便将事件传播到组件吗? (使小提琴的第二种情况起作用)

我听说过Polymer-react,但还没有尝试过。而且,我尽可能不引入其他层。

2 个答案:

答案 0 :(得分:1)

根据React文档。

  

Web组件发出的事件可能无法通过React渲染树正确传播。您将需要手动附加事件处理程序以在React组件中处理这些事件。

所以答案是,您只能自己附加事件监听器。

答案 1 :(得分:0)

我花了一些时间尝试查找修复程序或解决方法,结果如下:

最后,作为结论,我们决定使用不带Shadow-DOM功能的Web组件。