Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ReactJS可以';t使用event.persist()从事件设置状态_Javascript_Reactjs - Fatal编程技术网

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
}

在函数中,应该使用const
event.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()