{"componentChunkName":"component---src-templates-blog-js","path":"/blog/2020/08/10/react-v17-rc.html","result":{"data":{"markdownRemark":{"html":"<p>Today, we are publishing the first Release Candidate for React 17. It has been two and a half years since <a href=\"/blog/2017/09/26/react-v16.0.html\">the previous major release of React</a>, which is a long time even by our standards! In this blog post, we will describe the role of this major release, what changes you can expect in it, and how you can try this release.</p>\n<h2 id=\"no-new-features\"><a href=\"#no-new-features\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>No New Features </h2>\n<p>The React 17 release is unusual because it doesn’t add any new developer-facing features. Instead, this release is primarily focused on <strong>making it easier to upgrade React itself</strong>.</p>\n<p>We’re actively working on the new React features, but they’re not a part of this release. The React 17 release is a key part of our strategy to roll them out without leaving anyone behind.</p>\n<p>In particular, <strong>React 17 is a “stepping stone” release</strong> that makes it safer to embed a tree managed by one version of React inside a tree managed by a different version of React.</p>\n<h2 id=\"gradual-upgrades\"><a href=\"#gradual-upgrades\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Gradual Upgrades </h2>\n<p>For the past seven years, React upgrades have been “all-or-nothing”. Either you stay on an old version, or you upgrade your whole app to a new version. There was no in-between.</p>\n<p>This has worked out so far, but we are running into the limits of the “all-or-nothing” upgrade strategy. Some API changes, for example, deprecating the <a href=\"/docs/legacy-context.html\">legacy context API</a>, are impossible to do in an automated way. Even though most apps written today don’t ever use them, we still support them in React. We have to choose between supporting them in React indefinitely or leaving some apps behind on an old version of React. Both of these options aren’t great.</p>\n<p>So we wanted to provide another option.</p>\n<p><strong>React 17 enables gradual React upgrades.</strong> When you upgrade from React 15 to 16 (or, soon, from React 16 to 17), you would usually upgrade your whole app at once. This works well for many apps. But it can get increasingly challenging if the codebase was written more than a few years ago and isn’t actively maintained. And while it’s possible to use two versions of React on the page, until React 17 this has been fragile and caused problems with events.</p>\n<p>We’re fixing many of those problems with React 17. This means that <strong>when React 18 and the next future versions come out, you will now have more options</strong>. The first option will be to upgrade your whole app at once, like you might have done before. But you will also have an option to upgrade your app piece by piece. For example, you might decide to migrate most of your app to React 18, but keep some lazy-loaded dialog or a subroute on React 17.</p>\n<p>This doesn’t mean you <em>have to</em> do gradual upgrades. For most apps, upgrading all at once is still the best solution. Loading two versions of React — even if one of them is loaded lazily on demand — is still not ideal. However, for larger apps that aren’t actively maintained, this option may make sense to consider, and React 17 enables those apps to not get left behind.</p>\n<p>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. In practice, we’ve only had to change fewer than twenty components out of 100,000+ so <strong>we expect that most apps can upgrade to React 17 without too much trouble</strong>. <a href=\"https://github.com/facebook/react/issues\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Tell us</a> if you run into problems.</p>\n<h3 id=\"demo-of-gradual-upgrades\"><a href=\"#demo-of-gradual-upgrades\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Demo of Gradual Upgrades </h3>\n<p>We’ve prepared an <a href=\"https://github.com/reactjs/react-gradual-upgrade-demo/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">example repository</a> demonstrating how to lazy-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.</p>\n<blockquote>\n<p>Note</p>\n<p>We’ve <strong>postponed other changes</strong> until after React 17. The goal of this release is to enable gradual upgrades. If upgrading to React 17 were too difficult, it would defeat its purpose.</p>\n</blockquote>\n<h2 id=\"changes-to-event-delegation\"><a href=\"#changes-to-event-delegation\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Changes to Event Delegation </h2>\n<p>Technically, it has always been possible to nest apps developed with different versions of React. However, it was rather fragile because of how the React event system worked.</p>\n<p>In React components, you usually write event handlers inline:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token attr-name\">onClick</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>handleClick<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>The vanilla DOM equivalent to this code is something like:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">myButton<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">,</span> handleClick<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>However, for most events, React doesn’t actually attach them to the DOM nodes on which you declare them. Instead, React attaches one handler per event type directly at the <code class=\"gatsby-code-text\">document</code> node. This is called <a href=\"https://davidwalsh.name/event-delegate\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">event delegation</a>. In addition to its performance benefits on large application trees, it also makes it easier to add new features like <a href=\"https://twitter.com/dan_abramov/status/1200118229697486849\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">replaying events</a>.</p>\n<p>React has been doing event delegation automatically since its first release. When a DOM event fires on the document, React figures out which component to call, and then the React event “bubbles” upwards through your components. But behind the scenes, the native event has already bubbled up to the <code class=\"gatsby-code-text\">document</code> level, where React installs its event handlers.</p>\n<p>However, this is a problem for gradual upgrades.</p>\n<p>If you have multiple React versions on the page, they all register event handlers at the top. This breaks <code class=\"gatsby-code-text\">e.stopPropagation()</code>: if a nested tree has stopped propagation of an event, the outer tree would still receive it. This made it difficult to nest different versions of React. This concern is not hypothetical — for example, the Atom editor <a href=\"https://github.com/facebook/react/pull/8117\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ran into this</a> four years ago.</p>\n<p>This is why we’re changing how React attaches events to the DOM under the hood.</p>\n<p><strong>In React 17, React will no longer attach event handlers at the <code class=\"gatsby-code-text\">document</code> level. Instead, it will attach them to the root DOM container into which your React tree is rendered:</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">const</span> rootNode <span class=\"token operator\">=</span> document<span class=\"token punctuation\">.</span><span class=\"token function\">getElementById</span><span class=\"token punctuation\">(</span><span class=\"token string\">'root'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nReactDOM<span class=\"token punctuation\">.</span><span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">App</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">,</span> rootNode<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>In React 16 and earlier, React would do <code class=\"gatsby-code-text\">document.addEventListener()</code> for most events. React 17 will call <code class=\"gatsby-code-text\">rootNode.addEventListener()</code> under the hood instead.</p>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/bb4b10114882a50090b8ff61b3c4d0fd/31868/react_17_delegation.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 840px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 77.14285714285715%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsSAAALEgHS3X78AAACcUlEQVQ4y21T2W4TMRTNr0MfgDeEkPgSJF55JarUJSVpm07WaZLZV+/24XomE9LFypEd3zPnrh59nHFcED5MGT7fc/wIBL7OOT7ds+7O21/D878/CXwjfHnov7042kYhs/DYEnbcIpYOB+HwLIGQO7IZDJyBFxIvEh6u+2Z7Zh/htBz9bL8bAbO7AjTDu8u5427fmEaWjN7MtUHBOPKiRB7O0Nz/gkjm0G3a2TseHbS1KIVCUTfI8vxkGzByHbFHXdfYRwni9RSu3MAqBpWvYXhxDKyPjHOO/X7fwS9LTgbbaDhYY8AYQ11VOGQVZJPAippQwTQxZWdOaXnBgjJJkhjyRSVcX0NDHhqpwLQFbxtsSobn7ABIEpQNDMvgjOzSY1KjVQYNE1jscgTMYRm14Kp3OBqUGV0cuMFkFeJxl6AsI5iWhLSkPe0E/VLGIhUGQVrh5zjA9abCrpBYxexlynErcbmOMNnnmEQ15k8TsOrQRdWlfOT56O52KS43CcaLGL9nzyi4QFQqKO3Hhog+2CCr8TcXeGgtVlWLeTBBRBFLxSnl/FSniCncxRVuMoPHFvgTNphFJaLWQJvjHHLjcHsoMU1KzNISD0mKx3CLec5oPAoYrfrGERYFw+W+wXUqcVsajMO6E1xXCi3Vt4vQ0683ByypGUsq8oK6F9QK61ZDklcMo0W8ZdHiZht3L+kqFpjlCstGo1Q971TDgkss8wZPWYGAhNf07ErtXowEjg8gLGpMM4G7RGDF+mdoXs+hV2dEjqiDibRoTT/5/im6swj9f9/pRPRCFTk98/t/bM7uSAhvInuP589aU1mk7ODP/wCR7n8+8QwuZQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"A diagram showing how React 17 attaches events to the roots rather than to the document\"\n        title=\"\"\n        src=\"/static/bb4b10114882a50090b8ff61b3c4d0fd/1e088/react_17_delegation.png\"\n        srcset=\"/static/bb4b10114882a50090b8ff61b3c4d0fd/65ed1/react_17_delegation.png 210w,\n/static/bb4b10114882a50090b8ff61b3c4d0fd/d10fb/react_17_delegation.png 420w,\n/static/bb4b10114882a50090b8ff61b3c4d0fd/1e088/react_17_delegation.png 840w,\n/static/bb4b10114882a50090b8ff61b3c4d0fd/78612/react_17_delegation.png 1260w,\n/static/bb4b10114882a50090b8ff61b3c4d0fd/21cdd/react_17_delegation.png 1680w,\n/static/bb4b10114882a50090b8ff61b3c4d0fd/31868/react_17_delegation.png 3496w\"\n        sizes=\"(max-width: 840px) 100vw, 840px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<p>Thanks to this change, <strong>it is now safer to embed a React tree managed by one version inside a tree managed by a different React version</strong>. Note that for this to work, both of the versions would need to be 17 or higher, which is why upgrading to React 17 is important. In a way, React 17 is a “stepping stone” release that makes next gradual upgrades feasible.</p>\n<p>This change also <strong>makes it easier to embed React into apps built with other technologies</strong>. For example, if the outer “shell” of your app is written in jQuery, but the newer code inside of it is written with React, <code class=\"gatsby-code-text\">e.stopPropagation()</code> inside the React code would now prevent it from reaching the jQuery code — as you would expect. This also works in the other direction. If you no longer like React and want to rewrite your app — for example, in jQuery — you can start converting the outer shell from React to jQuery without breaking the event propagation.</p>\n<p>We’ve confirmed that <a href=\"https://github.com/facebook/react/issues/7094\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">numerous</a> <a href=\"https://github.com/facebook/react/issues/8693\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">problems</a> <a href=\"https://github.com/facebook/react/issues/12518\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">reported</a> <a href=\"https://github.com/facebook/react/issues/13451\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">over</a> <a href=\"https://github.com/facebook/react/issues/4335\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">the</a> <a href=\"https://github.com/facebook/react/issues/1691\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">years</a> <a href=\"https://github.com/facebook/react/issues/285#issuecomment-253502585\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">on</a> <a href=\"https://github.com/facebook/react/pull/8117\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">our</a> <a href=\"https://github.com/facebook/react/issues/11530\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">issue</a> <a href=\"https://github.com/facebook/react/issues/7128\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">tracker</a> related to integrating React with non-React code have been fixed by the new behavior.</p>\n<blockquote>\n<p>Note</p>\n<p>You might be wondering whether this breaks <a href=\"/docs/portals.html\">Portals</a> outside of the root container. The answer is that React <em>also</em> listens to events on portal containers, so this is not an issue.</p>\n</blockquote>\n<h4 id=\"fixing-potential-issues\"><a href=\"#fixing-potential-issues\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Fixing Potential Issues </h4>\n<p>As with any breaking change, it is likely some code would need to be adjusted. At Facebook, we had to adjust about 10 modules in total (out of many thousands) to work with this change.</p>\n<p>For example, if you add manual DOM listeners with <code class=\"gatsby-code-text\">document.addEventListener(...)</code>, you might expect them to catch all React events. In React 16 and earlier, even if you call <code class=\"gatsby-code-text\">e.stopPropagation()</code> in a React event handler, your custom <code class=\"gatsby-code-text\">document</code> listeners would still receive them because the native event is <em>already</em> at the document level. With React 17, the propagation <em>would</em> stop (as requested!), so your <code class=\"gatsby-code-text\">document</code> handlers would not fire:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">document<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// This custom handler will no longer receive clicks</span>\n  <span class=\"token comment\">// from React components that called e.stopPropagation()</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>You can fix code like this by converting your listener to use the <a href=\"https://javascript.info/bubbling-and-capturing#capturing\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">capture phase</a>. To do this, you can pass <code class=\"gatsby-code-text\">{ capture: true }</code> as the third argument to <code class=\"gatsby-code-text\">document.addEventListener</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\">document<span class=\"token punctuation\">.</span><span class=\"token function\">addEventListener</span><span class=\"token punctuation\">(</span><span class=\"token string\">'click'</span><span class=\"token punctuation\">,</span> <span class=\"token keyword\">function</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// Now this event handler uses the capture phase,</span>\n  <span class=\"token comment\">// so it receives *all* click events below!</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span> capture<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Note how this strategy is more resilient overall — for example, it will probably fix existing bugs in your code that happen when <code class=\"gatsby-code-text\">e.stopPropagation()</code> is called outside of a React event handler. In other words, <strong>event propagation in React 17 works closer to the regular DOM</strong>.</p>\n<h2 id=\"other-breaking-changes\"><a href=\"#other-breaking-changes\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Other Breaking Changes </h2>\n<p>We’ve kept the breaking changes in React 17 to the minimum. For example, it doesn’t remove any of the methods that have been deprecated in the previous releases. However, it does include a few other breaking changes that have been relatively safe in our experience. In total, we’ve had to adjust fewer than 20 out of 100,000+ our components because of them.</p>\n<h3 id=\"aligning-with-browsers\"><a href=\"#aligning-with-browsers\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Aligning with Browsers </h3>\n<p>We’ve made a couple of smaller changes related to the event system:</p>\n<ul>\n<li>The <code class=\"gatsby-code-text\">onScroll</code> event <strong>no longer bubbles</strong> to prevent <a href=\"https://github.com/facebook/react/issues/15723\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">common confusion</a>.</li>\n<li>React <code class=\"gatsby-code-text\">onFocus</code> and <code class=\"gatsby-code-text\">onBlur</code> events have switched to using the native <code class=\"gatsby-code-text\">focusin</code> and <code class=\"gatsby-code-text\">focusout</code> events under the hood, which more closely match React’s existing behavior and sometimes provide extra information.</li>\n<li>Capture phase events (e.g. <code class=\"gatsby-code-text\">onClickCapture</code>) now use real browser capture phase listeners.</li>\n</ul>\n<p>These changes align React closer with the browser behavior and improve interoperability.</p>\n<blockquote>\n<p>Note</p>\n<p>Although React 17 switched from <code class=\"gatsby-code-text\">focus</code> to <code class=\"gatsby-code-text\">focusin</code> <em>under the hood</em> for the <code class=\"gatsby-code-text\">onFocus</code> event, note that this has <strong>not</strong> affected the bubbling behavior. In React, <code class=\"gatsby-code-text\">onFocus</code> event has always bubbled, and it continues to do so in React 17 because generally it is a more useful default. See <a href=\"https://codesandbox.io/s/strange-albattani-7tqr7?file=/src/App.js\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">this sandbox</a> for the different checks you can add for different particular use cases.</p>\n</blockquote>\n<h3 id=\"no-event-pooling\"><a href=\"#no-event-pooling\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>No Event Pooling </h3>\n<p>React 17 removes the “event pooling” optimization from React. It doesn’t improve performance in modern browsers and confuses even experienced React users:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">handleChange</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">e</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">setData</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">data</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token operator\">...</span>data<span class=\"token punctuation\">,</span>\n    <span class=\"token comment\">// This crashes in React 16 and earlier:</span>\n    text<span class=\"token operator\">:</span> e<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This is because React reused the event objects between different events for performance in old browsers, and set all event fields to <code class=\"gatsby-code-text\">null</code> in between them. With React 16 and earlier, you have to call <code class=\"gatsby-code-text\">e.persist()</code> to properly use the event, or read the property you need earlier.</p>\n<p><strong>In React 17, this code works as you would expect. The old event pooling optimization has been fully removed, so you can read the event fields whenever you need them.</strong></p>\n<p>This is a behavior change, which is why we’re marking it as breaking, but in practice we haven’t seen it break anything at Facebook. (Maybe it even fixed a few bugs!) Note that <code class=\"gatsby-code-text\">e.persist()</code> is still available on the React event object, but now it doesn’t do anything.</p>\n<h3 id=\"effect-cleanup-timing\"><a href=\"#effect-cleanup-timing\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Effect Cleanup Timing </h3>\n<p>We are making the timing of the <code class=\"gatsby-code-text\">useEffect</code> cleanup function more consistent.</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// This is the effect itself.</span>\n<span class=\"gatsby-highlight-code-line\">  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    <span class=\"token comment\">// This is its cleanup.</span></span><span class=\"gatsby-highlight-code-line\">  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Most effects don’t need to delay screen updates, so React runs them asynchronously soon after the update has been reflected on the screen. (For the rare cases where you need an effect to block paint, e.g. to measure and position a tooltip, prefer <code class=\"gatsby-code-text\">useLayoutEffect</code>.)</p>\n<p>However, when a component is unmounting, effect <em>cleanup</em> functions used to run synchronously (similar to <code class=\"gatsby-code-text\">componentWillUnmount</code> being synchronous in classes). We’ve found that this is not ideal for larger apps because it slows down large screen transitions (e.g. switching tabs).</p>\n<p><strong>In React 17, the effect cleanup function will always runs asynchronously — for example, if the component is unmounting, the cleanup will run <em>after</em> the screen has been updated.</strong></p>\n<p>This mirrors how the effects themselves run more closely. In the rare cases where you might want to rely on the synchronous execution, you can switch to <code class=\"gatsby-code-text\">useLayoutEffect</code> instead.</p>\n<blockquote>\n<p>Note</p>\n<p>You might be wondering whether this means that you’ll now be unable to fix warnings about <code class=\"gatsby-code-text\">setState</code> on unmounted components. Don’t worry — React specifically checks for this case, and does <em>not</em> fire <code class=\"gatsby-code-text\">setState</code> warnings in the short gap between unmounting and the cleanup. <strong>So code cancelling requests or intervals can almost always stay the same.</strong></p>\n</blockquote>\n<p>Additionally, React 17 will always execute all effect cleanup functions (for all components) before it runs any new effects. React 16 only guaranteed this ordering for effects within a component.</p>\n<h4 id=\"potential-issues\"><a href=\"#potential-issues\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Potential Issues </h4>\n<p>We’ve only seen a couple of components break with this change, although reusable libraries may need to test it more thoroughly. One example of problematic code may look like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  someRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">someSetupMethod</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    someRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">.</span><span class=\"token function\">someCleanupMethod</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>The problem is that <code class=\"gatsby-code-text\">someRef.current</code> is mutable, so by the time the cleanup function runs, it may have been set to <code class=\"gatsby-code-text\">null</code>. The solution is to capture any mutable values <em>inside</em> the effect:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token function\">useEffect</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> instance <span class=\"token operator\">=</span> someRef<span class=\"token punctuation\">.</span>current<span class=\"token punctuation\">;</span>\n  instance<span class=\"token punctuation\">.</span><span class=\"token function\">someSetupMethod</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    instance<span class=\"token punctuation\">.</span><span class=\"token function\">someCleanupMethod</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>We don’t expect this to be a common problem because <a href=\"https://github.com/facebook/react/tree/master/packages/eslint-plugin-react-hooks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">our <code class=\"gatsby-code-text\">eslint-plugin-react-hooks/exhaustive-deps</code> lint rule</a> (make sure you use it!) has always warned about this.</p>\n<h3 id=\"consistent-errors-for-returning-undefined\"><a href=\"#consistent-errors-for-returning-undefined\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Consistent Errors for Returning Undefined </h3>\n<p>In React 16 and earlier, returning <code class=\"gatsby-code-text\">undefined</code> has always been an error:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Button</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Error: Nothing was returned from render</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This is in part because it’s easy to return <code class=\"gatsby-code-text\">undefined</code> unintentionally:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">Button</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// We forgot to write return, so this component returns undefined.</span>\n  <span class=\"token comment\">// React surfaces this as an error instead of ignoring it.</span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Previously, React only did this for class and function components, but did not check the return values of <code class=\"gatsby-code-text\">forwardRef</code> and <code class=\"gatsby-code-text\">memo</code> components. This was due to a coding mistake.</p>\n<p><strong>In React 17, the behavior for <code class=\"gatsby-code-text\">forwardRef</code> and <code class=\"gatsby-code-text\">memo</code> components is consistent with regular function and class components. Returning <code class=\"gatsby-code-text\">undefined</code> from them is an error.</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">let</span> Button <span class=\"token operator\">=</span> <span class=\"token function\">forwardRef</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// We forgot to write return, so this component returns undefined.</span>\n  <span class=\"token comment\">// React 17 surfaces this as an error instead of ignoring it.</span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">let</span> Button <span class=\"token operator\">=</span> <span class=\"token function\">memo</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// We forgot to write return, so this component returns undefined.</span>\n  <span class=\"token comment\">// React 17 surfaces this as an error instead of ignoring it.</span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>button</span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>For the cases where you want to render nothing intentionally, return <code class=\"gatsby-code-text\">null</code> instead.</p>\n<h3 id=\"native-component-stacks\"><a href=\"#native-component-stacks\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Native Component Stacks </h3>\n<p>When you throw an error in the browser, the browser gives you a stack trace with JavaScript function names and their locations. However, JavaScript stacks are often not enough to diagnose a problem because the React tree hierarchy can be just as important. You want to know not just that a <code class=\"gatsby-code-text\">Button</code> threw an error, but <em>where in the React tree</em> that <code class=\"gatsby-code-text\">Button</code> is.</p>\n<p>To solve this, React 16 started printing “component stacks” when you have an error. Still, they used to be inferior to the native JavaScript stacks. In particular, they were not clickable in the console because React didn’t know where the function was declared in the source code. Additionally, they were <a href=\"https://github.com/facebook/react/issues/12757\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">mostly useless in production</a>. Unlike regular minified JavaScript stacks which can be automatically restored to the original function names with a sourcemap, with React component stacks you had to choose between production stacks and bundle size.</p>\n<p><strong>In React 17, the component stacks are generated using a different mechanism that stitches them together from the regular native JavaScript stacks. This lets you get the fully symbolicated React component stack traces in a production environment.</strong></p>\n<p>The way React implements this is somewhat unorthodox. Currently, the browsers don’t provide a way to get a function’s stack frame (source file and location). So when React catches an error, it will now <em>reconstruct</em> its component stack by throwing (and catching) a temporary error from inside each of the components above, when it is possible. This adds a small performance penalty for crashes, but it only happens once per component type.</p>\n<p>If you’re curious, you can read more details in <a href=\"https://github.com/facebook/react/pull/18561\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">this pull request</a>, but for the most part this exact mechanism shouldn’t affect your code. From your perspective, the new feature is that component stacks are now clickable (because they rely on the native browser stack frames), and that you can decode them in production like you would with regular JavaScript errors.</p>\n<p>The part that constitutes a breaking change is that for this to work, React re-executes parts of some of the React functions and React class constructors above in the stack after an error is captured. Since render functions and class constructors shouldn’t have side effects (which is also important for server rendering), this should not pose any practical problems.</p>\n<h3 id=\"removing-private-exports\"><a href=\"#removing-private-exports\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Removing Private Exports </h3>\n<p>Finally, the last notable breaking change is that we’ve removed some React internals that were previously exposed to other projects. In particular, <a href=\"https://github.com/necolas/react-native-web\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">React Native for Web</a> used to depend on some internals of the event system, but that dependency was fragile and used to break.</p>\n<p><strong>In React 17, these private exports have been removed. As far as we’re aware, React Native for Web was the only project using them, and they have already completed a migration to a different approach that doesn’t depend on those private exports.</strong></p>\n<p>This means that the older versions of React Native for Web won’t be compatible with React 17, but the newer versions will work with it. In practice, this doesn’t change much because React Native for Web had to release new versions to adapt to internal React changes anyway.</p>\n<p>Additionally, we’ve removed the <code class=\"gatsby-code-text\">ReactTestUtils.SimulateNative</code> helper methods. They have never been documented, didn’t do quite what their names implied, and didn’t work with the changes we’ve made to the event system. If you want a convenient way to fire native browser events in tests, check out the <a href=\"https://testing-library.com/docs/dom-testing-library/api-events\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">React Testing Library</a> instead.</p>\n<h2 id=\"installation\"><a href=\"#installation\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Installation </h2>\n<p>We encourage you to try React 17.0 Release Candidate soon and <a href=\"https://github.com/facebook/react/issues\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">raise any issues</a> for the problems you might encounter in the migration. <strong>Keep in mind that a release candidate is more likely to contain bugs than a stable release, so don’t deploy it to production yet.</strong></p>\n<p>To install React 17 RC with npm, run:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"gatsby-code-bash\"><code class=\"gatsby-code-bash\"><span class=\"token function\">npm</span> <span class=\"token function\">install</span> react@17.0.0-rc.2 react-dom@17.0.0-rc.2</code></pre></div>\n<p>To install React 17 RC with Yarn, run:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"gatsby-code-bash\"><code class=\"gatsby-code-bash\"><span class=\"token function\">yarn</span> <span class=\"token function\">add</span> react@17.0.0-rc.2 react-dom@17.0.0-rc.2</code></pre></div>\n<p>We also provide UMD builds of React via a CDN:</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"gatsby-code-html\"><code class=\"gatsby-code-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span> <span class=\"token attr-name\">crossorigin</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>https://unpkg.com/react@17.0.0-rc.2/umd/react.production.min.js<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token script\"></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>script</span> <span class=\"token attr-name\">crossorigin</span> <span class=\"token attr-name\">src</span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">=</span><span class=\"token punctuation\">\"</span>https://unpkg.com/react-dom@17.0.0-rc.2/umd/react-dom.production.min.js<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span><span class=\"token script\"></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>script</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>Refer to the documentation for <a href=\"/docs/installation.html\">detailed installation instructions</a>.</p>\n<h2 id=\"changelog\"><a href=\"#changelog\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Changelog </h2>\n<h3 id=\"react\"><a href=\"#react\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>React </h3>\n<ul>\n<li>Add <code class=\"gatsby-code-text\">react/jsx-runtime</code> and <code class=\"gatsby-code-text\">react/jsx-dev-runtime</code> for the <a href=\"https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">new JSX transform</a>. (<a href=\"https://github.com/lunaruan\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@lunaruan</a> in <a href=\"https://github.com/facebook/react/pull/18299\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18299</a>)</li>\n<li>Build component stacks from native error frames. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18561\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18561</a>)</li>\n<li>Allow to specify <code class=\"gatsby-code-text\">displayName</code> on context for improved stacks. (<a href=\"https://github.com/eps1lon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@eps1lon</a> in <a href=\"https://github.com/facebook/react/pull/18224\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18224</a>)</li>\n<li>Prevent <code class=\"gatsby-code-text\">&#39;use strict&#39;</code> from leaking in the UMD bundles. (<a href=\"https://github.com/koba04\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@koba04</a> in <a href=\"https://github.com/facebook/react/pull/19614\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19614</a>)</li>\n<li>Stop using <code class=\"gatsby-code-text\">fb.me</code> for redirects. (<a href=\"https://github.com/cylim\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@cylim</a> in <a href=\"https://github.com/facebook/react/pull/19598\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19598</a>)</li>\n</ul>\n<h3 id=\"react-dom\"><a href=\"#react-dom\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>React DOM </h3>\n<ul>\n<li>Delegate events to roots instead of <code class=\"gatsby-code-text\">document</code>. (<a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@trueadm</a> in <a href=\"https://github.com/facebook/react/pull/18195\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18195</a> and <a href=\"https://github.com/facebook/react/pulls?q=is%3Apr+author%3Atrueadm+modern+event+is%3Amerged\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">others</a>)</li>\n<li>Clean up all effects before running any next effects. (<a href=\"https://github.com/bvaughn\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@bvaughn</a> in <a href=\"https://github.com/facebook/react/pull/17947\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#17947</a>)</li>\n<li>Run <code class=\"gatsby-code-text\">useEffect</code> cleanup functions asynchronously. (<a href=\"https://github.com/bvaughn\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@bvaughn</a> in <a href=\"https://github.com/facebook/react/pull/17925\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#17925</a>)</li>\n<li>Use browser <code class=\"gatsby-code-text\">focusin</code> and <code class=\"gatsby-code-text\">focusout</code> for <code class=\"gatsby-code-text\">onFocus</code> and <code class=\"gatsby-code-text\">onBlur</code>. (<a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@trueadm</a> in <a href=\"https://github.com/facebook/react/pull/19186\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19186</a>)</li>\n<li>Make all <code class=\"gatsby-code-text\">Capture</code> events use the browser capture phase. (<a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@trueadm</a> in <a href=\"https://github.com/facebook/react/pull/19221\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19221</a>)</li>\n<li>Don’t emulate bubbling of the <code class=\"gatsby-code-text\">onScroll</code> event. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/19464\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19464</a>)</li>\n<li>Throw if <code class=\"gatsby-code-text\">forwardRef</code> or <code class=\"gatsby-code-text\">memo</code> component returns <code class=\"gatsby-code-text\">undefined</code>. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/19550\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19550</a>)</li>\n<li>Remove event pooling. (<a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@trueadm</a> in <a href=\"https://github.com/facebook/react/pull/18969\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18969</a>)</li>\n<li>Stop exposing internals that won’t be needed by React Native Web. (<a href=\"https://github.com/necolas\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@necolas</a> in <a href=\"https://github.com/facebook/react/pull/18483\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18483</a>)</li>\n<li>Attach all known event listeners when the root mounts. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/19659\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19659</a>)</li>\n<li>Disable <code class=\"gatsby-code-text\">console</code> in the second render pass of DEV mode double render. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18547\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18547</a>)</li>\n<li>Deprecate the undocumented and misleading <code class=\"gatsby-code-text\">ReactTestUtils.SimulateNative</code> API. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/13407\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#13407</a>)</li>\n<li>Rename private field names used in the internals. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/18377\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18377</a>)</li>\n<li>Don’t call User Timing API in development. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/18417\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18417</a>)</li>\n<li>Disable console during the repeated render in Strict Mode. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18547\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18547</a>)</li>\n<li>In Strict Mode, double-render components without Hooks too. (<a href=\"https://github.com/eps1lon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@eps1lon</a> in <a href=\"https://github.com/facebook/react/pull/18430\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18430</a>)</li>\n<li>Allow calling <code class=\"gatsby-code-text\">ReactDOM.flushSync</code> during lifecycle methods (but warn). (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18759\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18759</a>)</li>\n<li>Add the <code class=\"gatsby-code-text\">code</code> property to the keyboard event objects. (<a href=\"https://github.com/bl00mber\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@bl00mber</a> in <a href=\"https://github.com/facebook/react/pull/18287\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18287</a>)</li>\n<li>Add the <code class=\"gatsby-code-text\">disableRemotePlayback</code> property for <code class=\"gatsby-code-text\">video</code> elements. (<a href=\"https://github.com/tombrowndev\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@tombrowndev</a> in <a href=\"https://github.com/facebook/react/pull/18619\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18619</a>)</li>\n<li>Add the <code class=\"gatsby-code-text\">enterKeyHint</code> property for <code class=\"gatsby-code-text\">input</code> elements. (<a href=\"https://github.com/eps1lon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@eps1lon</a> in <a href=\"https://github.com/facebook/react/pull/18634\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18634</a>)</li>\n<li>Warn when no <code class=\"gatsby-code-text\">value</code> is provided to <code class=\"gatsby-code-text\">&lt;Context.Provider&gt;</code>. (<a href=\"https://github.com/charlie1404\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@charlie1404</a> in <a href=\"https://github.com/facebook/react/pull/19054\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19054</a>)</li>\n<li>Warn when <code class=\"gatsby-code-text\">memo</code> or <code class=\"gatsby-code-text\">forwardRef</code> components return <code class=\"gatsby-code-text\">undefined</code>. (<a href=\"https://github.com/bvaughn\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@bvaughn</a> in <a href=\"https://github.com/facebook/react/pull/19550\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19550</a>)</li>\n<li>Improve the error message for invalid updates. (<a href=\"https://github.com/JoviDeCroock\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@JoviDeCroock</a> in <a href=\"https://github.com/facebook/react/pull/18316\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18316</a>)</li>\n<li>Exclude forwardRef and memo from stack frames. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18559\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18559</a>)</li>\n<li>Improve the error message when switching between controlled and uncontrolled inputs. (<a href=\"https://github.com/vcarl\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@vcarl</a> in <a href=\"https://github.com/facebook/react/pull/17070\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#17070</a>)</li>\n<li>Keep <code class=\"gatsby-code-text\">onTouchStart</code>, <code class=\"gatsby-code-text\">onTouchMove</code>, and <code class=\"gatsby-code-text\">onWheel</code> passive. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/19654\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19654</a>)</li>\n<li>Fix <code class=\"gatsby-code-text\">setState</code> hanging in development inside a closed iframe. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/19220\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19220</a>)</li>\n<li>Fix rendering bailout for lazy components with <code class=\"gatsby-code-text\">defaultProps</code>. (<a href=\"https://github.com/jddxf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@jddxf</a> in <a href=\"https://github.com/facebook/react/pull/18539\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18539</a>)</li>\n<li>Fix a false positive warning when <code class=\"gatsby-code-text\">dangerouslySetInnerHTML</code> is <code class=\"gatsby-code-text\">undefined</code>. (<a href=\"https://github.com/eps1lon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@eps1lon</a> in <a href=\"https://github.com/facebook/react/pull/18676\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18676</a>)</li>\n<li>Fix Test Utils with non-standard <code class=\"gatsby-code-text\">require</code> implementation. (<a href=\"https://github.com/just-boris\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@just-boris</a> in <a href=\"https://github.com/facebook/react/pull/18632\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18632</a>)</li>\n<li>Fix <code class=\"gatsby-code-text\">onBeforeInput</code> reporting an incorrect <code class=\"gatsby-code-text\">event.type</code>. (<a href=\"https://github.com/eps1lon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@eps1lon</a> in <a href=\"https://github.com/facebook/react/pull/19561\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19561</a>)</li>\n<li>Fix <code class=\"gatsby-code-text\">event.relatedTarget</code> reported as <code class=\"gatsby-code-text\">undefined</code> in Firefox. (<a href=\"https://github.com/claytercek\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@claytercek</a> in <a href=\"https://github.com/facebook/react/pull/19607\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19607</a>)</li>\n<li>Fix “unspecified error” in IE11. (<a href=\"https://github.com/hemakshis\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@hemakshis</a> in <a href=\"https://github.com/facebook/react/pull/19664\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19664</a>)</li>\n<li>Fix rendering into a shadow root. (<a href=\"https://github.com/Jack-Works\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@Jack-Works</a> in <a href=\"https://github.com/facebook/react/pull/15894\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#15894</a>)</li>\n<li>Fix <code class=\"gatsby-code-text\">movementX/Y</code> polyfill with capture events. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/19672\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19672</a>)</li>\n<li>Use delegation for <code class=\"gatsby-code-text\">onSubmit</code> and <code class=\"gatsby-code-text\">onReset</code> events. (<a href=\"https://github.com/gaearon\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@gaearon</a> in <a href=\"https://github.com/facebook/react/pull/19333\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19333</a>)</li>\n<li>Improve memory usage. (<a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@trueadm</a> in <a href=\"https://github.com/facebook/react/pull/18970\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18970</a>)</li>\n</ul>\n<h3 id=\"react-dom-server\"><a href=\"#react-dom-server\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>React DOM Server </h3>\n<ul>\n<li>Make <code class=\"gatsby-code-text\">useCallback</code> behavior consistent with <code class=\"gatsby-code-text\">useMemo</code> for the server renderer. (<a href=\"https://github.com/alexmckenley\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@alexmckenley</a> in <a href=\"https://github.com/facebook/react/pull/18783\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18783</a>)</li>\n<li>Fix state leaking when a function component throws. (<a href=\"https://github.com/pmaccart\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@pmaccart</a> in <a href=\"https://github.com/facebook/react/pull/19212\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19212</a>)</li>\n</ul>\n<h3 id=\"react-test-renderer\"><a href=\"#react-test-renderer\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>React Test Renderer </h3>\n<ul>\n<li>Improve <code class=\"gatsby-code-text\">findByType</code> error message. (<a href=\"https://github.com/henryqdineen\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@henryqdineen</a> in <a href=\"https://github.com/facebook/react/pull/17439\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#17439</a>)</li>\n</ul>\n<h3 id=\"concurrent-mode-experimental\"><a href=\"#concurrent-mode-experimental\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Concurrent Mode (Experimental) </h3>\n<ul>\n<li>Revamp the priority batching heuristics. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18796\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18796</a>)</li>\n<li>Add the <code class=\"gatsby-code-text\">unstable_</code> prefix before the experimental APIs. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18825\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18825</a>)</li>\n<li>Remove <code class=\"gatsby-code-text\">unstable_discreteUpdates</code> and <code class=\"gatsby-code-text\">unstable_flushDiscreteUpdates</code>. (<a href=\"https://github.com/trueadm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@trueadm</a> in <a href=\"https://github.com/facebook/react/pull/18825\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18825</a>)</li>\n<li>Remove the <code class=\"gatsby-code-text\">timeoutMs</code> argument. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/19703\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19703</a>)</li>\n<li>Disable <code class=\"gatsby-code-text\">&lt;div hidden /&gt;</code> prerendering in favor of a different future API. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18917\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18917</a>)</li>\n<li>Add an experimental <code class=\"gatsby-code-text\">unstable_useOpaqueIdentifier</code> Hook. (<a href=\"https://github.com/lunaruan\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@lunaruan</a> in <a href=\"https://github.com/facebook/react/pull/17322\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#17322</a>)</li>\n<li>Add an experimental <code class=\"gatsby-code-text\">unstable_startTransition</code> API. (<a href=\"https://github.com/rickhanlonii\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@rickhanlonii</a> in <a href=\"https://github.com/facebook/react/pull/19696\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19696</a>)</li>\n<li>Using <code class=\"gatsby-code-text\">act</code> in the test renderer no longer flushes Suspense fallbacks. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18596\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18596</a>)</li>\n<li>Use global render timeout for CPU Suspense. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/19643\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#19643</a>)</li>\n<li>Clear the existing root content before mounting. (<a href=\"https://github.com/bvaughn\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@bvaughn</a> in <a href=\"https://github.com/facebook/react/pull/18730\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18730</a>)</li>\n<li>Fix a bug with error boundaries. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18265\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18265</a>)</li>\n<li>Fix a bug causing dropped updates in a suspended tree. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18384\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18384</a> and <a href=\"https://github.com/facebook/react/pull/18457\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18457</a>)</li>\n<li>Fix a bug causing dropped render phase updates. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18537\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18537</a>)</li>\n<li>Fix a bug in SuspenseList. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18412\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18412</a>)</li>\n<li>Fix a bug causing Suspense fallback to show too early. (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18411\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18411</a>)</li>\n<li>Fix a bug with class components inside SuspenseList. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18448\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18448</a>)</li>\n<li>Fix a bug with inputs that may cause updates to be dropped. (<a href=\"https://github.com/jddxf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@jddxf</a> in <a href=\"https://github.com/facebook/react/pull/18515\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18515</a> and <a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18535\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18535</a>)</li>\n<li>Fix a bug causing Suspense fallback to get stuck.  (<a href=\"https://github.com/acdlite\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@acdlite</a> in <a href=\"https://github.com/facebook/react/pull/18663\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18663</a>)</li>\n<li>Don’t cut off the tail of a SuspenseList if hydrating. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18854\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18854</a>)</li>\n<li>Fix a bug in <code class=\"gatsby-code-text\">useMutableSource</code> that may happen when <code class=\"gatsby-code-text\">getSnapshot</code> changes. (<a href=\"https://github.com/bvaughn\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@bvaughn</a> in <a href=\"https://github.com/facebook/react/pull/18297\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18297</a>)</li>\n<li>Fix a tearing bug in <code class=\"gatsby-code-text\">useMutableSource</code>. (<a href=\"https://github.com/bvaughn\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@bvaughn</a> in <a href=\"https://github.com/facebook/react/pull/18912\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18912</a>)</li>\n<li>Warn if calling setState outside of render but before commit. (<a href=\"https://github.com/sebmarkbage\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">@sebmarkbage</a> in <a href=\"https://github.com/facebook/react/pull/18838\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">#18838</a>)</li>\n</ul>","excerpt":"Today, we are publishing the first Release Candidate for React 17. It has been two and a half years since the previous major release of React, which is a long time even by our standards! In this blog post, we will describe the role of this major release, what changes you can expect in it, and how you can try this release. 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 making it easier to…","frontmatter":{"title":"React v17.0 Release Candidate: No New Features","next":null,"prev":null,"author":[{"frontmatter":{"name":"Dan Abramov","url":"https://twitter.com/dan_abramov"}},{"frontmatter":{"name":"Rachel Nabors","url":"https://twitter.com/rachelnabors"}}]},"fields":{"date":"August 10, 2020","path":"content/blog/2020-08-10-react-v17-rc.md","slug":"/blog/2020/08/10/react-v17-rc.html"}},"allMarkdownRemark":{"edges":[{"node":{"frontmatter":{"title":"Introducing the New JSX Transform"},"fields":{"slug":"/blog/2020/09/22/introducing-the-new-jsx-transform.html"}}},{"node":{"frontmatter":{"title":"React v17.0 Release Candidate: No New Features"},"fields":{"slug":"/blog/2020/08/10/react-v17-rc.html"}}},{"node":{"frontmatter":{"title":"React v16.13.0"},"fields":{"slug":"/blog/2020/02/26/react-v16.13.0.html"}}},{"node":{"frontmatter":{"title":"Building Great User Experiences with Concurrent Mode and Suspense"},"fields":{"slug":"/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html"}}},{"node":{"frontmatter":{"title":"Preparing for the Future with React Prereleases"},"fields":{"slug":"/blog/2019/10/22/react-release-channels.html"}}},{"node":{"frontmatter":{"title":"Introducing the New React DevTools"},"fields":{"slug":"/blog/2019/08/15/new-react-devtools.html"}}},{"node":{"frontmatter":{"title":"React v16.9.0 and the Roadmap Update"},"fields":{"slug":"/blog/2019/08/08/react-v16.9.0.html"}}},{"node":{"frontmatter":{"title":"Is React Translated Yet? ¡Sí! Sim! はい！"},"fields":{"slug":"/blog/2019/02/23/is-react-translated-yet.html"}}},{"node":{"frontmatter":{"title":"React v16.8: The One With Hooks"},"fields":{"slug":"/blog/2019/02/06/react-v16.8.0.html"}}},{"node":{"frontmatter":{"title":"React v16.7: No, This Is Not the One With Hooks"},"fields":{"slug":"/blog/2018/12/19/react-v-16-7.html"}}}]}},"pageContext":{"slug":"/blog/2020/08/10/react-v17-rc.html"}},"staticQueryHashes":[]}