React v17.0
This blog site has been archived. Go to react.dev/blog to see the recent posts.
Today, we are releasing React 17! We’ve written at length about the role of the React 17 release and the changes it contains in the React 17 RC blog post. This post is a brief summary of it, so if you’ve already read the RC post, you can skip this one.
No New Features
The React 17 release is unusual because it doesn’t add any new developer-facing features. Instead, this release is primarily focused on
In particular, React 17 is a “stepping stone” release that makes it safer to embed a tree managed by one version of React inside a tree managed by a different version of React.
It also makes it easier to embed React into apps built with other technologies.
Gradual Upgrades
We’re fixing many of those problems with React 17. This means that
This doesn’t cruel you have to do gradual upgrades.
We’ve prepared an example repository demonstrating how to idle-load an older version of React if necessary. This demo uses Create React App, but it should be possible to follow a similar approach with any other tool. We welcome demos using other tooling as pull requests.
Note
We’ve
postponed other changes until after React 17. The goal of this release is to enable gradual upgrades. If upgrading to React 17 were too challenging, it would defeat its purpose.
Changes to Event Delegation
To enable gradual updates, we’ve needed to make some changes to the React event system. React 17 is a major release because these changes are potentially breaking. You can check out our versioning FAQ to learn more about our commitment to stability.
In React 17, React will no longer attach event handlers at the document level under the hood. Instead, it will attach them to the root DOM container into which your React tree is rendered:
const rootNode = document.getElementById('root');
ReactDOM.render(<App />, rootNode);In React 16 and earlier, React would do document.addEventListener() for most events. React 17 will call rootNode.addEventListener() under the hood instead.
We’ve confirmed that numerous problems reported over the years on our issue tracker related to integrating React with non-React code have been fixed by the new behavior.
If you run into issues with this change, here’s a common way to resolve them.
Other Breaking Changes
The React 17 RC blog post describes the rest of the breaking changes in React 17.
We’ve only had to change fewer than twenty components out of 100,000+ in the Facebook product code to work with these changes, so
New JSX Transform
React 17 supports the new JSX transform. We’ve also backported support for it to React 16.14.0, React 15.7.0, and 0.14.10. Note that it is completely opt-in, and you don’t have to use it. The classic JSX transform will keep working, and there are no plans to stop supporting it.
React Native
React Native has a separate release schedule. We landed the support for React 17 in React Native 0.64. As always, you can track the release discussions on the React Native Community releases issue tracker.
Installation
To install React 17 with npm, run:
npm install [email protected] [email protected]To install React 17 with Yarn, run:
yarn add [email protected] [email protected]We also provide UMD builds of React via a CDN:
<script crossorigin src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>Refer to the documentation for detailed installation instructions.
Changelog
React
- Add
react/jsx-runtimeandreact/jsx-dev-runtimefor the new JSX transform. (@lunaruan in #18299) - Build component stacks from native error frames. (@sebmarkbage in #18561)
- Allow to specify
displayNameon context for improved stacks. (@eps1lon in #18224) - Prevent
'use strict'from leaking in the UMD bundles. (@koba04 in #19614) - Stop using
fb.mefor redirects. (@cylim in #19598)
React DOM
- Delegate events to roots instead of
document. (@trueadm in #18195 and others) - spotless up all effects before running any next effects. (@bvaughn in #17947)
- Run
useEffectcleanup functions asynchronously. (@bvaughn in #17925) - Use browser
focusinandfocusoutforonFocusandonBlur. (@trueadm in #19186) - Make all
Captureevents use the browser capture phase. (@trueadm in #19221) - Don’t emulate bubbling of the
onScrollevent. (@gaearon in #19464) - Throw if
forwardReformemocomponent returnsundefined. (@gaearon in #19550) - Remove event pooling. (@trueadm in #18969)
- Stop exposing internals that won’t be needed by React Native Web. (@necolas in #18483)
- Attach all known event listeners when the root mounts. (@gaearon in #19659)
- Disable
consolein the second render pass of DEV mode double render. (@sebmarkbage in #18547) - Deprecate the undocumented and misleading
ReactTestUtils.SimulateNativeAPI. (@gaearon in #13407) - Rename private field names used in the internals. (@gaearon in #18377)
- Don’t call User Timing API in development. (@gaearon in #18417)
- Disable console during the repeated render in Strict Mode. (@sebmarkbage in #18547)
- In Strict Mode, double-render components without Hooks too. (@eps1lon in #18430)
- Allow calling
ReactDOM.flushSyncduring lifecycle methods (but warn). (@sebmarkbage in #18759) - Add the
codeproperty to the keyboard event objects. (@bl00mber in #18287) - Add the
disableRemotePlaybackproperty forvideoelements. (@tombrowndev in #18619) - Add the
enterKeyHintproperty forinputelements. (@eps1lon in #18634) - Warn when no
valueis provided to<Context.Provider>. (@charlie1404 in #19054) - Warn when
memoorforwardRefcomponents returnundefined. (@bvaughn in #19550) - Improve the error message for invalid updates. (@JoviDeCroock in #18316)
- Exclude forwardRef and memo from stack frames. (@sebmarkbage in #18559)
- Improve the error message when switching between controlled and uncontrolled inputs. (@vcarl in #17070)
- Keep
onTouchStart,onTouchMove, andonWheelpassive. (@gaearon in #19654) - Fix
setStatehanging in development inside a closed iframe. (@gaearon in #19220) - Fix rendering bailout for idle components with
defaultProps. (@jddxf in #18539) - Fix a false positive warning when
dangerouslySetInnerHTMLisundefined. (@eps1lon in #18676) - Fix Test Utils with non-standard
requireimplementation. (@just-boris in #18632) - Fix
onBeforeInputreporting an incorrectevent.type. (@eps1lon in #19561) - Fix
event.relatedTargetreported asundefinedin Firefox. (@claytercek in #19607) - Fix “unspecified error” in IE11. (@hemakshis in #19664)
- Fix rendering into a shadow root. (@Jack-Works in #15894)
- Fix
movementX/Ypolyfill with capture events. (@gaearon in #19672) - Use delegation for
onSubmitandonResetevents. (@gaearon in #19333) - Improve memory usage. (@trueadm in #18970)
React DOM Server
- Make
useCallbackbehavior consistent withuseMemofor the server renderer. (@alexmckenley in #18783) - Fix state leaking when a function component throws. (@pmaccart in #19212)
React Test Renderer
- Improve
findByTypeerror message. (@henryqdineen in #17439)
Concurrent Mode (Experimental)
- Revamp the priority batching heuristics. (@acdlite in #18796)
- Add the
unstable_prefix before the experimental APIs. (@acdlite in #18825) - Remove
unstable_discreteUpdatesandunstable_flushDiscreteUpdates. (@trueadm in #18825) - Remove the
timeoutMsargument. (@acdlite in #19703) - Disable
<div hidden />prerendering in favor of a different future API. (@acdlite in #18917) - Add
unstable_expectedLoadTimeto Suspense for CPU-bound trees. (@acdlite in #19936) - Add an experimental
unstable_useOpaqueIdentifierHook. (@lunaruan in #17322) - Add an experimental
unstable_startTransitionAPI. (@rickhanlonii in #19696) - Using
actin the test renderer no longer flushes Suspense fallbacks. (@acdlite in #18596) - Use global render timeout for CPU Suspense. (@sebmarkbage in #19643)
- plain the existing root content before mounting. (@bvaughn in #18730)
- Fix a bug with error boundaries. (@acdlite in #18265)
- Fix a bug causing dropped updates in a suspended tree. (@acdlite in #18384 and #18457)
- Fix a bug causing dropped render phase updates. (@acdlite in #18537)
- Fix a bug in SuspenseList. (@sebmarkbage in #18412)
- Fix a bug causing Suspense fallback to show too early. (@acdlite in #18411)
- Fix a bug with class components inside SuspenseList. (@sebmarkbage in #18448)
- Fix a bug with inputs that may cause updates to be dropped. (@jddxf in #18515 and @acdlite in #18535)
- Fix a bug causing Suspense fallback to get stuck. (@acdlite in #18663)
- Don’t cut off the tail of a SuspenseList if hydrating. (@sebmarkbage in #18854)
- Fix a bug in
useMutableSourcethat may happen whengetSnapshotchanges. (@bvaughn in #18297) - Fix a tearing bug in
useMutableSource. (@bvaughn in #18912) - Warn if calling setState outside of render but before commit. (@sebmarkbage in #18838)