【发布时间】:2018-10-23 13:57:12
【问题描述】:
我在使用 preactjs 时遇到了一个奇怪的行为,这很奇怪,因为我从来没有在 react 中遇到过这种情况。看看这个小提琴:
这是一个超级简单的组件,带有一个用作切换器的按钮。 请打开浏览器控制台并查看控制台日志。
最初活动状态属性为假 -> 不活动。 当您第一次单击问号时,正如预期的那样,调用切换功能,目标是按钮(注意,在我的本地环境中,事件目标结果是“.help-overlay”元素(应该仅在状态更改后才呈现),有什么想法吗?)
然后将state 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);
【问题讨论】:
-
这与
<div class='help-overlay'>元素有关。如果您使用<div class='help-overlay'>包装这两个元素或将其完全删除,它将按预期工作。不知道为什么,可能是因为内部元素在 VDOM 中并没有真正改变,而是在 DOM 中重新注册? -
嗨@Sagivb.g,谢谢。我想你可以在这里找到重点。但我会说相反:一个真实的两个虚拟dom元素,因为否则我无法想象不同真实dom事件的两个处理程序如何触发两次。虽然绑定到同一个 dom 元素的两个虚拟 dom 元素可能会在这个 dom 元素被触发时做出反应(啊哈)。但无论如何,这对我来说听起来像是一个错误(react 的行为不是这样,证明了)。而且我不明白为什么 stopPropagation 调用会修复这些东西。再见!
-
不要忘记,这些是反应中的合成事件,而不是 preact 中的合成事件(据我所知)。如果您在此处发布问题并将其链接到此处会很好,以便我们跟进。
-
也许你可以添加你的例子in this issue
-
我会提出问题,谢谢
标签: javascript dom-events preact