React组件onClick处理程序无法正常工作

时间:2015-02-11 07:20:30

标签: javascript event-handling reactjs

单击按钮时会出现一个基本弹出窗口(图像)。当您单击该弹出窗口外部时,它应该关闭,但是当您单击它内部时,它应该保持打开状态并调用测试功能。其初始状态isPopupVisible设置为false。当您单击按钮时,我将状态设置为true,从而呈现弹出窗口。

问题是单击图像时不会调用测试功能。我认为这是因为状态被设置为false并且具有onClick函数的图像元素最初没有被渲染。有谁知道如何解决这个问题?

(写在ecmascript 6中)

getInitialState () {
  return {isPopupVisible: false}
},
onClick () {
  if(!this.state.isPopupVisible){
    this.setState({isPopupVisible: true});
    document.body.addEventListener('click', this.onClickBody)
  }
},
onClickBody () {
  this.setState({isPopupVisible: false});
  document.body.removeEventListener('click', this.onClickBody)
},
test () {
  console.log('the onClick from the image works!');
},
showPopup () {
  if(this.state.isPopupVisible){
    return <div>
      <img src='img.png' onClick={this.test} />
    </div>
  }else{
    return null;
  }
},
render () {
  return (
    <span>
      <button onClick={this.onClick}>
        See Popup
      </button>
      {this.showPopup()}
    </span>
  );
}

4 个答案:

答案 0 :(得分:0)

这有点像黑客,但是......

onClickBody () {
  setTimeout(function(){
    if (!this.clickedInBounds && this.isMounted()) {
      this.setState({isPopupVisible: false});
      document.body.removeEventListener('click', this.onClickBody)
    }
    this.clickedInBounds = false;    
  }.bind(this), 0);
},
test () {
  console.log('the onClick from the image works!');
  this.clickedInBounds = true;
},

setTimeout只是让它在test有机会运行后运行该代码。 isMounted只是因为在主体点击和setTimeout到来之间卸载组件的可能性很小。

jsbin

答案 1 :(得分:0)

在调用onClickBody之前调用test处理程序,更改状态并在合成事件触发之前从虚拟DOM中删除图像。

可能有一种优雅的方式,但是因为你混合使用本机和React事件API,我猜你必须更改onClickBody的签名才能将事件作为第一个参数,然后将方法的主体包装为if (e.target.nodeName !== "IMG") {}

JSFiddle在此处显示了这一点:http://jsfiddle.net/reactjs/69z2wepo/

答案 2 :(得分:0)

不是在click上添加body侦听器,而是可以在呈现弹出窗口之前添加底层透明div,以便在单击时关闭弹出窗口。

例如,这是react-bootstrap模态组件中实现的方式:https://github.com/react-bootstrap/react-bootstrap/blob/master/src/Modal.jsx#L73

您可以在此处查看演示:http://react-bootstrap.github.io/components.html#modals

答案 3 :(得分:0)

我知道这篇文章已经过了一年,但我知道正确答案。

你有很多参考危险。

onClick () {
  var self = this;
  if(!this.state.isPopupVisible){
    self .setState({isPopupVisible: true});
    document.body.addEventListener('click', self .onClickBody)
  }
},
onClickBody () {
  var self = this;
  this.setState({isPopupVisible: false});
  document.body.removeEventListener('click', self .onClickBody)
},
test () {
  console.log('the onClick from the image works!');
},
showPopup () {
  var self = this;
  if(this.state.isPopupVisible){
    return <div>
      <img src='img.png' onClick={self.test} />
    </div>
  }else{
    return null;
  }
},

这应该可以解决你的问题