Javascript ReactJS可以';t使用event.persist()从事件设置状态
我需要设置一个从事件中获取的状态字段,但当我将函数传递给它时,它不会被设置。组件和方法如下所示:Javascript ReactJS可以';t使用event.persist()从事件设置状态,javascript,reactjs,Javascript,Reactjs,我需要设置一个从事件中获取的状态字段,但当我将函数传递给它时,它不会被设置。组件和方法如下所示: constructor(props: SomeProps, context: any) { super(props, context); this.state = { isFiltering: props.isFiltering, anchor: "", }; } private toggleFilter = (event: any) => { event.p
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
}));
}
如果删除event.persist()
,则会出现以下错误:
出于性能原因,重用此合成事件。如果您看到了这一点,那么您正在访问一个已发布/无效的合成事件的方法currentTarget
。这是一个无操作功能。如果必须保留原始合成事件,请使用event.persist()。有关更多信息,请参阅
出于某种原因,以下代码起作用:
private toggleFilter = (event: any) => {
this.setState({anchor:event.currentTarget}) // works fine
this.setState(prevState => ({
isFiltering: !prevState.isFiltering,
}));
}
为什么上面的方法有效,但当我使用
this.setState(prevState=>…)
?加上@thirtydot的注释,我得到了一个有效的解决方案
我认为这是因为setState是“异步”的,所以当您传递给setState的函数被执行(并且事件被访问)时,事件就不再存在了。在第二个版本中,立即访问事件,并将其currentTarget传递给setState
因此,我将event.currentTarget
存储到一个变量中,并按照
看起来像这样,而且很有效
private toggleFilter = (event: any) => {
let target = event.currentTarget;
this.setState((prevState) => ({
isFiltering: !prevState.isFiltering,
anchor: target
}));
}
但是,这并不能解释为什么
event.persist()
不起作用。我会接受解释它的答案。这是预期的行为,因为event.persist()
并不意味着currentTarget
没有被取消,事实上它应该是-这符合浏览器的本机实现
这意味着,如果您想以异步方式访问currentTarget,您需要像在回答中那样将其缓存在变量中
举一个React核心开发者的例子- currentTarget会随着事件的冒泡而更改–如果您在接收事件的元素上有一个事件处理程序,而在其祖先上有其他事件处理程序,那么他们会看到currentTarget的不同值。IIRC将其置零与本机事件上发生的情况一致;如果没有,请告诉我,我们将重新考虑我们在这里的行为 查看官方React存储库中的讨论,以及下面由Sophie提供的片段,我稍微提到了一下
var savedEvent;
var储蓄目标;
divb.addEventListener('click',函数(e){
savedEvent=e;
savedTarget=e.currentTarget;
setTimeout(函数(){
log('b:currentTarget现在是'+e.currentTarget');
}, 0);
},假);
diva.addEventListener('click',函数(e){
log('same event object?'+(e==savedEvent));
log('same target?'+(savedTarget==e.currentTarget));
setTimeout(函数(){
log('a:currentTarget现在是'+e.currentTarget');
}, 0);
},假)代码>
div{
填充:50px;
背景:rgba(0,0,0,0.5);
颜色:白色;
}
JS-Bin
单击我并查看输出!
在动态填充组件时,我遇到了类似的警告消息,为了解决这个问题,我只需使用arrow函数包装函数
发件人:
{ text: "Delete item", onClick: deleteItem },
致:
要解决此问题-在调用表单的handleSubmit之前,请调用
然后在handleSubmit()定义中编写逻辑。例如
<form id="add_exp_form" onSubmit={(event) => {event.persist();this.handleSubmit(event)}}>
handleSubmit(event){
// use event.currentTarget - It will be visible here
}
{event.persist();this.handleSubmit(event)}>
handleSubmit(事件){
//使用event.currentTarget-它将在此处可见
}
关于这个问题有一个很好的描述和两种不同的解决方案,你可以用这个来检查你可以使用像这样的curry函数来处理它
const persistEvent = (fun: any) => (e: any) => {
e.persist();
fun(e);
};
现在您可以像这样编写函数了
persistEvent(toggleFilter);
它将是这样的:
const persistEvent = (fun: any) => (e: any) => {
e.persist();
fun(e);
};
const delayedFunctionality = (e) => {
setTimeout(()=> {
console.log(e.target.value)
},500
}
<input onChange={persistEvent(delayedFunctionality)} />
constpersistEvent=(乐趣:任何)=>(e:any)=>{
e、 坚持();
乐趣(e);
};
const delayedFunctionality=(e)=>{
设置超时(()=>{
console.log(例如target.value)
},500
}
在函数中,应该使用constevent.preventDefault()
或event.prevent()
例如:
updateSpecs1 = (event) => {
event.preventDefault()
我认为这是因为setState
是“异步”的,所以当传递给setState
的函数被执行时(并且事件被访问),事件不再存在。在第二个版本中,事件立即被访问,其currentTarget
被传递到setState
@thirtydot,这很有意义,但是它似乎是event.persist()
是解决这一问题的合适方案,但它对我来说有点不起作用..是的。我不知道为什么它不起作用(我自己没有测试),所以我没有写答案。应该没问题。有什么特别的原因你不想使用它吗?private-toggleFilter=(event:any)=>{this.setState({isFiltering:!this.state.isFiltering,anchor:event.currentTarget};}
。可能更容易理解。感谢您指出此链接。我选择了在设置状态之前“缓存值”的解决方案,而不是event.persist():只需执行const value=event.target.value;setState(value)
。
updateSpecs1 = (event) => {
event.preventDefault()