preactjs,onclick切换器触发两次

时间:2018-10-23 13:57:13

标签: javascript-events preact

我在preactjs中遇到了一个奇怪的行为,这很奇怪,因为它从来没有发生过带有react的事情。看这个小提琴:

http://jsfiddle.net/8s4vhknt/

这是一个非常简单的组件,带有一个按钮,可充当切换按钮。 请打开浏览器控制台并查看控制台日志。

最初,活动状态prop为false-> INACTIVE。 当您第一次按预期方式单击问号时,将调用切换功能,目标是按钮(在我的本地环境中为 NB,事件目标原来是'.help-overlay'元素(应仅在状态更改后才能呈现),任何想法?

然后将状态active prop设置为true,再次渲染该组件->在控制台中显示ACTIVE,并且按钮会更改。

现在单击按钮将触发两次onclick事件,并且显然没有任何变化。

我知道,这些东西在某种程度上与事件传播有关,实际上,在切换功能的开头添加e.stopPropagation()可以完成工作

但是我不明白的是为什么!我的意思是,该事件应通过dom向上传播,为什么在相同元素上再次触发相同的onclick处理程序呢?

这就是为什么我不要求解决方案,而是要求解释我无法掌握的情况。

非常感谢您。

我将在小提琴中发布组件广告的代码。

const { h, render, Component } = preact;    // normally this would be an import statement.

class Help extends Component {
  constructor () {
    super()
    this.state = {active: false}
    this.toggle = this.toggle.bind(this)
  }

  toggle (e) {
    console.log('ONCLICK', new Date().getTime(), e.target)
    this.setState(state => ({active: !state.active}))
  }

  render () {
    if (!this.state.active) {
      console.log('NOT ACTIVE')
      return (
        <div class='help-btn' onClick={this.toggle}>?</div>
      )
    } else {
      console.log('ACTIVE')
      return (
        <div class='help-overlay'>
          <div class='help-btn' onClick={this.toggle}>✕</div>
        </div>
      )
    }
  }
}

// render an instance of Clock into <body>:
render(<Help />, document.body);

1 个答案:

答案 0 :(得分:0)

在一个dom中具有重叠类的

div在另一个dom中不具有重叠类,将创建一个vdom diff,该diff将启动重新渲染的触发器。 我已经将两个div和父div都包含了条件叠加层,并且按预期工作了。

.help-btn {
  background: #000;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
}

.help-overlay {
  background: rgba(0, 0, 0, .7);
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
  z-index: 9;
}

/** @jsx h */
const { h, render, Component } = preact;    // normally this would be an import statement.

class Help extends Component {
  constructor () {
    super()
    this.state = {active: false};
  }

  toggle (e,isActive) {
    console.log('ONCLICK', new Date().getTime(), e.target)
    this.setState({active:!isActive});
  }

  render (props,{active}) {
        return (
        <div class={active ? "help-overlay" : "" }>
        {!active && <div class='help-btn' onClick={e => this.toggle(e,false)}>?</div>}
        {active && <div class='help-btn' onClick={e => this.toggle(e,true)}>✕</div>}
        </div>
      )
  }
}

// render an instance of Clock into <body>:
render(<Help />, document.body);

jsfiddle-http://jsfiddle.net/nhkz4feq/