Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在ReactJS中的父组件上设置事件侦听器?_Javascript_Reactjs_Event Handling_Addeventlistener - Fatal编程技术网

Javascript 如何在ReactJS中的父组件上设置事件侦听器?

Javascript 如何在ReactJS中的父组件上设置事件侦听器?,javascript,reactjs,event-handling,addeventlistener,Javascript,Reactjs,Event Handling,Addeventlistener,我正在尝试创建一个自定义上下文菜单,当用户右键单击我页面的某个部分时,该菜单将激活(我希望浏览器的默认上下文菜单位于页面的其余部分) 从父元素调用子元素: <ContextMenu clickDomain={this.parentRef}> (其中,openContextMenu设置状态可见:true以及x和y坐标。) 但是!!self.props.clickDomain.current为false(self.props.clickDomain.current为null),而dom

我正在尝试创建一个自定义上下文菜单,当用户右键单击我页面的某个部分时,该菜单将激活(我希望浏览器的默认上下文菜单位于页面的其余部分)

从父元素调用子元素:

<ContextMenu clickDomain={this.parentRef}>
(其中,
openContextMenu
设置状态
可见:true
以及x和y坐标。)

但是
!!self.props.clickDomain.current
为false(
self.props.clickDomain.current
为null),而
domain
document

那么,即使父引用不在DOM中,子组件也已经“挂载”了

如何将对父组件的实时引用传递给子组件,以便从子组件内部在父组件上设置事件侦听器?

可能是一个解决方案。设置ref后,您可以使用状态存储ref,并将
this.state.ref
传递给
组件

但我建议你试试这个:

class WithContextMenu extends React.Component {
    constructor(props) {
        super(props);
        this.state = {open: false};
    }

    openContextMenu(e) {
        e.preventDefault();
        this.setState({open: true});
    }

    render() {
        return (<React.Fragment>
            {React.cloneElement(
                React.Children.only(this.props.children),
                { onContextMenu: this.openContextMenu.bind(this) }
            )}
            { this.state.open && <div>context menu</div> }
        </React.Fragment>)
    }
}

// In any other component
const MyComponent = () => (
    <WithContextMenu>
      <div>
        <h1>Hello</h1>
        <p>Right-click to open context menu</p>
      </div>
    </WithContextMenu>
);
class with contextmenu扩展React.Component{
建造师(道具){
超级(道具);
this.state={open:false};
}
openContextMenu(e){
e、 预防默认值();
this.setState({open:true});
}
render(){
返回(
{React.cloneElement(
反应。儿童。仅限(此。道具。儿童),
{onContextMenu:this.openContextMenu.bind(this)}
)}
{this.state.open&&context menu}
)
}
}
//在任何其他组件中
常量MyComponent=()=>(
你好
右键单击打开关联菜单

);
然后可以使用上下文菜单装饰任何组件。以下是它的工作原理:

  • 使用上下文菜单将任何组件包装在
    组件中
  • onContextMenu
    事件处理程序附加到包装的组件
  • 触发事件处理程序时,上下文菜单本身将与包装的组件一起呈现

  • 嘿,如果你要投票否决我,请至少在评论中解释原因!您被绑定使用
    domain.addEventListener('contextmenu')
    有什么原因吗?看起来您可以简单地监视父组件上的
    onClick
    ,设置一个状态,比如说
    isContext
    状态为
    true
    ,然后将其传递给
    。在
    ContextMenu.render
    中,如果
    this.props.isOpen===true
    ,则您可以简单地
    呈现您的元素。@SungM.Kim,感谢您的投票和回复!您的建议当然更直截了当,但在我看来,组件的可见性是该组件状态的一部分,而不是真正的父级状态。我正在尝试使上下文菜单组件自包含,这样我就可以轻松地重用它,而无需对主机/父级进行大量更改。嗨,Pierre,非常感谢您的回复!我试图理解您建议的代码在做什么,以及它如何解决我的问题。看起来您是在
    ContextMenu
    的子菜单上设置事件处理程序,而不是在父菜单上设置(我想要的)?我误读了吗?不客气!我建议的是decorator模式的实现。我更新了示例代码,使其更加明确。
    class WithContextMenu extends React.Component {
        constructor(props) {
            super(props);
            this.state = {open: false};
        }
    
        openContextMenu(e) {
            e.preventDefault();
            this.setState({open: true});
        }
    
        render() {
            return (<React.Fragment>
                {React.cloneElement(
                    React.Children.only(this.props.children),
                    { onContextMenu: this.openContextMenu.bind(this) }
                )}
                { this.state.open && <div>context menu</div> }
            </React.Fragment>)
        }
    }
    
    // In any other component
    const MyComponent = () => (
        <WithContextMenu>
          <div>
            <h1>Hello</h1>
            <p>Right-click to open context menu</p>
          </div>
        </WithContextMenu>
    );