justjavac / justjavac/react-pits

SyntheticEvent objects are pooled

Open
#2 0 comments 13 reactions 0 assignees View on GitHub
blog React
Dominant language
HTML
Stars
29
Forks
4
PR merge metrics
No merged PRs in 30d

Description

## 0x00

> The `SyntheticEvent `is pooled. This means that the `SyntheticEvent `object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, **you cannot access the event in an asynchronous way**.

在 React 事件处理中,事件对象被包装在一个 `SyntheticEvent`(合成事件)对象中。这些对象是被池化的(pooled),这意味着在事件处理程序会把这些对象重用于其他事件以提高性能。随之而来的问题就是,异步访问事件对象的属性是不可能的,因为事件的属性由于重用而被重置(nullified)。

## 0x01

下面代码存在问题:

```
function handleClick(event) {
setTimeout(function () {
console.log(event.target.name);
}, 1000);
}
```

控制台会输出 `null`,因为每次事件回调完成后,`SyntheticEvent` 会被重置。

解决方式是把 `event` 赋值到一个内部变量上。

```
function handleClick(event) {
let name = event.target.name; // 内部变量保存 event.target.name 的值
setTimeout(function () {
console.log(name);
}, 1000);
}
```

## 0x02

facebook 官方的实例:

```
function onClick(event) {
console.log(event); // => nullified object.
console.log(event.type); // => "click"
const eventType = event.type; // => "click"

setTimeout(function() {
console.log(event.type); // => null
console.log(eventType); // => "click"
}, 0);

// Won't work. this.state.clickEvent will only contain null values.
this.setState({clickEvent: event});

// You can still export event properties.
this.setState({eventType: event.type});
}
```

如果想异步访问事件属性,可以在事件上调用 `event.persist()`,这会从池中移除合成事件并允许对事件的引用被保留。

## 参考资料

- [SyntheticEvent - React](https://facebook.github.io/react/docs/events.html)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.