From 64d067f2c0366f1c9ffa16cdf6f1fc162a313ea4 Mon Sep 17 00:00:00 2001 From: Toru Kobayashi Date: Sat, 24 Oct 2020 05:14:24 +0900 Subject: [PATCH] Remove event pooling and SyntheticEvent#persist from documents (#3207) * remove event pooling and SyntheticEvent#persist from documents Syntheticevent#event exists in v17, but it does nothing at the version * add a page for legacy event pooling for _redirects * add a warning e.persist() is no longer pooled * Update legacy-event-pooling.md * docs: update a redirect link for event pooling * Update legacy-event-pooling.md * Update legacy-event-pooling.md * Update reference-events.md Co-authored-by: Dan Abramov --- content/docs/faq-functions.md | 3 --- content/docs/legacy-event-pooling.md | 37 ++++++++++++++++++++++++++++ content/docs/reference-events.md | 29 ++-------------------- static/_redirects | 2 +- vercel.json | 2 +- 5 files changed, 41 insertions(+), 32 deletions(-) create mode 100644 content/docs/legacy-event-pooling.md diff --git a/content/docs/faq-functions.md b/content/docs/faq-functions.md index 18fdfe11..d3aa6f7f 100644 --- a/content/docs/faq-functions.md +++ b/content/docs/faq-functions.md @@ -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); } diff --git a/content/docs/legacy-event-pooling.md b/content/docs/legacy-event-pooling.md new file mode 100644 index 00000000..0ba91e9d --- /dev/null +++ b/content/docs/legacy-event-pooling.md @@ -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); +} +``` diff --git a/content/docs/reference-events.md b/content/docs/reference-events.md index 6cae9bb1..74541573 100644 --- a/content/docs/reference-events.md +++ b/content/docs/reference-events.md @@ -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} diff --git a/static/_redirects b/static/_redirects index 8757815d..ee53fade 100644 --- a/static/_redirects +++ b/static/_redirects @@ -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 diff --git a/vercel.json b/vercel.json index d532a5bd..6a26fb69 100644 --- a/vercel.json +++ b/vercel.json @@ -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 },