Mur*_*göz 31 javascript reactjs
我需要设置一个从事件中获取的状态字段,但是当我将函数传递给它时它不会被设置.组件和方法如下所示:
constructor(props: SomeProps, context: any) {
super(props, context);
this.state = {
isFiltering: props.isFiltering,
anchor: "",
};
}
private toggleFilter = (event: any) => {
event.persist()
this.setState(prevState => ({
isFiltering: !prevState.isFiltering,
anchor: event.currentTarget // does not work, it's null
}));
}
Run Code Online (Sandbox Code Playgroud)
如果我删除event.persist()然后我收到以下错误:
出于性能原因,此合成事件将重复使用.如果您看到这个,那么您将
currentTarget在已发布/无效的合成事件上访问该方法.这是一个无操作功能.如果必须保留原始合成事件,请使用event.persist().有关更多信息,请参阅https://facebook.github.io/react/docs/events.html#event-pooling.
由于某种原因,以下代码有效:
private toggleFilter = (event: any) => {
this.setState({anchor:event.currentTarget}) // works fine
this.setState(prevState => ({
isFiltering: !prevState.isFiltering,
}));
}
Run Code Online (Sandbox Code Playgroud)
为什么以上工作但不是我使用时this.setState(prevState=> ...)?
Lyu*_*mir 28
这是预期的行为,因为event.persist()并不意味着currentTarget没有被取消,事实上应该是 - 这符合浏览器的本机实现.
这意味着如果要以异步方式访问currentTarget,则需要像在答案中一样将其缓存在变量中.
引用其中一位React核心开发人员--Sophie Alpert.
当事件冒泡时,currentTarget会发生变化 - 如果你在接收事件的元素上有一个事件处理程序,而在其祖先上有其他事件,他们会看到currentTarget的不同值.IIRC将其归零与本机事件发生的情况一致; 如果没有,请告诉我,我们会在这里重新考虑我们的行为.
查看官方React存储库中的讨论来源以及Sophie提供的以下代码片段,我已经触及了一下.
var savedEvent;
var savedTarget;
divb.addEventListener('click', function(e) {
savedEvent = e;
savedTarget = e.currentTarget;
setTimeout(function() {
console.log('b: currentTarget is now ' + e.currentTarget);
}, 0);
}, false);
diva.addEventListener('click', function(e) {
console.log('same event object? ' + (e === savedEvent));
console.log('same target? ' + (savedTarget === e.currentTarget));
setTimeout(function() {
console.log('a: currentTarget is now ' + e.currentTarget);
}, 0);
}, false);Run Code Online (Sandbox Code Playgroud)
div {
padding: 50px;
background: rgba(0,0,0,0.5);
color: white;
}Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="diva"><div id="divb"> Click me and see output! </div></div>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
Mur*_*göz 13
随着@thirtydot的评论我得到了一个有效的解决方案.
我认为这是因为setState是"异步"的,所以当你传递给setState的函数被执行(并且访问事件)时,事件就不再存在了.在第二个版本中,立即访问事件并将其currentTarget传递给setState
所以我将其存储event.currentTarget到一个变量并使用它,就像它在ReactJs事件池中所解释的那样
看起来像这样,它的工作原理
private toggleFilter = (event: any) => {
let target = event.currentTarget;
this.setState((prevState) => ({
isFiltering: !prevState.isFiltering,
anchor: target
}));
}
Run Code Online (Sandbox Code Playgroud)
然而,这并不能解释为什么event.persist()不起作用.我会接受解释它的答案.
小智 9
要解决此问题 - 在调用表单的 handleSubmit 之前,调用 event.persist() 然后在 handleSubmit() 定义中 - 编写您的逻辑。例如
<form id="add_exp_form" onSubmit={(event) => {event.persist();this.handleSubmit(event)}}>
handleSubmit(event){
// use event.currentTarget - It will be visible here
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31606 次 |
| 最近记录: |