Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions content/docs/faq-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,6 @@ class Searchbox extends React.Component {
}

handleChange(e) {
// React pools events, so we read the value before debounce.
// Alternately we could call `event.persist()` and pass the entire event.
// For more info see reactjs.org/docs/events.html#event-pooling
this.emitChangeDebounced(e.target.value);
}

Expand Down
37 changes: 37 additions & 0 deletions content/docs/legacy-event-pooling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
id: legacy-event-pooling
title: Event Pooling
permalink: docs/legacy-event-pooling.html
---

>Note
>
>This page is only relevant for React 16 and earlier, and for React Native.
>
>React 17 on the web **does not** use event pooling.
>
>[Read more](/blog/2020/08/10/react-v17-rc.html#no-event-pooling) about this change in React 17.

The [`SyntheticEvent`](/docs/events.html) objects are pooled. This means that the `SyntheticEvent` object will be reused and all properties will be nullified after the event event handler has been called. For example, this won't work:

```javascript
function handleChange(e) {
// This won't work because the event object gets reused.
setTimeout(() => {
console.log(e.target.value); // Too late!
}, 100);
}
```

If you need to access event object's properties after the event handler has run, you need to call `e.persist()`:

```javascript
function handleChange(e) {
// Prevents React from resetting its properties:
e.persist();

setTimeout(() => {
console.log(e.target.value); // Works
}, 100);
}
```
29 changes: 2 additions & 27 deletions content/docs/reference-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,36 +34,11 @@ string type

> Note:
>
> As of v0.14, returning `false` from an event handler will no longer stop event propagation. Instead, `e.stopPropagation()` or `e.preventDefault()` should be triggered manually, as appropriate.

### Event Pooling {#event-pooling}

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.

```javascript
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});
}
```
> As of v17, `e.persist()` doesn't do anything because the `SyntheticEvent` is no longer [pooled](/docs/legacy-event-pooling.html).

> Note:
>
> If you want to access the event properties in an asynchronous way, you should call `event.persist()` on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.
> As of v0.14, returning `false` from an event handler will no longer stop event propagation. Instead, `e.stopPropagation()` or `e.preventDefault()` should be triggered manually, as appropriate.

## Supported Events {#supported-events}

Expand Down
2 changes: 1 addition & 1 deletion static/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/link/dangerously-set-inner-html /docs/dom-elements.html#dangerouslysetinnerhtml
/link/derived-state /blog/2018/06/07/you-probably-dont-need-derived-state.html
/link/error-boundaries /docs/error-boundaries.html
/link/event-pooling /docs/events.html#event-pooling
/link/event-pooling /docs/legacy-event-pooling.html
/link/hooks-data-fetching /docs/hooks-faq.html#how-can-i-do-data-fetching-with-hooks
/link/invalid-aria-props /warnings/invalid-aria-prop.html
/link/invalid-hook-call /warnings/invalid-hook-call-warning.html
Expand Down
2 changes: 1 addition & 1 deletion vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{ "source": "/link/dangerously-set-inner-html", "destination": "/docs/dom-elements.html#dangerouslysetinnerhtml", "permanent": false },
{ "source": "/link/derived-state", "destination": "/blog/2018/06/07/you-probably-dont-need-derived-state.html", "permanent": false },
{ "source": "/link/error-boundaries", "destination": "/docs/error-boundaries.html", "permanent": false },
{ "source": "/link/event-pooling", "destination": "/docs/events.html#event-pooling", "permanent": false },
{ "source": "/link/event-pooling", "destination": "/docs/legacy-event-pooling.html", "permanent": false },
{ "source": "/link/hooks-data-fetching", "destination": "/docs/hooks-faq.html#how-can-i-do-data-fetching-with-hooks", "permanent": false },
{ "source": "/link/invalid-aria-props", "destination": "/warnings/invalid-aria-prop.html", "permanent": false },
{ "source": "/link/invalid-hook-call", "destination": "/warnings/invalid-hook-call-warning.html", "permanent": false },
Expand Down