我需要设置一个从事件中获取的状态字段,但当我向其传递函数时,它不会被设置.组件和方法如下所示:

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.这是一个无操作功能.如果必须保留原始合成事件,请使用事件.坚持().更多信息请参见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,
  }));
}

为什么当我使用this.setState(prevState=> ...)时,上面的方法不起作用?

推荐答案

That's the expected behaviour,因为event.persist()并不意味着currentTarget没有被取消,事实上它应该被取消——这符合浏览器的本机实现.

这意味着,如果您想以异步方式访问currentTarget,您需要像在回答中那样将其缓存在变量中.


举一个React核心开发者的例子——Sophie Alpert.

currentTarget会随着事件的冒泡而变化——如果您在接收事件的元素上有一个事件处理程序,而在其祖先上有其他事件处理程序,那么他们会看到currentTarget的不同值.IIRC将其置零与本机事件上发生的情况一致;如果没有,请告诉我,我们会重新考虑我们在这里的行为.

查看官方React存储库中的the source篇讨论,以及下面由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);
div {
  padding: 50px;
  background: rgba(0,0,0,0.5);
  color: white;
}
<!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>

Reactjs相关问答推荐

如何在useEffect中使用useParams()

迁移到React Router Dom v6后,我是否错误地使用了Link组件?

ReferenceError:未在Redux组件中定义窗口

滚动事件监听器在Next.js客户端组件中不触发

根据另一个Select中的选定值更改Select中的值

利用OVERPASS API端点计算某建筑的表面积

在每页上应用字体-NextJS

在迭代状态时无法读取未定义的属性(读取 map )

React 错误无法读取未定义的属性(读取id)#react

从ReactDataGridtry 将数据传递给父组件

在添加了useplacesautocomplete后,在构建React/Next.js项目时,NPM抛出类型期望的错误

无法在react 中向表中添加行

React + Redux:数据未正确传递给具有动态路由的组件

需要先填写依赖输入字段,以便其他人工作

@react-three/postprocessing 没有匹配的从 three.module.js 导出以导入WebGLMultisampleRenderTarget

为什么我在此代码段中看不到 useEffect for count = 1?

Storybook - 无法解析generated-stories-entry.cjs/字段browser不包含有效的别名配置

使用 yarn 编译 protobuf js 时出现错误pbjs: command not found

react-query、react-hook-form 和表单验证

如果两个组件在 React 中导入相同的 CSS 文件会发生什么?