简体   繁体   English

ReactJS - 从外部为多个实例调用组件 function

[英]ReactJS - Call a component function from outside for multiple instances

I want to call a method exposed by a React component from the outside of React for multiple instances.我想从 React 外部为多个实例调用由 React 组件公开的方法。 In bellow exmaple, I wanted to fire the respective toggleOverlay method when the user clicks on anywhere of article DIV.在下面的示例中,我想在用户单击文章DIV 的任何位置时触发相应的toggleOverlay方法。 The main DIV is not rendered through React, it was rendered from server-side (AEM) and I can add vanilla javascript into article div to attached the click event.主 DIV 不是通过 React 呈现的,它是从服务器端 (AEM) 呈现的,我可以将 vanilla javascript 添加到文章div 中以附加点击事件。

The configData for each component is different which comes thourgh AEM (server sides).每个组件的 configData 都不同,这来自 AEM(服务器端)。

Example:例子:

<div class="main">
    <div class="article">
        <h3>Lorem Ipsum</h3>
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
        <articleOverlay configData="" /> 
    </div>
    <div class="article">
        <h3>Lorem Ipsum</h3>
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
        <articleOverlay configData="" />
    </div>
    <div class="article">
        <h3>Lorem Ipsum</h3>
        <p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
        <articleOverlay configData="" />
    </div>
</div>


// articleOverlay component
class articleOverlay extends React.Component {
    constructor(props) {
        super(props);
    
        this.state = {
            showOverlay: false
        };

        window.articleOverlay = this;

       toggleOverlay = (e) => {
           if (this.state.showFlyout) {
               this.setState({ showOverlay: true }
           }else{
               this.setState({ showOverlay: false }
           }
       }

    }

    render() {
        const { configData } = this.props;
        return (
            <div className="article-overlay">
                <button className="article-overlay__button" onClick={this.toggleOverlay}>View flows</button>
                {
                    this.state.showOverlay && 
                    <div className="article-overlay__body">
                        <div className="article-overlay__item">
                            {configData.name}
                        </div>
                    </div>
                }
            </div>
        );
    }

}

I had tried to expose the method on window object using - window.articleOverlay = this;我曾尝试使用 - window.articleOverlay = this; and

Calling using -调用使用 -

document.querySelector('.article').addEventListener('click', function(){
  window.articleOverlay.toggleOverlay();
});

But suspecting it should not work for multiple instances, answer from here https://stackoverflow.com/a/50466217/2479903但怀疑它不应该适用于多个实例,从这里回答https://stackoverflow.com/a/50466217/2479903

Is there a way to achieve this?有没有办法做到这一点?

There's no need to make the function global, just add the event listener to the element in a componentDidMount , and there won't be any issues with multiple listeners that way either.无需将 function 设为全局,只需将事件侦听器添加到componentDidMount中的元素,这样多个侦听器也不会有任何问题。

And since you have multiple articles, don't use querySelector .而且由于您有多篇文章,请不要使用querySelector If the .article isn't part of React, but a parent of the root node, it looks like the best thing to do is attach a ref to a rendered element, then use .closest on it to find the article.如果.article不是 React 的一部分,而是根节点的父节点,看起来最好的做法是将 ref 附加到渲染的元素,然后在其上使用.closest来查找文章。

Change改变

<div className="article-overlay">

to

<div className="article-overlay" ref={div => this.article = div.closest('.article') }>

and use并使用

componentDidMount() {
  this.article.addEventListener('click', this.articleOverlay);
}
// cleanup too...
componentWillUnmount() {
  this.article.removeEventListener('click', this.articleOverlay);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM