<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[React]]></title><description><![CDATA[A JavaScript library for building user interfaces]]></description><link>https://reactjs.org</link><generator>GatsbyJS</generator><lastBuildDate>Fri, 16 May 2025 20:02:45 GMT</lastBuildDate><item><title><![CDATA[React v17.0 Release Candidate: No New Features]]></title><description><![CDATA[<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<p>So we wanted to provide another option.</p>
<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>
<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>
<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>
<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>
<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>
<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>
<blockquote>
<p>Note</p>
<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>
</blockquote>
<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>
<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>
<p>In React components, you usually write event handlers inline:</p>
<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>
<p>The vanilla DOM equivalent to this code is something like:</p>
<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>
<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>
<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>
<p>However, this is a problem for gradual upgrades.</p>
<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>
<p>This is why we’re changing how React attaches events to the DOM under the hood.</p>
<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>
<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>
ReactDOM<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>
<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>
<p>
  <a
    class="gatsby-resp-image-link"
    href="/static/bb4b10114882a50090b8ff61b3c4d0fd/31868/react_17_delegation.png"
    style="display: block"
    target="_blank"
    rel="noopener"
  >
  
  <span
    class="gatsby-resp-image-wrapper"
    style="position: relative; display: block;  max-width: 840px; margin-left: auto; margin-right: auto;"
  >
    <span
      class="gatsby-resp-image-background-image"
      style="padding-bottom: 77.14285714285715%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAACZklEQVQ4y12TW2/TQBCF8/+fygviFYHEL+AZCQkhFUGLQpP0kqRNE6exHV/X613v5UO2EyftSKOxd46PZ2fOjN491LR+8VDzfqH48qz5+KS654tD7tyPZ59Xmk8rxYfla9xIWs/Ra8fg0jhkG8/yJ5ynPuDf5kYczHtPYyzOGqyqUMvv+CriZH6IHc57rDFn572NWqLWGusopCJOMvarG+T8Gzp5pMk3eO9oYS3WOo/QhiTLiaK4+7Yl9wcfCNtYFgVhtCfaLEBscUZhigAr4gHTmqwqwt2OIAh6QueG3EBorUUpTV0JtklJXkR4VeC06Ai9bQZSrRvKUhDvYzLTV3jMdT20ziFUgzCOsixZZ5JdFoMue0KZ4I3quiVbMm0o64bJKmYhPLeBIBXN6wpr43guNVfLNf+eX4jjAFOGeGewVUuoO5xxjlAaZmHG118P/LyLyJXlKZJdfwfCnaj5vdox21fcppr7+ZgyD7uqrIiGWYrGMt5EXAUZ423Bj3lIkJfEwqCNY9SOzwLztGKaa2ZFwyIruF9OCKRBKomt80EWO9lws6+4Tiwz4bkMKia7jK2wqI4Qj3Lwd5swi1LuUsFdnDB/eeEuqUhFgbWmnyawzCSX64xJ2jDODH+2gllUsCoaKm36K7cVTrd7HnPJk3Qs47bZlk3taDyvJBMIxU0QEWi4Dmtuc8NKOoR5IxvZGJ5TwTzJeSxqNrWnNK7bhKNo+6F4wqJiuq+ZJpp1bYm1G6Qz6sH9SrU/yYzvXLnT+Un8x3corSdtPJX1PdlxUzrAcCX/ZjfPyc6iP+HafVZKobTGGMN/fgyCgH8QG5QAAAAASUVORK5CYII='); background-size: cover; display: block;"
    >
      <img
        class="gatsby-resp-image-image"
        style="width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;"
        alt="A diagram showing how React 17 attaches events to the roots rather than to the document"
        title=""
        src="/static/bb4b10114882a50090b8ff61b3c4d0fd/1e088/react_17_delegation.png"
        srcset="/static/bb4b10114882a50090b8ff61b3c4d0fd/65ed1/react_17_delegation.png 210w,
/static/bb4b10114882a50090b8ff61b3c4d0fd/d10fb/react_17_delegation.png 420w,
/static/bb4b10114882a50090b8ff61b3c4d0fd/1e088/react_17_delegation.png 840w,
/static/bb4b10114882a50090b8ff61b3c4d0fd/78612/react_17_delegation.png 1260w,
/static/bb4b10114882a50090b8ff61b3c4d0fd/21cdd/react_17_delegation.png 1680w,
/static/bb4b10114882a50090b8ff61b3c4d0fd/31868/react_17_delegation.png 3496w"
        sizes="(max-width: 840px) 100vw, 840px"
      />
    </span>
  </span>
  
  </a>
    </p>
<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>
<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>
<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>
<blockquote>
<p>Note</p>
<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>
</blockquote>
<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>
<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>
<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>
<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>
  <span class="token comment">// This custom handler will no longer receive clicks</span>
  <span class="token comment">// from React components that called e.stopPropagation()</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<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>
<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>
  <span class="token comment">// Now this event handler uses the capture phase,</span>
  <span class="token comment">// so it receives *all* click events below!</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">capture</span><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>
<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>
<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>
<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>
<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>
<p>We’ve made a couple of smaller changes related to the event system:</p>
<ul>
<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>
<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>
<li>Capture phase events (e.g. <code class="gatsby-code-text">onClickCapture</code>) now use real browser capture phase listeners.</li>
</ul>
<p>These changes align React closer with the browser behavior and improve interoperability.</p>
<blockquote>
<p>Note</p>
<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>
</blockquote>
<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>
<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>
<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>
  <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>
    <span class="token operator">...</span>data<span class="token punctuation">,</span>
    <span class="token comment">// This crashes in React 16 and earlier:</span>
    <span class="token literal-property property">text</span><span class="token operator">:</span> e<span class="token punctuation">.</span>target<span class="token punctuation">.</span>value
  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div>
<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>
<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>
<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>
<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>
<p>We are making the timing of the <code class="gatsby-code-text">useEffect</code> cleanup function more consistent.</p>
<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>
  <span class="token comment">// This is the effect itself.</span>
<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>
<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>
<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>
<p><strong>In React 17, the effect cleanup function always runs asynchronously — for example, if the component is unmounting, the cleanup runs <em>after</em> the screen has been updated.</strong></p>
<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>
<blockquote>
<p>Note</p>
<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>
</blockquote>
<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>
<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>
<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>
<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>
  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>
  <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>
    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>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<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>
<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>
  <span class="token keyword">const</span> instance <span class="token operator">=</span> someRef<span class="token punctuation">.</span>current<span class="token punctuation">;</span>
  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>
  <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>
    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>
  <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>We don’t expect this to be a common problem because <a href="https://github.com/facebook/react/tree/main/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>
<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>
<p>In React 16 and earlier, returning <code class="gatsby-code-text">undefined</code> has always been an error:</p>
<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>
  <span class="token keyword">return</span><span class="token punctuation">;</span> <span class="token comment">// Error: Nothing was returned from render</span>
<span class="token punctuation">}</span></code></pre></div>
<p>This is in part because it’s easy to return <code class="gatsby-code-text">undefined</code> unintentionally:</p>
<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>
  <span class="token comment">// We forgot to write return, so this component returns undefined.</span>
  <span class="token comment">// React surfaces this as an error instead of ignoring it.</span>
  <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>
<span class="token punctuation">}</span></code></pre></div>
<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>
<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>
<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>
  <span class="token comment">// We forgot to write return, so this component returns undefined.</span>
  <span class="token comment">// React 17 surfaces this as an error instead of ignoring it.</span>
  <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>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<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>
  <span class="token comment">// We forgot to write return, so this component returns undefined.</span>
  <span class="token comment">// React 17 surfaces this as an error instead of ignoring it.</span>
  <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>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>For the cases where you want to render nothing intentionally, return <code class="gatsby-code-text">null</code> instead.</p>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<p>To install React 17 RC with npm, run:</p>
<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.3 react-dom@17.0.0-rc.3</code></pre></div>
<p>To install React 17 RC with Yarn, run:</p>
<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.3 react-dom@17.0.0-rc.3</code></pre></div>
<p>We also provide UMD builds of React via a CDN:</p>
<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.3/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>
<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.3/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>
<p>Refer to the documentation for <a href="/docs/installation.html">detailed installation instructions</a>.</p>
<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>
<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>
<ul>
<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>
<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>
<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>
<li>Prevent <code class="gatsby-code-text">'use strict'</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>
<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>
</ul>
<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>
<ul>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<li>Warn when no <code class="gatsby-code-text">value</code> is provided to <code class="gatsby-code-text">&lt;Context.Provider></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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
</ul>
<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>
<ul>
<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>
<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>
</ul>
<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>
<ul>
<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>
</ul>
<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>
<ul>
<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>
<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>
<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>
<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>
<li>Disable <code class="gatsby-code-text">&lt;div hidden /></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>
<li>Add <code class="gatsby-code-text">unstable_expectedLoadTime</code> to Suspense for CPU-bound trees. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/19936" target="_blank" rel="nofollow noopener noreferrer">#19936</a>)</li>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
<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>
</ul>]]></description><link>https://reactjs.org/blog/2020/08/10/react-v17-rc.html</link><guid isPermaLink="false">https://reactjs.org/blog/2020/08/10/react-v17-rc.html</guid><pubDate>Mon, 10 Aug 2020 00:00:00 GMT</pubDate></item><item><title><![CDATA[React v16.13.0]]></title><description><![CDATA[<p>Today we are releasing React 16.13.0. It contains bugfixes and new deprecation warnings to help prepare for a future major release.</p>
<h2 id="new-warnings"><a href="#new-warnings" 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>New Warnings </h2>
<h3 id="warnings-for-some-updates-during-render"><a href="#warnings-for-some-updates-during-render" 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>Warnings for some updates during render </h3>
<p>A React component should not cause side effects in other components during rendering.</p>
<p>It is supported to call <code class="gatsby-code-text">setState</code> during render, but <a href="/docs/hooks-faq.html#how-do-i-implement-getderivedstatefromprops">only for <em>the same component</em></a>. If you call <code class="gatsby-code-text">setState</code> during a render on a different component, you will now see a warning:</p>
<div class="gatsby-highlight" data-language="text"><pre class="gatsby-code-text"><code class="gatsby-code-text">Warning: Cannot update a component from inside the function body of a different component.</code></pre></div>
<p><strong>This warning will help you find application bugs caused by unintentional state changes.</strong> In the rare case that you intentionally want to change the state of another component as a result of rendering, you can wrap the <code class="gatsby-code-text">setState</code> call into <code class="gatsby-code-text">useEffect</code>.</p>
<h3 id="warnings-for-conflicting-style-rules"><a href="#warnings-for-conflicting-style-rules" 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>Warnings for conflicting style rules </h3>
<p>When dynamically applying a <code class="gatsby-code-text">style</code> that contains longhand and shorthand versions of CSS properties, particular combinations of updates can cause inconsistent styling. For example: </p>
<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>div</span> <span class="token attr-name">style</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>toggle <span class="token operator">?</span> 
  <span class="token punctuation">{</span> <span class="token literal-property property">background</span><span class="token operator">:</span> <span class="token string">'blue'</span><span class="token punctuation">,</span> <span class="token literal-property property">backgroundColor</span><span class="token operator">:</span> <span class="token string">'red'</span> <span class="token punctuation">}</span> <span class="token operator">:</span> 
  <span class="token punctuation">{</span> <span class="token literal-property property">backgroundColor</span><span class="token operator">:</span> <span class="token string">'red'</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">
  ...
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span> </code></pre></div>
<p>You might expect this <code class="gatsby-code-text">&lt;div></code> to always have a red background, no matter the value of <code class="gatsby-code-text">toggle</code>. However, on alternating the value of <code class="gatsby-code-text">toggle</code> between <code class="gatsby-code-text">true</code> and <code class="gatsby-code-text">false</code>, the background color start as <code class="gatsby-code-text">red</code>, then alternates between <code class="gatsby-code-text">transparent</code> and <code class="gatsby-code-text">blue</code>, <a href="https://codesandbox.io/s/serene-dijkstra-dr0vev" target="_blank" rel="nofollow noopener noreferrer">as you can see in this demo</a>.</p>
<p><strong>React now detects conflicting style rules and logs a warning.</strong> To fix the issue, don’t mix shorthand and longhand versions of the same CSS property in the <code class="gatsby-code-text">style</code> prop.</p>
<h3 id="warnings-for-some-deprecated-string-refs"><a href="#warnings-for-some-deprecated-string-refs" 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>Warnings for some deprecated string refs </h3>
<p><a href="/docs/refs-and-the-dom.html#legacy-api-string-refs">String Refs is an old legacy API</a> which is discouraged and is going to be deprecated in the future:</p>
<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><span class="token class-name">Button</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>myRef<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span></code></pre></div>
<p>(Don’t confuse String Refs with refs in general, which <strong>remain fully supported</strong>.)</p>
<p>In the future, we will provide an automated script (a “codemod”) to migrate away from String Refs. However, some rare cases can’t be migrated automatically. This release adds a new warning <strong>only for those cases</strong> in advance of the deprecation.</p>
<p>For example, it will fire if you use String Refs together with the Render Prop pattern:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">ClassWithRenderProp</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>refs<span class="token punctuation">.</span>myRef<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span><span class="token function">children</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">ClassParent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</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">ClassWithRenderProp</span></span><span class="token punctuation">></span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Button</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>myRef<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ClassWithRenderProp</span></span><span class="token punctuation">></span></span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre></div>
<p>Code like this often indicates bugs. (You might expect the ref to be available on <code class="gatsby-code-text">ClassParent</code>, but instead it gets placed on <code class="gatsby-code-text">ClassWithRenderProp</code>).</p>
<p><strong>You most likely don’t have code like this</strong>. If you do and it is intentional, convert it to <a href="/docs/refs-and-the-dom.html#creating-refs"><code class="gatsby-code-text">React.createRef()</code></a> instead:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">class</span> <span class="token class-name">ClassWithRenderProp</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  myRef <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">createRef</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">componentDidMount</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">doSomething</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>myRef<span class="token punctuation">.</span>current<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>props<span class="token punctuation">.</span><span class="token function">children</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>myRef<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">ClassParent</span> <span class="token keyword">extends</span> <span class="token class-name">React<span class="token punctuation">.</span>Component</span> <span class="token punctuation">{</span>
  <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</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">ClassWithRenderProp</span></span><span class="token punctuation">></span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token parameter">myRef</span> <span class="token operator">=></span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Button</span></span> <span class="token attr-name">ref</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>myRef<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">ClassWithRenderProp</span></span><span class="token punctuation">></span></span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre></div>
<blockquote>
<p>Note</p>
<p>To see this warning, you need to have the <a href="https://babeljs.io/docs/en/babel-plugin-transform-react-jsx-self" target="_blank" rel="nofollow noopener noreferrer">babel-plugin-transform-react-jsx-self</a> installed in your Babel plugins. It must <em>only</em> be enabled in development mode. </p>
<p>If you use Create React App or have the “react” preset with Babel 7+, you already have this plugin installed by default.</p>
</blockquote>
<h3 id="deprecating-reactcreatefactory"><a href="#deprecating-reactcreatefactory" 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>Deprecating <code class="gatsby-code-text">React.createFactory</code> </h3>
<p><a href="/docs/react-api.html#createfactory"><code class="gatsby-code-text">React.createFactory</code></a> is a legacy helper for creating React elements. This release adds a deprecation warning to the method. It will be removed in a future major version.</p>
<p>Replace usages of <code class="gatsby-code-text">React.createFactory</code> with regular JSX. Alternately, you can copy and paste this one-line helper or publish it as a library:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">let</span> <span class="token function-variable function">createFactory</span> <span class="token operator">=</span> <span class="token parameter">type</span> <span class="token operator">=></span> React<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> type<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>It does exactly the same thing.</p>
<h3 id="deprecating-reactdomunstable_createportal-in-favor-of-reactdomcreateportal"><a href="#deprecating-reactdomunstable_createportal-in-favor-of-reactdomcreateportal" 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>Deprecating <code class="gatsby-code-text">ReactDOM.unstable_createPortal</code> in favor of <code class="gatsby-code-text">ReactDOM.createPortal</code> </h3>
<p>When React 16 was released, <code class="gatsby-code-text">createPortal</code> became an officially supported API.</p>
<p>However, we kept <code class="gatsby-code-text">unstable_createPortal</code> as a supported alias to keep the few libraries that adopted it working. We are now deprecating the unstable alias. Use <code class="gatsby-code-text">createPortal</code> directly instead of <code class="gatsby-code-text">unstable_createPortal</code>. It has exactly the same signature.</p>
<h2 id="other-improvements"><a href="#other-improvements" 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 Improvements </h2>
<h3 id="component-stacks-in-hydration-warnings"><a href="#component-stacks-in-hydration-warnings" 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>Component stacks in hydration warnings </h3>
<p>React adds component stacks to its development warnings, enabling developers to isolate bugs and debug their programs. This release adds component stacks to a number of development warnings that didn’t previously have them. As an example, consider this hydration warning from the previous versions:</p>
<p>
  <a
    class="gatsby-resp-image-link"
    href="/static/20bd06e254e7ad32aa007a59a41d1e65/61583/hydration-warning-before.png"
    style="display: block"
    target="_blank"
    rel="noopener"
  >
  
  <span
    class="gatsby-resp-image-wrapper"
    style="position: relative; display: block;  max-width: 840px; margin-left: auto; margin-right: auto;"
  >
    <span
      class="gatsby-resp-image-background-image"
      style="padding-bottom: 7.142857142857142%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAABCAYAAADeko4lAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAPUlEQVQI1zXHQQ6AIAxEUe5/0FIQ0YSkGBb9xhQXkzc/Lcl4KbgqLoLXGv9o4d+f7Qxt7hnMB7tuuiprDF4Tqkyb/eSbCwAAAABJRU5ErkJggg=='); background-size: cover; display: block;"
    >
      <img
        class="gatsby-resp-image-image"
        style="width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;"
        alt="A screenshot of the console warning, simply stating the nature of the hydration mismatch: "Warning: Expected server HTML to contain a matching div in div.""
        title=""
        src="/static/20bd06e254e7ad32aa007a59a41d1e65/1e088/hydration-warning-before.png"
        srcset="/static/20bd06e254e7ad32aa007a59a41d1e65/65ed1/hydration-warning-before.png 210w,
/static/20bd06e254e7ad32aa007a59a41d1e65/d10fb/hydration-warning-before.png 420w,
/static/20bd06e254e7ad32aa007a59a41d1e65/1e088/hydration-warning-before.png 840w,
/static/20bd06e254e7ad32aa007a59a41d1e65/78612/hydration-warning-before.png 1260w,
/static/20bd06e254e7ad32aa007a59a41d1e65/61583/hydration-warning-before.png 1616w"
        sizes="(max-width: 840px) 100vw, 840px"
      />
    </span>
  </span>
  
  </a>
    </p>
<p>While it’s pointing out an error with the code, it’s not clear where the error exists, and what to do next. This release adds a component stack to this warning, which makes it look like this:</p>
<p>
  <a
    class="gatsby-resp-image-link"
    href="/static/abf3b580867e79d5f377330842bb6522/d3d45/hydration-warning-after.png"
    style="display: block"
    target="_blank"
    rel="noopener"
  >
  
  <span
    class="gatsby-resp-image-wrapper"
    style="position: relative; display: block;  max-width: 840px; margin-left: auto; margin-right: auto;"
  >
    <span
      class="gatsby-resp-image-background-image"
      style="padding-bottom: 16.19047619047619%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAlUlEQVQI103OTQrCMBiE4d7/Vj1AddGdFiIoTdO0UTE/UpvvlVDQLp7FDAxM9ek1+XYjXy5Id+atFEkpSi/GkAutycNAtnbLL/8jPpCc4641y+NJJdOMtC3UNTQNqWnwhyNr10GvwYwwWrDTn7vvPMjTzDJaZHZUa0hgDHI6IdcrTGXgtq4oL2JCQtwJfz5AiBAjhMAXwerkhoKdWqMAAAAASUVORK5CYII='); background-size: cover; display: block;"
    >
      <img
        class="gatsby-resp-image-image"
        style="width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;"
        alt="A screenshot of the console warning, stating the nature of the hydration mismatch, but also including a component stack : "Warning: Expected server HTML to contain a matching div in div, in div (at pages/index.js:4)...""
        title=""
        src="/static/abf3b580867e79d5f377330842bb6522/1e088/hydration-warning-after.png"
        srcset="/static/abf3b580867e79d5f377330842bb6522/65ed1/hydration-warning-after.png 210w,
/static/abf3b580867e79d5f377330842bb6522/d10fb/hydration-warning-after.png 420w,
/static/abf3b580867e79d5f377330842bb6522/1e088/hydration-warning-after.png 840w,
/static/abf3b580867e79d5f377330842bb6522/78612/hydration-warning-after.png 1260w,
/static/abf3b580867e79d5f377330842bb6522/d3d45/hydration-warning-after.png 1614w"
        sizes="(max-width: 840px) 100vw, 840px"
      />
    </span>
  </span>
  
  </a>
    </p>
<p>This makes it clear where the problem is, and lets you locate and fix the bug faster. </p>
<h3 id="notable-bugfixes"><a href="#notable-bugfixes" 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>Notable bugfixes </h3>
<p>This release contains a few other notable improvements:</p>
<ul>
<li>In Strict Development Mode, React calls lifecycle methods twice to flush out any possible unwanted side effects. This release adds that behaviour to <code class="gatsby-code-text">shouldComponentUpdate</code>. This shouldn’t affect most code, unless you have side effects in <code class="gatsby-code-text">shouldComponentUpdate</code>. To fix this, move the code with side effects into <code class="gatsby-code-text">componentDidUpdate</code>.</li>
<li>In Strict Development Mode, the warnings for usage of the legacy context API didn’t include the stack for the component that triggered the warning. This release adds the missing stack to the warning.</li>
<li><code class="gatsby-code-text">onMouseEnter</code> now doesn’t trigger on disabled <code class="gatsby-code-text">&lt;button></code> elements.</li>
<li>ReactDOM was missing a <code class="gatsby-code-text">version</code> export since we published v16. This release adds it back. We don’t recommend using it in your application logic, but it’s useful when debugging issues with mismatching / multiple versions of ReactDOM on the same page.</li>
</ul>
<p>We’re thankful to all the contributors who helped surface and fix these and other issues. You can find the full changelog <a href="#changelog">below</a>.</p>
<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>
<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>
<p>React v16.13.0 is available on the npm registry.</p>
<p>To install React 16 with Yarn, run:</p>
<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@^16.13.0 react-dom@^16.13.0</code></pre></div>
<p>To install React 16 with npm, run:</p>
<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> --save react@^16.13.0 react-dom@^16.13.0</code></pre></div>
<p>We also provide UMD builds of React via a CDN:</p>
<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@16/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>
<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@16/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>
<p>Refer to the documentation for <a href="/docs/installation.html">detailed installation instructions</a>.</p>
<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>
<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>
<ul>
<li>Warn when a string ref is used in a manner that’s not amenable to a future codemod (<a href="https://github.com/lunaruan" target="_blank" rel="nofollow noopener noreferrer">@lunaruan</a> in <a href="https://github.com/facebook/react/pull/17864" target="_blank" rel="nofollow noopener noreferrer">#17864</a>)</li>
<li>Deprecate <code class="gatsby-code-text">React.createFactory()</code> (<a href="https://github.com/trueadm" target="_blank" rel="nofollow noopener noreferrer">@trueadm</a> in <a href="https://github.com/facebook/react/pull/17878" target="_blank" rel="nofollow noopener noreferrer">#17878</a>)</li>
</ul>
<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>
<ul>
<li>Warn when changes in <code class="gatsby-code-text">style</code> may cause an unexpected collision (<a href="https://github.com/sophiebits" target="_blank" rel="nofollow noopener noreferrer">@sophiebits</a> in <a href="https://github.com/facebook/react/pull/14181" target="_blank" rel="nofollow noopener noreferrer">#14181</a>, <a href="https://github.com/facebook/react/pull/18002" target="_blank" rel="nofollow noopener noreferrer">#18002</a>)</li>
<li>Warn when a function component is updated during another component’s render phase (<a href="(https://github.com/acdlite)">@acdlite</a> in <a href="https://github.com/facebook/react/pull/17099" target="_blank" rel="nofollow noopener noreferrer">#17099</a>)</li>
<li>Deprecate <code class="gatsby-code-text">unstable_createPortal</code> (<a href="https://github.com/trueadm" target="_blank" rel="nofollow noopener noreferrer">@trueadm</a> in <a href="https://github.com/facebook/react/pull/17880" target="_blank" rel="nofollow noopener noreferrer">#17880</a>)</li>
<li>Fix <code class="gatsby-code-text">onMouseEnter</code> being fired on disabled buttons (<a href="https://github.com/AlfredoGJ" target="_blank" rel="nofollow noopener noreferrer">@AlfredoGJ</a> in <a href="https://github.com/facebook/react/pull/17675" target="_blank" rel="nofollow noopener noreferrer">#17675</a>)</li>
<li>Call <code class="gatsby-code-text">shouldComponentUpdate</code> twice when developing in <code class="gatsby-code-text">StrictMode</code> (<a href="https://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">@bvaughn</a> in <a href="https://github.com/facebook/react/pull/17942" target="_blank" rel="nofollow noopener noreferrer">#17942</a>)</li>
<li>Add <code class="gatsby-code-text">version</code> property to ReactDOM (<a href="https://github.com/ealush" target="_blank" rel="nofollow noopener noreferrer">@ealush</a> in <a href="https://github.com/facebook/react/pull/15780" target="_blank" rel="nofollow noopener noreferrer">#15780</a>)</li>
<li>Don’t call <code class="gatsby-code-text">toString()</code> of <code class="gatsby-code-text">dangerouslySetInnerHTML</code> (<a href="https://github.com/sebmarkbage" target="_blank" rel="nofollow noopener noreferrer">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/17773" target="_blank" rel="nofollow noopener noreferrer">#17773</a>)</li>
<li>Show component stacks in more warnings (<a href="https://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/17922" target="_blank" rel="nofollow noopener noreferrer">#17922</a>, <a href="https://github.com/facebook/react/pull/17586" target="_blank" rel="nofollow noopener noreferrer">#17586</a>)</li>
</ul>
<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>
<ul>
<li>Warn for problematic usages of <code class="gatsby-code-text">ReactDOM.createRoot()</code> (<a href="https://github.com/trueadm" target="_blank" rel="nofollow noopener noreferrer">@trueadm</a> in <a href="https://github.com/facebook/react/pull/17937" target="_blank" rel="nofollow noopener noreferrer">#17937</a>)</li>
<li>Remove <code class="gatsby-code-text">ReactDOM.createRoot()</code> callback params and added warnings on usage (<a href="https://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">@bvaughn</a> in <a href="https://github.com/facebook/react/pull/17916" target="_blank" rel="nofollow noopener noreferrer">#17916</a>)</li>
<li>Don’t group Idle/Offscreen work with other work (<a href="https://github.com/sebmarkbage" target="_blank" rel="nofollow noopener noreferrer">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/17456" target="_blank" rel="nofollow noopener noreferrer">#17456</a>)</li>
<li>Adjust <code class="gatsby-code-text">SuspenseList</code> CPU bound heuristic (<a href="https://github.com/sebmarkbage" target="_blank" rel="nofollow noopener noreferrer">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/17455" target="_blank" rel="nofollow noopener noreferrer">#17455</a>)</li>
<li>Add missing event plugin priorities (<a href="https://github.com/trueadm" target="_blank" rel="nofollow noopener noreferrer">@trueadm</a> in <a href="https://github.com/facebook/react/pull/17914" target="_blank" rel="nofollow noopener noreferrer">#17914</a>)</li>
<li>Fix <code class="gatsby-code-text">isPending</code> only being true when transitioning from inside an input event (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/17382" target="_blank" rel="nofollow noopener noreferrer">#17382</a>)</li>
<li>Fix <code class="gatsby-code-text">React.memo</code> components dropping updates when interrupted by a higher priority update (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/18091" target="_blank" rel="nofollow noopener noreferrer">#18091</a>)</li>
<li>Don’t warn when suspending at the wrong priority (<a href="https://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/17971" target="_blank" rel="nofollow noopener noreferrer">#17971</a>)</li>
<li>Fix a bug with rebasing updates (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> and <a href="https://github.com/sebmarkbage" target="_blank" rel="nofollow noopener noreferrer">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/17560" target="_blank" rel="nofollow noopener noreferrer">#17560</a>, <a href="https://github.com/facebook/react/pull/17510" target="_blank" rel="nofollow noopener noreferrer">#17510</a>, <a href="https://github.com/facebook/react/pull/17483" target="_blank" rel="nofollow noopener noreferrer">#17483</a>, <a href="https://github.com/facebook/react/pull/17480" target="_blank" rel="nofollow noopener noreferrer">#17480</a>)</li>
</ul>]]></description><link>https://reactjs.org/blog/2020/02/26/react-v16.13.0.html</link><guid isPermaLink="false">https://reactjs.org/blog/2020/02/26/react-v16.13.0.html</guid><pubDate>Wed, 26 Feb 2020 00:00:00 GMT</pubDate></item><item><title><![CDATA[Building Great User Experiences with Concurrent Mode and Suspense]]></title><description><![CDATA[<p>At React Conf 2019 we announced an <a href="/docs/concurrent-mode-adoption.html#installation">experimental release</a> of React that supports Concurrent Mode and Suspense. In this post we’ll introduce best practices for using them that we’ve identified through the process of building <a href="https://twitter.com/facebook/status/1123322299418124289" target="_blank" rel="nofollow noopener noreferrer">the new facebook.com</a>.</p>
<blockquote>
<p>This post will be most relevant to people working on <em>data fetching libraries</em> for React. </p>
<p>It shows how to best integrate them with Concurrent Mode and Suspense. The patterns introduced here are based on <a href="https://relay.dev/docs/en/experimental/step-by-step" target="_blank" rel="nofollow noopener noreferrer">Relay</a> — our library for building data-driven UIs with GraphQL. However, the ideas in this post <strong>apply to other GraphQL clients as well as libraries using REST</strong> or other approaches.</p>
</blockquote>
<p>This post is <strong>aimed at library authors</strong>. If you’re primarily an application developer, you might still find some interesting ideas here, but don’t feel like you have to read it in its entirety.</p>
<h2 id="talk-videos"><a href="#talk-videos" 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>Talk Videos </h2>
<p>If you prefer to watch videos, some of the ideas from this blog post have been referenced in several React Conf 2019 presentations:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=Tl0S7QkxFE4&#x26;list=PLPxbbTqCLbGHPxZpw4xj_Wwg8-fdNxJRh&#x26;index=15&#x26;t=0s" target="_blank" rel="nofollow noopener noreferrer">Data Fetching with Suspense in Relay</a> by <a href="https://twitter.com/en_JS" target="_blank" rel="nofollow noopener noreferrer">Joe Savona</a></li>
<li><a href="https://www.youtube.com/watch?v=KT3XKDBZW7M&#x26;list=PLPxbbTqCLbGHPxZpw4xj_Wwg8-fdNxJRh&#x26;index=4" target="_blank" rel="nofollow noopener noreferrer">Building the New Facebook with React and Relay</a> by <a href="https://twitter.com/catchingash" target="_blank" rel="nofollow noopener noreferrer">Ashley Watkins</a></li>
<li><a href="https://www.youtube.com/watch?v=uXEEL9mrkAQ&#x26;list=PLPxbbTqCLbGHPxZpw4xj_Wwg8-fdNxJRh&#x26;index=2" target="_blank" rel="nofollow noopener noreferrer">React Conf Keynote</a> by <a href="https://twitter.com/yuzhiz" target="_blank" rel="nofollow noopener noreferrer">Yuzhi Zheng</a></li>
</ul>
<p>This post presents a deeper dive on implementing a data fetching library with Suspense.</p>
<h2 id="putting-user-experience-first"><a href="#putting-user-experience-first" 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>Putting User Experience First </h2>
<p>The React team and community has long placed a deserved emphasis on developer experience: ensuring that React has good error messages, focusing on components as a way to reason locally about app behavior, crafting APIs that are predictable and encourage correct usage by design, etc. But we haven’t provided enough guidance on the best ways to achieve a great <em>user</em> experience in large apps.</p>
<p>For example, the React team has focused on <em>framework</em> performance and providing tools for developers to debug and tune application performance (e.g. <code class="gatsby-code-text">React.memo</code>). But we haven’t been as opinionated about the <em>high-level patterns</em> that make the difference between fast, fluid apps and slow, janky ones. We always want to ensure that React remains approachable to new users and supports a variety of use-cases — not every app has to be “blazing” fast. But as a community we can and should aim high. <strong>We should make it as easy as possible to build apps that start fast and stay fast,</strong> even as they grow in complexity, for users on varying devices and networks around the world. </p>
<p><a href="/docs/concurrent-mode-intro.html">Concurrent Mode</a> and <a href="/docs/concurrent-mode-suspense.html">Suspense</a> are experimental features that can help developers achieve this goal. We first introduced them at <a href="/blog/2018/03/01/sneak-peek-beyond-react-16.html">JSConf Iceland in 2018</a>, intentionally sharing details very early to give the community time to digest the new concepts and to set the stage for subsequent changes. Since then we’ve completed related work, such as the new Context API and the introduction of Hooks, which are designed in part to help developers naturally write code that is more compatible with Concurrent Mode. But we didn’t want to implement these features and release them without validating that they work. So over the past year, the React, Relay, web infrastructure, and product teams at Facebook have all collaborated closely to build a new version of facebook.com that deeply integrates Concurrent Mode and Suspense to create an experience with a more fluid and app-like feel. </p>
<p>Thanks to this project, we’re more confident than ever that Concurrent Mode and Suspense can make it easier to deliver great, <em>fast</em> user experiences. But doing so requires rethinking how we approach loading code and data for our apps. Effectively all of the data-fetching on the new facebook.com is powered by <a href="https://relay.dev/docs/en/experimental/step-by-step" target="_blank" rel="nofollow noopener noreferrer">Relay Hooks</a> — new Hooks-based Relay APIs that integrate with Concurrent Mode and Suspense out of the box.</p>
<p>Relay Hooks — and GraphQL — won’t be for everyone, and that’s ok! Through our work on these APIs we’ve identified a set of more general patterns for using Suspense. <strong>Even if Relay isn’t the right fit for you, we think the key patterns we’ve introduced with Relay Hooks can be adapted to other frameworks.</strong></p>
<h2 id="best-practices-for-suspense"><a href="#best-practices-for-suspense" 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>Best Practices for Suspense </h2>
<p>It’s tempting to focus only on the total startup time for an app — but it turns out that users’ perception of performance is determined by more than the absolute loading time. For example, when comparing two apps with the same absolute startup time, our research shows that users will generally perceive the one with fewer intermediate loading states and fewer layout changes as having loaded faster. Suspense is a powerful tool for carefully orchestrating an elegant loading sequence with a few, well-defined states that progressively reveal content. But improving perceived performance only goes so far — our apps still shouldn’t take forever to fetch all of their code, data, images, and other assets.</p>
<p>The traditional approach to loading data in React apps involves what we refer to as <a href="/docs/concurrent-mode-suspense.html#approach-1-fetch-on-render-not-using-suspense">“fetch-on-render”</a>. First we render a component with a spinner, then fetch data on mount (<code class="gatsby-code-text">componentDidMount</code> or <code class="gatsby-code-text">useEffect</code>), and finally update to render the resulting data. It’s certainly <em>possible</em> to use this pattern with Suspense: instead of initially rendering a placeholder itself, a component can “suspend” — indicate to React that it isn’t ready yet. This will tell React to find the nearest ancestor <code class="gatsby-code-text">&lt;Suspense fallback={&lt;Placeholder/>}></code>, and render its fallback instead. If you watched earlier Suspense demos this example may feel familiar — it’s how we originally imagined using Suspense for data-fetching. </p>
<p>It turns out that this approach has some limitations. Consider a page that shows a social media post by a user, along with comments on that post. That might be structured as a <code class="gatsby-code-text">&lt;Post></code> component that renders both the post body and a <code class="gatsby-code-text">&lt;CommentList></code> to show the comments. Using the fetch-on-render approach described above to implement this could cause sequential round trips (sometimes referred to as a “waterfall”). First the data for the <code class="gatsby-code-text">&lt;Post></code> component would be fetched and then the data for <code class="gatsby-code-text">&lt;CommentList></code> would be fetched, increasing the time it takes to show the full page.</p>
<p>There’s also another often-overlooked downside to this approach. If <code class="gatsby-code-text">&lt;Post></code> eagerly requires (or imports) the <code class="gatsby-code-text">&lt;CommentList></code> component, our app will have to wait to show the post <em>body</em> while the code for the <em>comments</em> is downloading. We could lazily load <code class="gatsby-code-text">&lt;CommentList></code>, but then that would delay fetching comments data and increase the time to show the full page. How do we resolve this problem without compromising on the user experience?</p>
<h2 id="render-as-you-fetch"><a href="#render-as-you-fetch" 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>Render As You Fetch </h2>
<p>The fetch-on-render approach is widely used by React apps today and can certainly be used to create great apps. But can we do even better? Let’s step back and consider our goal.</p>
<p>In the above <code class="gatsby-code-text">&lt;Post></code> example, we’d ideally show the more important content — the post body — as early as possible, <em>without</em> negatively impacting the time to show the full page (including comments). Let’s consider the key constraints on any solution and look at how we can achieve them:</p>
<ul>
<li>Showing the more important content (the post body) as early as possible means that we need to load the code and data for the view incrementally. We <em>don’t want to block showing the post body</em> on the code for <code class="gatsby-code-text">&lt;CommentList></code> being downloaded, for example.</li>
<li>At the same time we don’t want to increase the time to show the full page including comments. So we need to <em>start loading the code and data for the comments</em> as soon as possible, ideally <em>in parallel</em> with loading the post body.</li>
</ul>
<p>This might sound difficult to achieve — but these constraints are actually incredibly helpful. They rule out a large number of approaches and spell out a solution for us. This brings us to the key patterns we’ve implemented in Relay Hooks, and that can be adapted to other data-fetching libraries. We’ll look at each one in turn and then see how they add up to achieve our goal of fast, delightful loading experiences:</p>
<ol>
<li>Parallel data and view trees</li>
<li>Fetch in event handlers</li>
<li>Load data incrementally</li>
<li>Treat code like data</li>
</ol>
<h3 id="parallel-data-and-view-trees"><a href="#parallel-data-and-view-trees" 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>Parallel Data and View Trees </h3>
<p>One of the most appealing things about the fetch-on-render pattern is that it colocates <em>what</em> data a component needs with <em>how</em> to render that data. This colocation is great — an example of how it makes sense to group code by concerns and not by technologies. All the issues we saw above were due to <em>when</em> we fetch data in this approach: upon rendering. We need to be able to fetch data <em>before</em> we’ve rendered the component. The only way to achieve that is by extracting the data dependencies into parallel data and view trees. </p>
<p>Here’s how that works in Relay Hooks. Continuing our example of a social media post with body and comments, here’s how we might define it with Relay Hooks:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Post.js</span>
<span class="token keyword">function</span> <span class="token function">Post</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// Given a reference to some post - `props.post` - *what* data</span>
  <span class="token comment">// do we need about that post?</span>
  <span class="token keyword">const</span> postData <span class="token operator">=</span> <span class="token function">useFragment</span><span class="token punctuation">(</span>graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
    fragment PostData on Post @refetchable(queryName: "PostQuery") {
      author
      title
      # ...  more fields ...
    }
  </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> props<span class="token punctuation">.</span>post<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// Now that we have the data, how do we render it?</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>postData<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">by </span><span class="token punctuation">{</span>postData<span class="token punctuation">.</span>author<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* more fields  */</span><span class="token punctuation">}</span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</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>
<p>Although the GraphQL is written within the component, Relay has a build step (Relay Compiler) that extracts these data-dependencies into separate files and aggregates the GraphQL for each view into a single query. So we get the benefit of colocating concerns, while at runtime having parallel data and view trees. Other frameworks could achieve a similar effect by allowing developers to define data-fetching logic in a sibling file (maybe <code class="gatsby-code-text">Post.data.js</code>), or perhaps integrate with a bundler to allow defining data dependencies with UI code and automatically extracting it, similar to Relay Compiler.</p>
<p>The key is that regardless of the technology we’re using to load our data — GraphQL, REST, etc — we can separate <em>what</em> data to load from how and when to actually load it. But once we do that, how and when <em>do</em> we fetch our data?</p>
<h3 id="fetch-in-event-handlers"><a href="#fetch-in-event-handlers" 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>Fetch in Event Handlers </h3>
<p>Imagine that we’re about to navigate from a list of a user’s posts to the page for a specific post. We’ll need to download the code for that page — <code class="gatsby-code-text">Post.js</code> — and also fetch its data.</p>
<p>Waiting until we render the component has problems as we saw above. The key is to start fetching code and data for a new view <em>in the same event handler that triggers showing that view</em>. We can either fetch the data within our router — if our router supports preloading data for routes — or in the click event on the link that triggered the navigation. It turns out that the React Router folks are already hard at work on building APIs to support preloading data for routes. But other routing frameworks can implement this idea too. </p>
<p>Conceptually, we want every route definition to include two things: what component to render and what data to preload, as a function of the route/url params. Here’s what such a route definition <em>might</em> look like. This example is loosely inspired by React Router’s route definitions and is <em>primarily intended to demonstrate the concept, not a specific API</em>:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// PostRoute.js (GraphQL version)</span>

<span class="token comment">// Relay generated query for loading Post data</span>
<span class="token keyword">import</span> PostQuery <span class="token keyword">from</span> <span class="token string">'./__generated__/PostQuery.graphql'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> PostRoute <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// a matching expression for which paths to handle</span>
  <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token string">'/post/:id'</span><span class="token punctuation">,</span>

  <span class="token comment">// what component to render for this route</span>
  <span class="token literal-property property">component</span><span class="token operator">:</span> React<span class="token punctuation">.</span><span class="token function">lazy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'./Post'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>

  <span class="token comment">// data to load for this route, as function of the route</span>
  <span class="token comment">// parameters</span>
  <span class="token function-variable function">prepare</span><span class="token operator">:</span> <span class="token parameter">routeParams</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token comment">// Relay extracts queries from components, allowing us to reference</span>
    <span class="token comment">// the data dependencies -- data tree -- from outside.</span>
    <span class="token keyword">const</span> postData <span class="token operator">=</span> <span class="token function">preloadQuery</span><span class="token punctuation">(</span>PostQuery<span class="token punctuation">,</span> <span class="token punctuation">{</span>
      <span class="token literal-property property">postId</span><span class="token operator">:</span> routeParams<span class="token punctuation">.</span>id<span class="token punctuation">,</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> <span class="token punctuation">{</span> postData <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> PostRoute<span class="token punctuation">;</span></code></pre></div>
<p>Given such a definition, a router can:</p>
<ul>
<li>Match a URL to a route definition.</li>
<li>Call the <code class="gatsby-code-text">prepare()</code> function to start loading that route’s data. Note that <code class="gatsby-code-text">prepare()</code> is synchronous — <em>we don’t wait for the data to be ready</em>, since we want to start rendering more important parts of the view (like the post body) as quickly as possible.</li>
<li>Pass the preloaded data to the component. If the component is ready — the <code class="gatsby-code-text">React.lazy</code> dynamic import has completed — the component will render and try to access its data. If not, <code class="gatsby-code-text">React.lazy</code> will suspend until the code is ready.</li>
</ul>
<p>This approach can be generalized to other data-fetching solutions. An app that uses REST might define a route like this:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// PostRoute.js (REST version)</span>

<span class="token comment">// Manually written logic for loading the data for the component</span>
<span class="token keyword">import</span> PostData <span class="token keyword">from</span> <span class="token string">'./Post.data'</span><span class="token punctuation">;</span>

<span class="token keyword">const</span> PostRoute <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token comment">// a matching expression for which paths to handle</span>
  <span class="token literal-property property">path</span><span class="token operator">:</span> <span class="token string">'/post/:id'</span><span class="token punctuation">,</span>

  <span class="token comment">// what component to render for this route</span>
  <span class="token literal-property property">component</span><span class="token operator">:</span> React<span class="token punctuation">.</span><span class="token function">lazy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'./Post'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>

  <span class="token comment">// data to load for this route, as function of the route</span>
  <span class="token comment">// parameters</span>
  <span class="token function-variable function">prepare</span><span class="token operator">:</span> <span class="token parameter">routeParams</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> postData <span class="token operator">=</span> <span class="token function">preloadRestEndpoint</span><span class="token punctuation">(</span>
      PostData<span class="token punctuation">.</span>endpointUrl<span class="token punctuation">,</span> 
      <span class="token punctuation">{</span>
        <span class="token literal-property property">postId</span><span class="token operator">:</span> routeParams<span class="token punctuation">.</span>id<span class="token punctuation">,</span>
      <span class="token punctuation">}</span><span class="token punctuation">,</span>
    <span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span> postData <span class="token punctuation">}</span><span class="token punctuation">;</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> PostRoute<span class="token punctuation">;</span></code></pre></div>
<p>This same approach can be employed not just for routing, but in other places where we show content lazily or based on user interaction. For example, a tab component could eagerly load the first tab’s code and data, and then use the same pattern as above to load the code and data for other tabs in the tab-change event handler. A component that displays a modal could preload the code and data for the modal in the click handler that triggers opening the modal, and so on. </p>
<p>Once we’ve implemented the ability to start loading code and data for a view independently, we have the option to go one step further. Consider a <code class="gatsby-code-text">&lt;Link to={path} /></code> component that links to a route. If the user hovers over that link, there’s a reasonable chance they’ll click it. And if they press the mouse down, there’s an even better chance that they’ll complete the click. If we can load code and data for a view <em>after</em> the user clicks, we can also start that work <em>before</em> they click, getting a head start on preparing the view.</p>
<p>Best of all, we can centralize that logic in a few key places — a router or core UI components — and get any performance benefits automatically throughout our app. Of course preloading isn’t always beneficial. It’s something an application would tune based on the user’s device or network speed to avoid eating up user’s data plans. But the pattern here makes it easier to centralize the implementation of preloading and the decision of whether to enable it or not.</p>
<h3 id="load-data-incrementally"><a href="#load-data-incrementally" 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>Load Data Incrementally </h3>
<p>The above patterns — parallel data/view trees and fetching in event handlers — let us start loading all the data for a view earlier. But we still want to be able to show more important parts of the view without waiting for <em>all</em> of our data. At Facebook we’ve implemented support for this in GraphQL and Relay in the form of some new GraphQL directives (annotations that affect how/when data is delivered, but not what data). These new directives, called <code class="gatsby-code-text">@defer</code> and <code class="gatsby-code-text">@stream</code>, allow us to retrieve data incrementally. For example, consider our <code class="gatsby-code-text">&lt;Post></code> component from above. We want to show the body without waiting for the comments to be ready. We can achieve this with <code class="gatsby-code-text">@defer</code> and <code class="gatsby-code-text">&lt;Suspense></code>:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Post.js</span>
<span class="token keyword">function</span> <span class="token function">Post</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">const</span> postData <span class="token operator">=</span> <span class="token function">useFragment</span><span class="token punctuation">(</span>graphql<span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
    fragment PostData on Post {
      author
      title

      # fetch data for the comments, but don't block on it being ready
      ...CommentList @defer
    }
  </span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> props<span class="token punctuation">.</span>post<span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>postData<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">by </span><span class="token punctuation">{</span>postData<span class="token punctuation">.</span>author<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>h2</span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token punctuation">{</span><span class="token comment">/* @defer pairs naturally with &lt;Suspense> to make the UI non-blocking too */</span><span class="token punctuation">}</span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Suspense</span></span> <span class="token attr-name">fallback</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</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">Spinner</span></span><span class="token punctuation">/></span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">CommentList</span></span> <span class="token attr-name">post</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>postData<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Suspense</span></span><span class="token punctuation">></span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</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>
<p>Here, our GraphQL server will stream back the results, first returning the <code class="gatsby-code-text">author</code> and <code class="gatsby-code-text">title</code> fields and then returning the comment data when it’s ready. We wrap <code class="gatsby-code-text">&lt;CommentList></code> in a <code class="gatsby-code-text">&lt;Suspense></code> boundary so that we can render the post body before <code class="gatsby-code-text">&lt;CommentList></code> and its data are ready. This same pattern can be applied to other frameworks as well. For example, apps that call a REST API might make parallel requests to fetch the body and comments data for a post to avoid blocking on all the data being ready.</p>
<h3 id="treat-code-like-data"><a href="#treat-code-like-data" 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>Treat Code Like Data </h3>
<p>But there’s one thing that’s still missing. We’ve shown how to preload <em>data</em> for a route — but what about code? The example above cheated a bit and used <code class="gatsby-code-text">React.lazy</code>. However, <code class="gatsby-code-text">React.lazy</code> is, as the name implies, <em>lazy</em>. It won’t start downloading code until the lazy component is actually rendered — it’s “fetch-on-render” for code!</p>
<p>To solve this, the React team is considering APIs that would allow bundle splitting and eager preloading for code as well. That would allow a user to pass some form of lazy component to a router, and for the router to trigger loading the code alongside its data as early as possible.</p>
<h2 id="putting-it-all-together"><a href="#putting-it-all-together" 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>Putting It All Together </h2>
<p>To recap, achieving a great loading experience means that we need to <strong>start loading code and data as early as possible, but without waiting for all of it to be ready</strong>. Parallel data and view trees allow us to load the data for a view in parallel with loading the view (code) itself. Fetching in an event handler means we can start loading data as early as possible, and even optimistically preload a view when we have enough confidence that a user will navigate to it. Loading data incrementally allows us to load important data earlier without delaying the fetching of less important data. And treating code as data — and preloading it with similar APIs — allows us to load it earlier too.</p>
<h2 id="using-these-patterns"><a href="#using-these-patterns" 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>Using These Patterns </h2>
<p>These patterns aren’t just ideas — we’ve implemented them in Relay Hooks and are using them in production throughout the new facebook.com (which is currently in beta testing). If you’re interested in using or learning more about these patterns, here are some resources:</p>
<ul>
<li>The <a href="/docs/concurrent-mode-intro.html">React Concurrent docs</a> explore how to use Concurrent Mode and Suspense and go into more detail about many of these patterns. It’s a great resource to learn more about the APIs and use-cases they support.</li>
<li>The <a href="https://relay.dev/docs/en/experimental/step-by-step" target="_blank" rel="nofollow noopener noreferrer">experimental release of Relay Hooks</a> implements the patterns described here. </li>
<li>
<p>We’ve implemented two similar example apps that demonstrate these concepts:</p>
<ul>
<li>The <a href="https://github.com/relayjs/relay-examples/tree/master/issue-tracker" target="_blank" rel="nofollow noopener noreferrer">Relay Hooks example app</a> uses GitHub’s public GraphQL API to implement a simple issue tracker app. It includes nested route support with code and data preloading. The code is fully commented — we encourage cloning the repo, running the app locally, and exploring how it works.</li>
<li>We also have a <a href="https://github.com/gaearon/suspense-experimental-github-demo" target="_blank" rel="nofollow noopener noreferrer">non-GraphQL version of the app</a> that demonstrates how these concepts can be applied to other data-fetching libraries.</li>
</ul>
</li>
</ul>
<p>While the APIs around Concurrent Mode and Suspense are <a href="/docs/concurrent-mode-adoption.html#who-is-this-experimental-release-for">still experimental</a>, we’re confident that the ideas in this post are proven by practice. However, we understand that Relay and GraphQL aren’t the right fit for everyone. That’s ok! <strong>We’re actively exploring how to generalize these patterns to approaches such as REST,</strong> and are exploring ideas for a more generic (ie non-GraphQL) API for composing a tree of data dependencies. In the meantime, we’re excited to see what new libraries will emerge that implement the patterns described in this post to make it easier to build great, <em>fast</em> user experiences.</p>]]></description><link>https://reactjs.org/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html</link><guid isPermaLink="false">https://reactjs.org/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html</guid><pubDate>Wed, 06 Nov 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[Preparing for the Future with React Prereleases]]></title><description><![CDATA[<p>To share upcoming changes with our partners in the React ecosystem, we’re establishing official prerelease channels. We hope this process will help us make changes to React with confidence, and give developers the opportunity to try out experimental features.</p>
<blockquote>
<p>This post will be most relevant to developers who work on frameworks, libraries, or developer tooling. Developers who use React primarily to build user-facing applications should not need to worry about our prerelease channels.</p>
</blockquote>
<p>React relies on a thriving open source community to file bug reports, open pull requests, and <a href="https://github.com/reactjs/rfcs" target="_blank" rel="nofollow noopener noreferrer">submit RFCs</a>. To encourage feedback, we sometimes share special builds of React that include unreleased features.</p>
<p>Because the source of truth for React is our <a href="https://github.com/facebook/react" target="_blank" rel="nofollow noopener noreferrer">public GitHub repository</a>, it’s always been possible to build a copy of React that includes the latest changes. However it’s much easier for developers to install React from npm, so we occasionally publish prerelease builds to the npm registry. A recent example is the 16.7 alpha, which included an early version of the Hooks API.</p>
<p>We would like to make it even easier for developers to test prerelease builds of React, so we’re formalizing our process with three separate release channels.</p>
<h2 id="release-channels"><a href="#release-channels" 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>Release Channels </h2>
<blockquote>
<p>The information in this post is also available on our <a href="/docs/release-channels.html">Release Channels</a> page. We will update that document whenever there are changes to our release process.</p>
</blockquote>
<p>Each of React’s release channels is designed for a distinct use case:</p>
<ul>
<li><a href="#latest-channel"><strong>Latest</strong></a> is for stable, semver React releases. It’s what you get when you install React from npm. This is the channel you’re already using today. <strong>Use this for all user-facing React applications.</strong></li>
<li><a href="#next-channel"><strong>Next</strong></a> tracks the main branch of the React source code repository. Think of these as release candidates for the next minor semver release. Use this for integration testing between React and third party projects.</li>
<li><a href="#experimental-channel"><strong>Experimental</strong></a> includes experimental APIs and features that aren’t available in the stable releases. These also track the main branch, but with additional feature flags turned on. Use this to try out upcoming features before they are released.</li>
</ul>
<p>All releases are published to npm, but only Latest uses <a href="/docs/faq-versioning.html">semantic versioning</a>. Prereleases (those in the Next and Experimental channels) have versions generated from a hash of their contents, e.g. <code class="gatsby-code-text">0.0.0-1022ee0ec</code> for Next and <code class="gatsby-code-text">0.0.0-experimental-1022ee0ec</code> for Experimental.</p>
<p><strong>The only officially supported release channel for user-facing applications is Latest</strong>. Next and Experimental releases are provided for testing purposes only, and we provide no guarantees that behavior won’t change between releases. They do not follow the semver protocol that we use for releases from Latest.</p>
<p>By publishing prereleases to the same registry that we use for stable releases, we are able to take advantage of the many tools that support the npm workflow, like <a href="https://unpkg.com" target="_blank" rel="nofollow noopener noreferrer">unpkg</a> and <a href="https://codesandbox.io" target="_blank" rel="nofollow noopener noreferrer">CodeSandbox</a>.</p>
<h3 id="latest-channel"><a href="#latest-channel" 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>Latest Channel </h3>
<p>Latest is the channel used for stable React releases. It corresponds to the <code class="gatsby-code-text">latest</code> tag on npm. It is the recommended channel for all React apps that are shipped to real users.</p>
<p><strong>If you’re not sure which channel you should use, it’s Latest.</strong> If you’re a React developer, this is what you’re already using.</p>
<p>You can expect updates to Latest to be extremely stable. Versions follow the semantic versioning scheme. Learn more about our commitment to stability and incremental migration in our <a href="/docs/faq-versioning.html">versioning policy</a>.</p>
<h3 id="next-channel"><a href="#next-channel" 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>Next Channel </h3>
<p>The Next channel is a prerelease channel that tracks the main branch of the React repository. We use prereleases in the Next channel as release candidates for the Latest channel. You can think of Next as a superset of Latest that is updated more frequently.</p>
<p>The degree of change between the most recent Next release and the most recent Latest release is approximately the same as you would find between two minor semver releases. However, <strong>the Next channel does not conform to semantic versioning.</strong> You should expect occasional breaking changes between successive releases in the Next channel.</p>
<p><strong>Do not use prereleases in user-facing applications.</strong></p>
<p>Releases in Next are published with the <code class="gatsby-code-text">next</code> tag on npm. Versions are generated from a hash of the build’s contents, e.g. <code class="gatsby-code-text">0.0.0-1022ee0ec</code>.</p>
<h4 id="using-the-next-channel-for-integration-testing"><a href="#using-the-next-channel-for-integration-testing" 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>Using the Next Channel for Integration Testing </h4>
<p>The Next channel is designed to support integration testing between React and other projects.</p>
<p>All changes to React go through extensive internal testing before they are released to the public. However, there are myriad environments and configurations used throughout the React ecosystem, and it’s not possible for us to test against every single one.</p>
<p>If you’re the author of a third party React framework, library, developer tool, or similar infrastructure-type project, you can help us keep React stable for your users and the entire React community by periodically running your test suite against the most recent changes. If you’re interested, follow these steps:</p>
<ul>
<li>Set up a cron job using your preferred continuous integration platform. Cron jobs are supported by both <a href="https://circleci.com/docs/2.0/triggers/#scheduled-builds" target="_blank" rel="nofollow noopener noreferrer">CircleCI</a> and <a href="https://docs.travis-ci.com/user/cron-jobs/" target="_blank" rel="nofollow noopener noreferrer">Travis CI</a>.</li>
<li>
<p>In the cron job, update your React packages to the most recent React release in the Next channel, using <code class="gatsby-code-text">next</code> tag on npm. Using the npm cli:</p>
<div class="gatsby-highlight" data-language="text"><pre class="gatsby-code-text"><code class="gatsby-code-text">npm update react@next react-dom@next</code></pre></div>
<p>Or yarn:</p>
<div class="gatsby-highlight" data-language="text"><pre class="gatsby-code-text"><code class="gatsby-code-text">yarn upgrade react@next react-dom@next</code></pre></div>
</li>
<li>Run your test suite against the updated packages.</li>
<li>If everything passes, great! You can expect that your project will work with the next minor React release.</li>
<li>If something breaks unexpectedly, please let us know by <a href="https://github.com/facebook/react/issues" target="_blank" rel="nofollow noopener noreferrer">filing an issue</a>.</li>
</ul>
<p>A project that uses this workflow is Next.js. (No pun intended! Seriously!) You can refer to their <a href="https://github.com/zeit/next.js/blob/c0a1c0f93966fe33edd93fb53e5fafb0dcd80a9e/.circleci/config.yml" target="_blank" rel="nofollow noopener noreferrer">CircleCI configuration</a> as an example.</p>
<h3 id="experimental-channel"><a href="#experimental-channel" 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>Experimental Channel </h3>
<p>Like Next, the Experimental channel is a prerelease channel that tracks the main branch of the React repository. Unlike Next, Experimental releases include additional features and APIs that are not ready for wider release.</p>
<p>Usually, an update to Next is accompanied by a corresponding update to Experimental. They are based on the same source revision, but are built using a different set of feature flags.</p>
<p>Experimental releases may be significantly different than releases to Next and Latest. <strong>Do not use Experimental releases in user-facing applications.</strong> You should expect frequent breaking changes between releases in the Experimental channel.</p>
<p>Releases in Experimental are published with the <code class="gatsby-code-text">experimental</code> tag on npm. Versions are generated from a hash of the build’s contents, e.g. <code class="gatsby-code-text">0.0.0-experimental-1022ee0ec</code>.</p>
<h4 id="what-goes-into-an-experimental-release"><a href="#what-goes-into-an-experimental-release" 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>What Goes Into an Experimental Release? </h4>
<p>Experimental features are ones that are not ready to be released to the wider public, and may change drastically before they are finalized. Some experiments may never be finalized — the reason we have experiments is to test the viability of proposed changes.</p>
<p>For example, if the Experimental channel had existed when we announced Hooks, we would have released Hooks to the Experimental channel weeks before they were available in Latest.</p>
<p>You may find it valuable to run integration tests against Experimental. This is up to you. However, be advised that Experimental is even less stable than Next. <strong>We do not guarantee any stability between Experimental releases.</strong></p>
<h4 id="how-can-i-learn-more-about-experimental-features"><a href="#how-can-i-learn-more-about-experimental-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>How Can I Learn More About Experimental Features? </h4>
<p>Experimental features may or may not be documented. Usually, experiments aren’t documented until they are close to shipping in Next or Stable.</p>
<p>If a feature is not documented, they may be accompanied by an <a href="https://github.com/reactjs/rfcs" target="_blank" rel="nofollow noopener noreferrer">RFC</a>.</p>
<p>We will post to the React blog when we’re ready to announce new experiments, but that doesn’t mean we will publicize every experiment.</p>
<p>You can always refer to our public GitHub repository’s <a href="https://github.com/facebook/react/commits/main" target="_blank" rel="nofollow noopener noreferrer">history</a> for a comprehensive list of changes.</p>]]></description><link>https://reactjs.org/blog/2019/10/22/react-release-channels.html</link><guid isPermaLink="false">https://reactjs.org/blog/2019/10/22/react-release-channels.html</guid><pubDate>Tue, 22 Oct 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[Introducing the New React DevTools]]></title><description><![CDATA[<p>We are excited to announce a new release of the React Developer Tools, available today in Chrome, Firefox, and (Chromium) Edge!</p>
<h2 id="whats-changed"><a href="#whats-changed" 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>What’s changed? </h2>
<p>A lot has changed in version 4!
At a high level, this new version should offer significant performance gains and an improved navigation experience.
It also offers full support for React Hooks, including inspecting nested objects.</p>
<p>
  <a
    class="gatsby-resp-image-link"
    href="/static/9552e88d7605ef4e547af89096a9225d/cd138/devtools-v4-screenshot.png"
    style="display: block"
    target="_blank"
    rel="noopener"
  >
  
  <span
    class="gatsby-resp-image-wrapper"
    style="position: relative; display: block;  max-width: 840px; margin-left: auto; margin-right: auto;"
  >
    <span
      class="gatsby-resp-image-background-image"
      style="padding-bottom: 46.19047619047619%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABo0lEQVQoz22SWW/UMBhF80cQIJQ9dhxndbZJp9POpinLCxISqnipoFLhse+IRfRPH5RMB6aUhyt/sq0j33ttyWKGn9REaYPIWsK0IdA1sujxVIUjS1xlcOKKMOvQZo6nGzxZ4ASaKDEUzSlpNSDTBsu5/ob9+Y6n1z959ukHzpc77JtfPLn6+lgfv/P88pasPSOIS5wow40yPJHjhClC11heu0Hu3pPsLlGLt1x8uGH97ooX5Rnjmdus/6rd4NVLVN7hy2KCHTQCk6LD8qsF0ckOMewQ3RazfEN5ssVOWty0fyQv7UjLgTA2EyS4B49zVg1YQWKIFy9R56+RwxY3rrD9BDdMcUL9QNNeoJG6oagXdPMVMq1xggQ70AhtsEb/olsh5xdE7RJvLOHIygNbR7PKe3IzwwkLPNVOQDllKHJCc0pYzfHTDncM2E8mCwcrxzkd1ihu0VmPLmvCaovtq33L4wXZr4gXrxCzDWK2nlZXFP+FHlo9WA7VGIXGDu5bHnOJzHwP61dE7fk0e+O3+Af053WqRhcDKje40b6U0XKcNfwGm2clmS51wfwAAAAASUVORK5CYII='); background-size: cover; display: block;"
    >
      <img
        class="gatsby-resp-image-image"
        style="width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;"
        alt="DevTools version 4 screenshot"
        title=""
        src="/static/9552e88d7605ef4e547af89096a9225d/1e088/devtools-v4-screenshot.png"
        srcset="/static/9552e88d7605ef4e547af89096a9225d/65ed1/devtools-v4-screenshot.png 210w,
/static/9552e88d7605ef4e547af89096a9225d/d10fb/devtools-v4-screenshot.png 420w,
/static/9552e88d7605ef4e547af89096a9225d/1e088/devtools-v4-screenshot.png 840w,
/static/9552e88d7605ef4e547af89096a9225d/cd138/devtools-v4-screenshot.png 1220w"
        sizes="(max-width: 840px) 100vw, 840px"
      />
    </span>
  </span>
  
  </a>
    </p>
<p><a href="https://react-devtools-tutorial.now.sh/" target="_blank" rel="nofollow noopener noreferrer">Visit the interactive tutorial</a> to try out the new version or <a href="https://github.com/facebook/react/blob/main/packages/react-devtools/CHANGELOG.md#400-august-15-2019" target="_blank" rel="nofollow noopener noreferrer">see the changelog</a> for demo videos and more details.</p>
<h2 id="which-versions-of-react-are-supported"><a href="#which-versions-of-react-are-supported" 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>Which versions of React are supported? </h2>
<p><strong><code class="gatsby-code-text">react-dom</code></strong></p>
<ul>
<li><code class="gatsby-code-text">0</code>-<code class="gatsby-code-text">14.x</code>: Not supported</li>
<li><code class="gatsby-code-text">15.x</code>: Supported (except for the new component filters feature)</li>
<li><code class="gatsby-code-text">16.x</code>: Supported</li>
</ul>
<p><strong><code class="gatsby-code-text">react-native</code></strong></p>
<ul>
<li><code class="gatsby-code-text">0</code>-<code class="gatsby-code-text">0.61.x</code>: Not supported</li>
<li><code class="gatsby-code-text">0.62</code>: Supported</li>
</ul>
<h2 id="how-do-i-get-the-new-devtools"><a href="#how-do-i-get-the-new-devtools" 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>How do I get the new DevTools? </h2>
<p>React DevTools is available as an extension for <a href="https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=en" target="_blank" rel="nofollow noopener noreferrer">Chrome</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/react-devtools/" target="_blank" rel="nofollow noopener noreferrer">Firefox</a>.
If you have already installed the extension, it should update automatically within the next couple of hours.</p>
<p>If you use the standalone shell (e.g. in React Native or Safari), you can install the new version <a href="https://www.npmjs.com/package/react-devtools" target="_blank" rel="nofollow noopener noreferrer">from NPM</a>:</p>
<div class="gatsby-highlight" data-language="shell"><pre class="gatsby-code-shell"><code class="gatsby-code-shell"><span class="token function">npm</span> <span class="token function">install</span> -g react-devtools@^4</code></pre></div>
<h2 id="where-did-all-of-the-dom-elements-go"><a href="#where-did-all-of-the-dom-elements-go" 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>Where did all of the DOM elements go? </h2>
<p>The new DevTools provides a way to filter components from the tree to make it easier to navigate deeply nested hierarchies.
Host nodes (e.g. HTML <code class="gatsby-code-text">&lt;div></code>, React Native <code class="gatsby-code-text">&lt;View></code>) are <em>hidden by default</em>, but this filter can be disabled:</p>
<p><img src="/758ea5ee734afdda4cd0f6b43c74fbb4/devtools-component-filters.gif" alt="DevTools component filters"></p>
<h2 id="how-do-i-get-the-old-version-back"><a href="#how-do-i-get-the-old-version-back" 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>How do I get the old version back? </h2>
<p>If you are working with React Native version 60 (or older) you can install the previous release of DevTools from NPM:</p>
<div class="gatsby-highlight" data-language="shell"><pre class="gatsby-code-shell"><code class="gatsby-code-shell"><span class="token function">npm</span> <span class="token function">install</span> --dev react-devtools@^3</code></pre></div>
<p>For older versions of React DOM (v0.14 or earlier) you will need to build the extension from source:</p>
<div class="gatsby-highlight" data-language="shell"><pre class="gatsby-code-shell"><code class="gatsby-code-shell"><span class="token comment"># Checkout the extension source</span>
<span class="token function">git</span> clone https://github.com/facebook/react-devtools

<span class="token builtin class-name">cd</span> react-devtools

<span class="token comment"># Checkout the previous release branch</span>
<span class="token function">git</span> checkout v3

<span class="token comment"># Install dependencies and build the unpacked extension</span>
<span class="token function">yarn</span> <span class="token function">install</span>
<span class="token function">yarn</span> build:extension

<span class="token comment"># Follow the on-screen instructions to complete installation</span></code></pre></div>
<h2 id="thank-you"><a href="#thank-you" 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>Thank you! </h2>
<p>We’d like to thank everyone who tested the early release of DevTools version 4.
Your feedback helped improve this initial release significantly.</p>
<p>We still have many exciting features planned and feedback is always welcome!
Please feel free to open a <a href="https://github.com/facebook/react/issues/new?labels=Component:%20Developer%20Tools" target="_blank" rel="nofollow noopener noreferrer">GitHub issue</a> or tag <a href="https://twitter.com/reactjs" target="_blank" rel="nofollow noopener noreferrer">@reactjs on Twitter</a>.</p>]]></description><link>https://reactjs.org/blog/2019/08/15/new-react-devtools.html</link><guid isPermaLink="false">https://reactjs.org/blog/2019/08/15/new-react-devtools.html</guid><pubDate>Thu, 15 Aug 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[React v16.9.0 and the Roadmap Update]]></title><description><![CDATA[<p>Today we are releasing React 16.9. It contains several new features, bugfixes, and new deprecation warnings to help prepare for a future major release. </p>
<h2 id="new-deprecations"><a href="#new-deprecations" 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>New Deprecations </h2>
<h3 id="renaming-unsafe-lifecycle-methods"><a href="#renaming-unsafe-lifecycle-methods" 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>Renaming Unsafe Lifecycle Methods </h3>
<p><a href="/blog/2018/03/27/update-on-async-rendering.html">Over a year ago</a>, we announced that unsafe lifecycle methods are getting renamed:</p>
<ul>
<li><code class="gatsby-code-text">componentWillMount</code> → <code class="gatsby-code-text">UNSAFE_componentWillMount</code></li>
<li><code class="gatsby-code-text">componentWillReceiveProps</code> → <code class="gatsby-code-text">UNSAFE_componentWillReceiveProps</code></li>
<li><code class="gatsby-code-text">componentWillUpdate</code> → <code class="gatsby-code-text">UNSAFE_componentWillUpdate</code></li>
</ul>
<p><strong>React 16.9 does not contain breaking changes, and the old names continue to work in this release.</strong> But you will now see a warning when using any of the old names:</p>
<p><img src="https://i.imgur.com/sngxSML.png" alt="Warning: componentWillMount has been renamed, and is not recommended for use."></p>
<p>As the warning suggests, there are usually <a href="/blog/2018/03/27/update-on-async-rendering.html#migrating-from-legacy-lifecycles">better approaches</a> for each of the unsafe methods. However, maybe you don’t have the time to migrate or test these components. In that case, we recommend running a <a href="https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb" target="_blank" rel="nofollow noopener noreferrer">“codemod”</a> script that renames them automatically:</p>
<div class="gatsby-highlight" data-language="bash"><pre class="gatsby-code-bash"><code class="gatsby-code-bash"><span class="token builtin class-name">cd</span> your_project
npx react-codemod rename-unsafe-lifecycles</code></pre></div>
<p><em>(Note that it says <code class="gatsby-code-text">npx</code>, not <code class="gatsby-code-text">npm</code>. <code class="gatsby-code-text">npx</code> is a utility that comes with Node 6+ by default.)</em></p>
<p>Running this codemod will replace the old names like <code class="gatsby-code-text">componentWillMount</code> with the new names like <code class="gatsby-code-text">UNSAFE_componentWillMount</code>:</p>
<p><img src="https://i.imgur.com/Heyvcyi.gif" alt="Codemod in action"></p>
<p>The new names like <code class="gatsby-code-text">UNSAFE_componentWillMount</code> <strong>will keep working in both React 16.9 and in React 17.x</strong>. However, the new <code class="gatsby-code-text">UNSAFE_</code> prefix will help components with problematic patterns stand out during the code review and debugging sessions. (If you’d like, you can further discourage their use inside your app with the opt-in <a href="/docs/strict-mode.html">Strict Mode</a>.)</p>
<blockquote>
<p>Note</p>
<p>Learn more about our <a href="/docs/faq-versioning.html#commitment-to-stability">versioning policy and commitment to stability</a>.</p>
</blockquote>
<h3 id="deprecating-javascript-urls"><a href="#deprecating-javascript-urls" 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>Deprecating <code class="gatsby-code-text">javascript:</code> URLs </h3>
<p>URLs starting with <code class="gatsby-code-text">javascript:</code> are a dangerous attack surface because it’s easy to accidentally include unsanitized output in a tag like <code class="gatsby-code-text">&lt;a href></code> and create a security hole:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">const</span> userProfile <span class="token operator">=</span> <span class="token punctuation">{</span>
  <span class="token literal-property property">website</span><span class="token operator">:</span> <span class="token string">"javascript: alert('you got hacked')"</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// This will now warn:</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name">href</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>userProfile<span class="token punctuation">.</span>website<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Profile</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span></code></pre></div>
<p><strong>In React 16.9,</strong> this pattern continues to work, but it will log a warning. If you use <code class="gatsby-code-text">javascript:</code> URLs for logic, try to use React event handlers instead. (As a last resort, you can circumvent the protection with <a href="/docs/dom-elements.html#dangerouslysetinnerhtml"><code class="gatsby-code-text">dangerouslySetInnerHTML</code></a>, but it is highly discouraged and often leads to security holes.)</p>
<p><strong>In a future major release,</strong> React will throw an error if it encounters a <code class="gatsby-code-text">javascript:</code> URL.</p>
<h3 id="deprecating-factory-components"><a href="#deprecating-factory-components" 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>Deprecating “Factory” Components </h3>
<p>Before compiling JavaScript classes with Babel became popular, React had support for a “factory” component that returns an object with a <code class="gatsby-code-text">render</code> method:</p>
<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">FactoryComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">{</span> <span class="token function">render</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token punctuation">/></span></span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre></div>
<p>This pattern is confusing because it looks too much like a function component — but it isn’t one. (A function component would just return the <code class="gatsby-code-text">&lt;div /></code> in the above example.)</p>
<p>This pattern was almost never used in the wild, and supporting it causes React to be slightly larger and slower than necessary. So we are deprecating this pattern in 16.9 and logging a warning if it’s encountered. If you rely on it, adding <code class="gatsby-code-text">FactoryComponent.prototype = React.Component.prototype</code> can serve as a workaround. Alternatively, you can convert it to either a class or a function component.</p>
<p>We don’t expect most codebases to be affected by this.</p>
<h2 id="new-features"><a href="#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>New Features </h2>
<h3 id="async-act-for-testing"><a href="#async-act-for-testing" 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>Async <a href="/docs/test-utils.html#act"><code class="gatsby-code-text">act()</code></a> for Testing </h3>
<p><a href="/blog/2019/02/06/react-v16.8.0.html">React 16.8</a> introduced a new testing utility called <a href="/docs/test-utils.html#act"><code class="gatsby-code-text">act()</code></a> to help you write tests that better match the browser behavior. For example, multiple state updates inside a single <code class="gatsby-code-text">act()</code> get batched. This matches how React already works when handling real browser events, and helps prepare your components for the future in which React will batch updates more often.</p>
<p>However, in 16.8 <code class="gatsby-code-text">act()</code> only supported synchronous functions. Sometimes, you might have seen a warning like this in a test but <a href="https://github.com/facebook/react/issues/14769" target="_blank" rel="nofollow noopener noreferrer">could not easily fix it</a>:</p>
<div class="gatsby-highlight" data-language="text"><pre class="gatsby-code-text"><code class="gatsby-code-text">An update to SomeComponent inside a test was not wrapped in act(...).</code></pre></div>
<p><strong>In React 16.9, <code class="gatsby-code-text">act()</code> also accepts asynchronous functions,</strong> and you can <code class="gatsby-code-text">await</code> its call:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">await</span> <span class="token function">act</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
  <span class="token comment">// ...</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>This solves the remaining cases where you couldn’t use <code class="gatsby-code-text">act()</code> before, such as when the state update was inside an asynchronous function. As a result, <strong>you should be able to fix all the remaining <code class="gatsby-code-text">act()</code> warnings in your tests now.</strong></p>
<p>We’ve heard there wasn’t enough information about how to write tests with <code class="gatsby-code-text">act()</code>. The new <a href="/docs/testing-recipes.html">Testing Recipes</a> guide describes common scenarios, and how <code class="gatsby-code-text">act()</code> can help you write good tests. These examples use vanilla DOM APIs, but you can also use <a href="https://testing-library.com/docs/react-testing-library/intro" target="_blank" rel="nofollow noopener noreferrer">React Testing Library</a> to reduce the boilerplate code. Many of its methods already use <code class="gatsby-code-text">act()</code> internally.</p>
<p>Please let us know <a href="https://github.com/facebook/react/issues" target="_blank" rel="nofollow noopener noreferrer">on the issue tracker</a> if you bump into any other scenarios where <code class="gatsby-code-text">act()</code> doesn’t work well for you, and we’ll try to help.</p>
<h3 id="performance-measurements-with-reactprofiler"><a href="#performance-measurements-with-reactprofiler" 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>Performance Measurements with <a href="/docs/profiler.html"><code class="gatsby-code-text">&lt;React.Profiler></code></a> </h3>
<p>In React 16.5, we introduced a new <a href="/blog/2018/09/10/introducing-the-react-profiler.html">React Profiler for DevTools</a> that helps find performance bottlenecks in your application. <strong>In React 16.9, we are also adding a <em>programmatic</em> way to gather measurements</strong> called <code class="gatsby-code-text">&lt;React.Profiler></code>. We expect that most smaller apps won’t use it, but it can be handy to track performance regressions over time in larger apps.</p>
<p>The <code class="gatsby-code-text">&lt;Profiler></code> measures how often a React application renders and what the “cost” of rendering is. Its purpose is to help identify parts of an application that are slow and may benefit from <a href="/docs/hooks-faq.html#how-to-memoize-calculations">optimizations such as memoization</a>.</p>
<p>A <code class="gatsby-code-text">&lt;Profiler></code> can be added anywhere in a React tree to measure the cost of rendering that part of the tree.
It requires two props: an <code class="gatsby-code-text">id</code> (string) and an <a href="/docs/profiler.html#onrender-callback"><code class="gatsby-code-text">onRender</code> callback</a> (function) which React calls any time a component within the tree “commits” an update.</p>
<div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token function">render</span><span class="token punctuation">(</span>
<span class="gatsby-highlight-code-line">  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Profiler</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>application<span class="token punctuation">"</span></span> <span class="token attr-name">onRender</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>onRenderCallback<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text"></span></span><span class="token plain-text">    </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 plain-text"></span>
<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Navigation</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token operator">...</span>props<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"></span>
<span class="token plain-text">      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Main</span></span> <span class="token spread"><span class="token punctuation">{</span><span class="token operator">...</span>props<span class="token punctuation">}</span></span> <span class="token punctuation">/></span></span><span class="token plain-text"></span>
<span class="token plain-text">    </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 plain-text"></span>
<span class="gatsby-highlight-code-line"><span class="token plain-text">  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">Profiler</span></span><span class="token punctuation">></span></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p> To learn more about the <code class="gatsby-code-text">Profiler</code> and the parameters passed to the <code class="gatsby-code-text">onRender</code> callback, check out <a href="/docs/profiler.html">the <code class="gatsby-code-text">Profiler</code> docs</a>.</p>
<blockquote>
<p>Note:</p>
<p>Profiling adds some additional overhead, so <strong>it is disabled in <a href="https://reactjs.org/docs/optimizing-performance.html#use-the-production-build" target="_blank" rel="nofollow noopener noreferrer">the production build</a></strong>.</p>
<p>To opt into production profiling, React provides a special production build with profiling enabled.
Read more about how to use this build at <a href="https://fb.me/react-profiling" target="_blank" rel="nofollow noopener noreferrer">fb.me/react-profiling</a>.</p>
</blockquote>
<h2 id="notable-bugfixes"><a href="#notable-bugfixes" 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>Notable Bugfixes </h2>
<p>This release contains a few other notable improvements:</p>
<ul>
<li>A crash when calling <code class="gatsby-code-text">findDOMNode()</code> inside a <code class="gatsby-code-text">&lt;Suspense></code> tree <a href="https://github.com/facebook/react/pull/15312" target="_blank" rel="nofollow noopener noreferrer">has been fixed</a>.</li>
<li>A memory leak caused by retaining deleted subtrees <a href="https://github.com/facebook/react/pull/16115" target="_blank" rel="nofollow noopener noreferrer">has been fixed</a> too.</li>
<li>An infinite loop caused by <code class="gatsby-code-text">setState</code> in <code class="gatsby-code-text">useEffect</code> now <a href="https://github.com/facebook/react/pull/15180" target="_blank" rel="nofollow noopener noreferrer">logs an error</a>. (This is similar to the error you see when you call <code class="gatsby-code-text">setState</code> in <code class="gatsby-code-text">componentDidUpdate</code> in a class.)</li>
</ul>
<p>We’re thankful to all the contributors who helped surface and fix these and other issues. You can find the full changelog <a href="#changelog">below</a>.</p>
<h2 id="an-update-to-the-roadmap"><a href="#an-update-to-the-roadmap" 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>An Update to the Roadmap </h2>
<p>In <a href="/blog/2018/11/27/react-16-roadmap.html">November 2018</a>, we have posted this roadmap for the 16.x releases:</p>
<ul>
<li>A minor 16.x release with React Hooks (past estimate: Q1 2019)</li>
<li>A minor 16.x release with Concurrent Mode (past estimate: Q2 2019)</li>
<li>A minor 16.x release with Suspense for Data Fetching (past estimate: mid 2019)</li>
</ul>
<p>These estimates were too optimistic, and we’ve needed to adjust them.</p>
<p><strong>tldr:</strong> We shipped Hooks on time, but we’re regrouping Concurrent Mode and Suspense for Data Fetching into a single release that we intend to release later this year.</p>
<p>In February, we <a href="/blog/2019/02/06/react-v16.8.0.html">shipped a stable 16.8 release</a> including React Hooks, with React Native support coming <a href="https://reactnative.dev/blog/2019/03/12/releasing-react-native-059" target="_blank" rel="nofollow noopener noreferrer">a month later</a>. However, we underestimated the follow-up work for this release, including the lint rules, developer tools, examples, and more documentation. This shifted the timeline by a few months.</p>
<p>Now that React Hooks are rolled out, the work on Concurrent Mode and Suspense for Data Fetching is in full swing. The <a href="https://twitter.com/facebook/status/1123322299418124289" target="_blank" rel="nofollow noopener noreferrer">new Facebook website that’s currently in active development</a> is built on top of these features. Testing them with real code helped discover and address many issues before they can affect the open source users. Some of these fixes involved an internal redesign of these features, which has also caused the timeline to slip.</p>
<p>With this new understanding, here’s what we plan to do next.</p>
<h3 id="one-release-instead-of-two"><a href="#one-release-instead-of-two" 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>One Release Instead of Two </h3>
<p>Concurrent Mode and Suspense <a href="https://developers.facebook.com/videos/2019/building-the-new-facebookcom-with-react-graphql-and-relay/" target="_blank" rel="nofollow noopener noreferrer">power the new Facebook website</a> that’s in active development, so we are confident that they’re close to a stable state technically. We also now better understand the concrete steps before they are ready for open source adoption.</p>
<p>Originally we thought we would split Concurrent Mode and Suspense for Data Fetching into two releases. We’ve found that this sequencing is confusing to explain because these features are more related than we thought at first. So we plan to release support for both Concurrent Mode and Suspense for Data Fetching in a single combined release instead.</p>
<p>We don’t want to overpromise the release date again. Given that we rely on both of them in production code, we expect to provide a 16.x release with opt-in support for them this year.</p>
<h3 id="an-update-on-data-fetching"><a href="#an-update-on-data-fetching" 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>An Update on Data Fetching </h3>
<p>While React is not opinionated about how you fetch data, the first release of Suspense for Data Fetching will likely focus on integrating with <em>opinionated data fetching libraries</em>. For example, at Facebook we are using upcoming Relay APIs that integrate with Suspense. We will document how other opinionated libraries like Apollo can support a similar integration.</p>
<p>In the first release, we <em>don’t</em> intend to focus on the ad-hoc “fire an HTTP request” solution we used in earlier demos (also known as “React Cache”). However, we expect that both we and the React community will be exploring that space in the months after the initial release.</p>
<h3 id="an-update-on-server-rendering"><a href="#an-update-on-server-rendering" 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>An Update on Server Rendering </h3>
<p>We have started the work on the <a href="/blog/2018/11/27/react-16-roadmap.html#suspense-for-server-rendering">new Suspense-capable server renderer</a>, but we <em>don’t</em> expect it to be ready for the initial release of Concurrent Mode. This release will, however, provide a temporary solution that lets the existing server renderer emit HTML for Suspense fallbacks immediately, and then render their real content on the client. This is the solution we are currently using at Facebook ourselves until the streaming renderer is ready.</p>
<h3 id="why-is-it-taking-so-long"><a href="#why-is-it-taking-so-long" 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>Why Is It Taking So Long? </h3>
<p>We’ve shipped the individual pieces leading up to Concurrent Mode as they became stable, including <a href="/blog/2018/03/29/react-v-16-3.html">new context API</a>, <a href="/blog/2018/10/23/react-v-16-6.html">lazy loading with Suspense</a>, and <a href="/blog/2019/02/06/react-v16.8.0.html">Hooks</a>. We are also eager to release the other missing parts, but <a href="/docs/design-principles.html#dogfooding">trying them at scale</a> is an important part of the process. The honest answer is that it just took more work than we expected when we started. As always, we appreciate your questions and feedback on <a href="https://twitter.com/reactjs" target="_blank" rel="nofollow noopener noreferrer">Twitter</a> and in our <a href="https://github.com/facebook/react/issues" target="_blank" rel="nofollow noopener noreferrer">issue tracker</a>.</p>
<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>
<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>
<p>React v16.9.0 is available on the npm registry.</p>
<p>To install React 16 with Yarn, run:</p>
<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@^16.9.0 react-dom@^16.9.0</code></pre></div>
<p>To install React 16 with npm, run:</p>
<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> --save react@^16.9.0 react-dom@^16.9.0</code></pre></div>
<p>We also provide UMD builds of React via a CDN:</p>
<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@16/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>
<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@16/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>
<p>Refer to the documentation for <a href="/docs/installation.html">detailed installation instructions</a>.</p>
<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>
<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>
<ul>
<li>Add <code class="gatsby-code-text">&lt;React.Profiler></code> API for gathering performance measurements programmatically. (<a href="https://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">@bvaughn</a> in <a href="https://github.com/facebook/react/pull/15172" target="_blank" rel="nofollow noopener noreferrer">#15172</a>)</li>
<li>Remove <code class="gatsby-code-text">unstable_ConcurrentMode</code> in favor of <code class="gatsby-code-text">unstable_createRoot</code>. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/15532" target="_blank" rel="nofollow noopener noreferrer">#15532</a>)</li>
</ul>
<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>
<ul>
<li>Deprecate old names for the <code class="gatsby-code-text">UNSAFE_*</code> lifecycle methods. (<a href="https://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">@bvaughn</a> in <a href="https://github.com/facebook/react/pull/15186" target="_blank" rel="nofollow noopener noreferrer">#15186</a> and <a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/16103" target="_blank" rel="nofollow noopener noreferrer">#16103</a>)</li>
<li>Deprecate <code class="gatsby-code-text">javascript:</code> URLs as a common attack surface. (<a href="https://github.com/sebmarkbage" target="_blank" rel="nofollow noopener noreferrer">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/15047" target="_blank" rel="nofollow noopener noreferrer">#15047</a>)</li>
<li>Deprecate uncommon “module pattern” (factory) components. (<a href="https://github.com/sebmarkbage" target="_blank" rel="nofollow noopener noreferrer">@sebmarkbage</a> in <a href="https://github.com/facebook/react/pull/15145" target="_blank" rel="nofollow noopener noreferrer">#15145</a>)</li>
<li>Add support for the <code class="gatsby-code-text">disablePictureInPicture</code> attribute on <code class="gatsby-code-text">&lt;video></code>. (<a href="https://github.com/eek" target="_blank" rel="nofollow noopener noreferrer">@eek</a> in <a href="https://github.com/facebook/react/pull/15334" target="_blank" rel="nofollow noopener noreferrer">#15334</a>)</li>
<li>Add support for <code class="gatsby-code-text">onLoad</code> event for <code class="gatsby-code-text">&lt;embed></code>. (<a href="https://github.com/cherniavskii" target="_blank" rel="nofollow noopener noreferrer">@cherniavskii</a> in <a href="https://github.com/facebook/react/pull/15614" target="_blank" rel="nofollow noopener noreferrer">#15614</a>)</li>
<li>Add support for editing <code class="gatsby-code-text">useState</code> state from DevTools. (<a href="https://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">@bvaughn</a> in <a href="https://github.com/facebook/react/pull/14906" target="_blank" rel="nofollow noopener noreferrer">#14906</a>)</li>
<li>Add support for toggling Suspense from DevTools. (<a href="https://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/15232" target="_blank" rel="nofollow noopener noreferrer">#15232</a>)</li>
<li>Warn when <code class="gatsby-code-text">setState</code> is called from <code class="gatsby-code-text">useEffect</code>, creating a loop. (<a href="https://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/15180" target="_blank" rel="nofollow noopener noreferrer">#15180</a>)</li>
<li>Fix a memory leak. (<a href="https://github.com/paulshen" target="_blank" rel="nofollow noopener noreferrer">@paulshen</a> in <a href="https://github.com/facebook/react/pull/16115" target="_blank" rel="nofollow noopener noreferrer">#16115</a>)</li>
<li>Fix a crash inside <code class="gatsby-code-text">findDOMNode</code> for components wrapped in <code class="gatsby-code-text">&lt;Suspense></code>. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/15312" target="_blank" rel="nofollow noopener noreferrer">#15312</a>)</li>
<li>Fix pending effects from being flushed too late. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/15650" target="_blank" rel="nofollow noopener noreferrer">#15650</a>)</li>
<li>Fix incorrect argument order in a warning message. (<a href="https://github.com/brickspert" target="_blank" rel="nofollow noopener noreferrer">@brickspert</a> in <a href="https://github.com/facebook/react/pull/15345" target="_blank" rel="nofollow noopener noreferrer">#15345</a>)</li>
<li>Fix hiding Suspense fallback nodes when there is an <code class="gatsby-code-text">!important</code> style. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/15861" target="_blank" rel="nofollow noopener noreferrer">#15861</a> and <a href="https://github.com/facebook/react/pull/15882" target="_blank" rel="nofollow noopener noreferrer">#15882</a>)</li>
<li>Slightly improve hydration performance. (<a href="https://github.com/bmeurer" target="_blank" rel="nofollow noopener noreferrer">@bmeurer</a> in <a href="https://github.com/facebook/react/pull/15998" target="_blank" rel="nofollow noopener noreferrer">#15998</a>)</li>
</ul>
<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>
<ul>
<li>Fix incorrect output for camelCase custom CSS property names. (<a href="https://github.com/bedakb" target="_blank" rel="nofollow noopener noreferrer">@bedakb</a> in <a href="https://github.com/facebook/react/pull/16167" target="_blank" rel="nofollow noopener noreferrer">#16167</a>)</li>
</ul>
<h3 id="react-test-utilities-and-test-renderer"><a href="#react-test-utilities-and-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 Utilities and Test Renderer </h3>
<ul>
<li>Add <code class="gatsby-code-text">act(async () => ...)</code> for testing asynchronous state updates. (<a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/14853" target="_blank" rel="nofollow noopener noreferrer">#14853</a>)</li>
<li>Add support for nesting <code class="gatsby-code-text">act</code> from different renderers. (<a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/16039" target="_blank" rel="nofollow noopener noreferrer">#16039</a> and <a href="https://github.com/facebook/react/pull/16042" target="_blank" rel="nofollow noopener noreferrer">#16042</a>)</li>
<li>Warn in Strict Mode if effects are scheduled outside an <code class="gatsby-code-text">act()</code> call. (<a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/15763" target="_blank" rel="nofollow noopener noreferrer">#15763</a> and <a href="https://github.com/facebook/react/pull/16041" target="_blank" rel="nofollow noopener noreferrer">#16041</a>)</li>
<li>Warn when using <code class="gatsby-code-text">act</code> from the wrong renderer. (<a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/15756" target="_blank" rel="nofollow noopener noreferrer">#15756</a>)</li>
</ul>]]></description><link>https://reactjs.org/blog/2019/08/08/react-v16.9.0.html</link><guid isPermaLink="false">https://reactjs.org/blog/2019/08/08/react-v16.9.0.html</guid><pubDate>Thu, 08 Aug 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[Is React Translated Yet? ¡Sí! Sim! はい！]]></title><description><![CDATA[<p>We’re excited to announce an ongoing effort to maintain official translations of the React documentation website into different languages. Thanks to the dedicated efforts of React community members from around the world, React is now being translated into <em>over 30</em> languages! You can find them on the new <a href="/languages">Languages</a> page.</p>
<p>In addition, the following three languages have completed translating most of the React Docs! 🎉</p>
<ul>
<li><strong>Spanish: <a href="https://es.reactjs.org" target="_blank" rel="nofollow noopener noreferrer">es.reactjs.org</a></strong></li>
<li><strong>Japanese: <a href="https://ja.reactjs.org" target="_blank" rel="nofollow noopener noreferrer">ja.reactjs.org</a></strong></li>
<li><strong>Brazilian Portuguese: <a href="https://pt-br.reactjs.org" target="_blank" rel="nofollow noopener noreferrer">pt-br.reactjs.org</a></strong></li>
</ul>
<p>Special congratulations to <a href="https://github.com/alejandronanez" target="_blank" rel="nofollow noopener noreferrer">Alejandro Ñáñez Ortiz</a>, <a href="https://github.com/carburo" target="_blank" rel="nofollow noopener noreferrer">Rainer Martínez Fraga</a>, <a href="https://github.com/dmorales" target="_blank" rel="nofollow noopener noreferrer">David Morales</a>, <a href="https://github.com/Darking360" target="_blank" rel="nofollow noopener noreferrer">Miguel Alejandro Bolivar Portilla</a>, and all the contributors to the Spanish translation for being the first to <em>completely</em> translate the core pages of the docs!</p>
<h2 id="why-localization-matters"><a href="#why-localization-matters" 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>Why Localization Matters </h2>
<p>React already has many meetups and conferences around the world, but many programmers don’t use English as their primary language. We’d love to support local communities who use React by making our documentation available in most popular languages.</p>
<p>In the past, React community members have created unofficial translations for <a href="https://github.com/discountry/react" target="_blank" rel="nofollow noopener noreferrer">Chinese</a>, <a href="https://wiki.hsoub.com/React" target="_blank" rel="nofollow noopener noreferrer">Arabic</a>, and <a href="https://github.com/reactjs/ko.reactjs.org/issues/4" target="_blank" rel="nofollow noopener noreferrer">Korean</a>; by making an official channel for these translated docs we’re hoping to make them easier to find and help make sure that non-English-speaking users of React aren’t left behind.</p>
<h2 id="contributing"><a href="#contributing" 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>Contributing </h2>
<p>If you would like to help out on a current translation, check out the <a href="/languages">Languages</a> page and click on the “Contribute” link for your language.</p>
<p>Can’t find your language? If you’d like to maintain your language’s translation fork, follow the instructions in the <a href="https://github.com/reactjs/reactjs.org-translation#starting-a-new-translation" target="_blank" rel="nofollow noopener noreferrer">translation repo</a>!</p>
<h2 id="backstory"><a href="#backstory" 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>Backstory </h2>
<p>Hi everyone! I’m <a href="https://twitter.com/tesseralis" target="_blank" rel="nofollow noopener noreferrer">Nat</a>! You may know me as the <a href="https://www.youtube.com/watch?v=Ew-UzGC8RqQ" target="_blank" rel="nofollow noopener noreferrer">polyhedra lady</a>. For the past few weeks, I’ve been helping the React team coordinate their translation effort. Here’s how I did it.</p>
<p>Our original approach for translations was to use a SaaS platform that allows users to submit translations. There was already a <a href="https://github.com/reactjs/reactjs.org/pull/873" target="_blank" rel="nofollow noopener noreferrer">pull request</a> to integrate it and my original responsibility was to finish that integration. However, we had concerns about the feasibility of that integration and the current quality of translations on the platform. Our primary concern was ensuring that translations kept up to date with the main repo and didn’t become “stale”.</p>
<p><a href="https://twitter.com/dan_abramov" target="_blank" rel="nofollow noopener noreferrer">Dan</a> encouraged me to look for alternate solutions, and we stumbled across how <a href="https://vuejs.org" target="_blank" rel="nofollow noopener noreferrer">Vue</a> maintained its translations — through different forks of the main repo on GitHub. In particular, the <a href="https://jp.vuejs.org" target="_blank" rel="nofollow noopener noreferrer">Japanese translation</a> used a bot to periodically check for changes in the English repo and submits pull requests whenever there is a change.</p>
<p>This approach appealed to us for several reasons:</p>
<ul>
<li>It was less code integration to get off the ground.</li>
<li>It encouraged active maintainers for each repo to ensure quality.</li>
<li>Contributors already understand GitHub as a platform and are motivated to contribute directly to the React organization.</li>
</ul>
<p>We started off with an initial trial period of three languages: Spanish, Japanese, and Simplified Chinese. This allowed us to work out any kinks in our process and make sure future translations are set up for success. I wanted to give the translation teams freedom to choose whatever tools they felt comfortable with. The only requirement is a <a href="https://github.com/reactjs/reactjs.org-translation/blob/master/PROGRESS.template.md" target="_blank" rel="nofollow noopener noreferrer">checklist</a> that outlines the order of importance for translating pages. </p>
<p>After the trial period, we were ready to accept more languages. I created <a href="https://github.com/reactjs/reactjs.org-translation/blob/master/scripts/create.js" target="_blank" rel="nofollow noopener noreferrer">a script</a> to automate the creation of the new language repo, and a site, <a href="https://translations.reactjs.org" target="_blank" rel="nofollow noopener noreferrer">Is React Translated Yet?</a>, to track progress on the different translations. We started <em>10</em> new translations on our first day alone!</p>
<p>Because of the automation, the rest of the maintenance went mostly smoothly. We eventually created a <a href="https://rt-slack-invite.herokuapp.com" target="_blank" rel="nofollow noopener noreferrer">Slack channel</a> to make it easier for translators to share information, and I released a guide solidifying the <a href="https://github.com/reactjs/reactjs.org-translation/blob/master/maintainer-guide.md" target="_blank" rel="nofollow noopener noreferrer">responsibilities of maintainers</a>. Allowing translators to talk with each other was a great boon — for example, the Arabic, Persian, and Hebrew translations were able to talk to each other in order to get <a href="https://en.wikipedia.org/wiki/Right-to-left" target="_blank" rel="nofollow noopener noreferrer">right-to-left text</a> working!</p>
<h2 id="the-bot"><a href="#the-bot" 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>The Bot </h2>
<p>The most challenging part was getting the bot to sync changes from the English version of the site. Initially we were using the <a href="https://github.com/vuejs-jp/che-tsumi" target="_blank" rel="nofollow noopener noreferrer">che-tsumi</a> bot created by the Japanese Vue translation team, but we soon decided to build our own bot to suit our needs. In particular, the che-tsumi bot works by <a href="https://git-scm.com/docs/git-cherry-pick" target="_blank" rel="nofollow noopener noreferrer">cherry picking</a> new commits. This ended up causing a cavalade of new issues that were interconnected, especially when <a href="/blog/2019/02/06/react-v16.8.0.html">Hooks were released</a>.</p>
<p>In the end, we decided that instead of cherry picking each commit, it made more sense to merge all new commits and create a pull request around once a day. Conflicts are merged as-is and listed in the <a href="https://github.com/reactjs/pt-BR.reactjs.org/pull/114" target="_blank" rel="nofollow noopener noreferrer">pull request</a>, leaving a checklist for maintainers to fix.</p>
<p>Creating the <a href="https://github.com/reactjs/reactjs.org-translation/blob/master/scripts/sync.js" target="_blank" rel="nofollow noopener noreferrer">sync script</a> was easy enough: it downloads the translated repo, adds the original as a remote, pulls from it, merges the conflicts, and creates a pull request.</p>
<p>The problem was finding a place for the bot to run. I’m a frontend developer for a reason — Heroku and its ilk are alien to me and <em>endlessly</em> frustrating. In fact, until this past Tuesday, I was running the script by hand on my local machine!</p>
<p>The biggest challenge was space. Each fork of the repo is around 100MB — which takes minutes to clone on my local machine. We have <em>32</em> forks, and the free tiers of most deployment platforms I checked limited you to 512MB of storage. </p>
<p>After lots of notepad calculations, I found a solution: delete each repo once we’ve finished the script and limit the concurrency of <code class="gatsby-code-text">sync</code> scripts that run at once to be within the storage requirements. Luckily, Heroku dynos have a much faster Internet connection and are able to clone even the React repo quickly.</p>
<p>There were other smaller issues that I ran into. I tried using the <a href="https://elements.heroku.com/addons/scheduler" target="_blank" rel="nofollow noopener noreferrer">Heroku Scheduler</a> add-on so I didn’t have to write any actual <code class="gatsby-code-text">watch</code> code, but it end up running too inconsistently, and I <a href="https://twitter.com/tesseralis/status/1097387938088796160" target="_blank" rel="nofollow noopener noreferrer">had an existential meltdown on Twitter</a> when I couldn’t figure out how to send commits from the Heroku dyno. But in the end, this frontend engineer was able to get the bot working!</p>
<p>There are, as always, improvements I want to make to the bot. Right now it doesn’t check whether there is an outstanding pull request before pushing another one. It’s still hard to tell the exact change that happened in the original source, and it’s possible to miss out on a needed translation change. But I trust the maintainers we’ve chosen to work through these issues, and the bot is <a href="https://github.com/reactjs/reactjs.org-translation" target="_blank" rel="nofollow noopener noreferrer">open source</a> if anyone wants to help me make these improvements!</p>
<h2 id="thanks"><a href="#thanks" 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>Thanks </h2>
<p>Finally, I would like to extend my gratitude to the following people and groups:</p>
<ul>
<li>All the translation maintainers and contributors who are helping translate React to more than thirty languages.</li>
<li>The <a href="https://github.com/vuejs-jp" target="_blank" rel="nofollow noopener noreferrer">Vue.js Japan User Group</a> for initiating the idea of having bot-managed translations, and especially <a href="https://github.com/potato4d" target="_blank" rel="nofollow noopener noreferrer">Hanatani Takuma</a> for helping us understand their approach and helping maintain the Japanese translation.</li>
<li><a href="https://github.com/smikitky" target="_blank" rel="nofollow noopener noreferrer">Soichiro Miki</a> for many <a href="https://github.com/reactjs/reactjs.org/pull/1636" target="_blank" rel="nofollow noopener noreferrer">contributions</a> and thoughtful comments on the overall translation process, as well as for maintaining the Japanese translation.</li>
<li><a href="https://github.com/ericnakagawa" target="_blank" rel="nofollow noopener noreferrer">Eric Nakagawa</a> for managing our previous translation process.</li>
<li><a href="https://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">Brian Vaughn</a> for setting up the <a href="/languages">languages page</a> and managing all the subdomains.</li>
</ul>
<p> And finally, thank you to <a href="https://twitter.com/dan_abramov" target="_blank" rel="nofollow noopener noreferrer">Dan Abramov</a> for giving me this opportunity and being a great mentor along the way.</p>]]></description><link>https://reactjs.org/blog/2019/02/23/is-react-translated-yet.html</link><guid isPermaLink="false">https://reactjs.org/blog/2019/02/23/is-react-translated-yet.html</guid><pubDate>Sat, 23 Feb 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[React v16.8: The One With Hooks]]></title><description><![CDATA[<p>With React 16.8, <a href="/docs/hooks-intro.html">React Hooks</a> are available in a stable release!</p>
<h2 id="what-are-hooks"><a href="#what-are-hooks" 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>What Are Hooks? </h2>
<p>Hooks let you use state and other React features without writing a class. You can also <strong>build your own Hooks</strong> to share reusable stateful logic between components.</p>
<p>If you’ve never heard of Hooks before, you might find these resources interesting:</p>
<ul>
<li><a href="/docs/hooks-intro.html">Introducing Hooks</a> explains why we’re adding Hooks to React.</li>
<li><a href="/docs/hooks-overview.html">Hooks at a Glance</a> is a fast-paced overview of the built-in Hooks.</li>
<li><a href="/docs/hooks-custom.html">Building Your Own Hooks</a> demonstrates code reuse with custom Hooks.</li>
<li><a href="https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889" target="_blank" rel="nofollow noopener noreferrer">Making Sense of React Hooks</a> explores the new possibilities unlocked by Hooks.</li>
<li><a href="https://usehooks.com/" target="_blank" rel="nofollow noopener noreferrer">useHooks.com</a> showcases community-maintained Hooks recipes and demos.</li>
</ul>
<p><strong>You don’t have to learn Hooks right now.</strong> Hooks have no breaking changes, and we have no plans to remove classes from React. The <a href="/docs/hooks-faq.html">Hooks FAQ</a> describes the gradual adoption strategy.</p>
<h2 id="no-big-rewrites"><a href="#no-big-rewrites" 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 Big Rewrites </h2>
<p>We don’t recommend rewriting your existing applications to use Hooks overnight. Instead, try using Hooks in some of the new components, and let us know what you think. Code using Hooks will work <a href="/docs/hooks-intro.html#gradual-adoption-strategy">side by side</a> with existing code using classes.</p>
<h2 id="can-i-use-hooks-today"><a href="#can-i-use-hooks-today" 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>Can I Use Hooks Today? </h2>
<p>Yes! Starting with 16.8.0, React includes a stable implementation of React Hooks for:</p>
<ul>
<li>React DOM</li>
<li>React DOM Server</li>
<li>React Test Renderer</li>
<li>React Shallow Renderer</li>
</ul>
<p>Note that <strong>to enable Hooks, all React packages need to be 16.8.0 or higher</strong>. Hooks won’t work if you forget to update, for example, React DOM.</p>
<p><strong>React Native will support Hooks in the <a href="https://github.com/react-native-community/react-native-releases/issues/79#issuecomment-457735214" target="_blank" rel="nofollow noopener noreferrer">0.59 release</a>.</strong></p>
<h2 id="tooling-support"><a href="#tooling-support" 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>Tooling Support </h2>
<p>React Hooks are now supported by React DevTools. They are also supported in the latest Flow and TypeScript definitions for React. We strongly recommend enabling a new <a href="https://www.npmjs.com/package/eslint-plugin-react-hooks" target="_blank" rel="nofollow noopener noreferrer">lint rule called <code class="gatsby-code-text">eslint-plugin-react-hooks</code></a> to enforce best practices with Hooks. It will soon be included into Create React App by default.</p>
<h2 id="whats-next"><a href="#whats-next" 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>What’s Next </h2>
<p>We described our plan for the next months in the recently published <a href="/blog/2018/11/27/react-16-roadmap.html">React Roadmap</a>.</p>
<p>Note that React Hooks don’t cover <em>all</em> use cases for classes yet but they’re <a href="/docs/hooks-faq.html#do-hooks-cover-all-use-cases-for-classes">very close</a>. Currently, only <code class="gatsby-code-text">getSnapshotBeforeUpdate()</code> and <code class="gatsby-code-text">componentDidCatch()</code> methods don’t have equivalent Hooks APIs, and these lifecycles are relatively uncommon. If you want, you should be able to use Hooks in most of the new code you’re writing.</p>
<p>Even while Hooks were in alpha, the React community created many interesting <a href="https://codesandbox.io/react-hooks" target="_blank" rel="nofollow noopener noreferrer">examples</a> and <a href="https://usehooks.com" target="_blank" rel="nofollow noopener noreferrer">recipes</a> using Hooks for animations, forms, subscriptions, integrating with other libraries, and so on. We’re excited about Hooks because they make code reuse easier, helping you write your components in a simpler way and make great user experiences. We can’t wait to see what you’ll create next!</p>
<h2 id="testing-hooks"><a href="#testing-hooks" 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>Testing Hooks </h2>
<p>We have added a new API called <code class="gatsby-code-text">ReactTestUtils.act()</code> in this release. It ensures that the behavior in your tests matches what happens in the browser more closely. We recommend to wrap any code rendering and triggering updates to your components into <code class="gatsby-code-text">act()</code> calls. Testing libraries can also wrap their APIs with it (for example, <a href="https://testing-library.com/react" target="_blank" rel="nofollow noopener noreferrer"><code class="gatsby-code-text">react-testing-library</code></a>’s <code class="gatsby-code-text">render</code> and <code class="gatsby-code-text">fireEvent</code> utilities do this).</p>
<p>For example, the counter example from <a href="/docs/hooks-effect.html">this page</a> can be tested like this:</p>
<div class="gatsby-highlight has-highlighted-lines" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> ReactDOM <span class="token keyword">from</span> <span class="token string">'react-dom'</span><span class="token punctuation">;</span>
<span class="gatsby-highlight-code-line"><span class="token keyword">import</span> <span class="token punctuation">{</span> act <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom/test-utils'</span><span class="token punctuation">;</span></span><span class="token keyword">import</span> Counter <span class="token keyword">from</span> <span class="token string">'./Counter'</span><span class="token punctuation">;</span>

<span class="token keyword">let</span> container<span class="token punctuation">;</span>

<span class="token function">beforeEach</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>
  container <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'div'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>container<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">afterEach</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>
  document<span class="token punctuation">.</span>body<span class="token punctuation">.</span><span class="token function">removeChild</span><span class="token punctuation">(</span>container<span class="token punctuation">)</span><span class="token punctuation">;</span>
  container <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token function">it</span><span class="token punctuation">(</span><span class="token string">'can render and update a counter'</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>
  <span class="token comment">// Test first render and effect</span>
<span class="gatsby-highlight-code-line">  <span class="token function">act</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></span><span class="gatsby-highlight-code-line">    ReactDOM<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">Counter</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">,</span> container<span class="token punctuation">)</span><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>  <span class="token keyword">const</span> button <span class="token operator">=</span> container<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">const</span> label <span class="token operator">=</span> container<span class="token punctuation">.</span><span class="token function">querySelector</span><span class="token punctuation">(</span><span class="token string">'p'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">expect</span><span class="token punctuation">(</span>label<span class="token punctuation">.</span>textContent<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">'You clicked 0 times'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">expect</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">'You clicked 0 times'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token comment">// Test second render and effect</span>
<span class="gatsby-highlight-code-line">  <span class="token function">act</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></span><span class="gatsby-highlight-code-line">    button<span class="token punctuation">.</span><span class="token function">dispatchEvent</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MouseEvent</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span><span class="token literal-property property">bubbles</span><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><span class="token punctuation">;</span></span><span class="gatsby-highlight-code-line">  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>  <span class="token function">expect</span><span class="token punctuation">(</span>label<span class="token punctuation">.</span>textContent<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">'You clicked 1 times'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">expect</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span>title<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">'You clicked 1 times'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>The calls to <code class="gatsby-code-text">act()</code> will also flush the effects inside of them.</p>
<p>If you need to test a custom Hook, you can do so by creating a component in your test, and using your Hook from it. Then you can test the component you wrote.</p>
<p>To reduce the boilerplate, we recommend using <a href="https://testing-library.com/react" target="_blank" rel="nofollow noopener noreferrer"><code class="gatsby-code-text">react-testing-library</code></a> which is designed to encourage writing tests that use your components as the end users do.</p>
<h2 id="thanks"><a href="#thanks" 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>Thanks </h2>
<p>We’d like to thank everybody who commented on the <a href="https://github.com/reactjs/rfcs/pull/68" target="_blank" rel="nofollow noopener noreferrer">Hooks RFC</a> for sharing their feedback. We’ve read all of your comments and made some adjustments to the final API based on them.</p>
<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>
<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>
<p>React v16.8.0 is available on the npm registry.</p>
<p>To install React 16 with Yarn, run:</p>
<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@^16.8.0 react-dom@^16.8.0</code></pre></div>
<p>To install React 16 with npm, run:</p>
<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> --save react@^16.8.0 react-dom@^16.8.0</code></pre></div>
<p>We also provide UMD builds of React via a CDN:</p>
<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@16/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>
<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@16/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>
<p>Refer to the documentation for <a href="/docs/installation.html">detailed installation instructions</a>.</p>
<h3 id="eslint-plugin-for-react-hooks"><a href="#eslint-plugin-for-react-hooks" 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>ESLint Plugin for React Hooks </h3>
<blockquote>
<p>Note</p>
<p>As mentioned above, we strongly recommend using the <code class="gatsby-code-text">eslint-plugin-react-hooks</code> lint rule.</p>
<p>If you’re using Create React App, instead of manually configuring ESLint you can wait for the next version of <code class="gatsby-code-text">react-scripts</code> which will come out shortly and will include this rule.</p>
</blockquote>
<p>Assuming you already have ESLint installed, run:</p>
<div class="gatsby-highlight" data-language="sh"><pre class="gatsby-code-sh"><code class="gatsby-code-sh"># npm
npm install eslint-plugin-react-hooks --save-dev

# yarn
yarn add eslint-plugin-react-hooks --dev</code></pre></div>
<p>Then add it to your ESLint configuration:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token punctuation">{</span>
  <span class="token string-property property">"plugins"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
    <span class="token comment">// ...</span>
    <span class="token string">"react-hooks"</span>
  <span class="token punctuation">]</span><span class="token punctuation">,</span>
  <span class="token string-property property">"rules"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
    <span class="token comment">// ...</span>
    <span class="token string-property property">"react-hooks/rules-of-hooks"</span><span class="token operator">:</span> <span class="token string">"error"</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre></div>
<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>
<h3 id="react-1"><a href="#react-1" 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>
<ul>
<li>Add <a href="https://reactjs.org/docs/hooks-intro.html" target="_blank" rel="nofollow noopener noreferrer">Hooks</a> — a way to use state and other React features without writing a class. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> et al. in <a href="https://github.com/facebook/react/pull/13968" target="_blank" rel="nofollow noopener noreferrer">#13968</a>)</li>
<li>Improve the <code class="gatsby-code-text">useReducer</code> Hook lazy initialization API. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14723" target="_blank" rel="nofollow noopener noreferrer">#14723</a>)</li>
</ul>
<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>
<ul>
<li>Bail out of rendering on identical values for <code class="gatsby-code-text">useState</code> and <code class="gatsby-code-text">useReducer</code> Hooks. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14569" target="_blank" rel="nofollow noopener noreferrer">#14569</a>)</li>
<li>Don’t compare the first argument passed to <code class="gatsby-code-text">useEffect</code>/<code class="gatsby-code-text">useMemo</code>/<code class="gatsby-code-text">useCallback</code> Hooks. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14594" target="_blank" rel="nofollow noopener noreferrer">#14594</a>)</li>
<li>Use <code class="gatsby-code-text">Object.is</code> algorithm for comparing <code class="gatsby-code-text">useState</code> and <code class="gatsby-code-text">useReducer</code> values. (<a href="https://github.com/Jessidhia" target="_blank" rel="nofollow noopener noreferrer">@Jessidhia</a> in <a href="https://github.com/facebook/react/pull/14752" target="_blank" rel="nofollow noopener noreferrer">#14752</a>)</li>
<li>Support synchronous thenables passed to <code class="gatsby-code-text">React.lazy()</code>. (<a href="https://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/14626" target="_blank" rel="nofollow noopener noreferrer">#14626</a>)</li>
<li>Render components with Hooks twice in Strict Mode (DEV-only) to match class behavior. (<a href="https://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/14654" target="_blank" rel="nofollow noopener noreferrer">#14654</a>)</li>
<li>Warn about mismatching Hook order in development. (<a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/14585" target="_blank" rel="nofollow noopener noreferrer">#14585</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/14591" target="_blank" rel="nofollow noopener noreferrer">#14591</a>)</li>
<li>Effect clean-up functions must return either <code class="gatsby-code-text">undefined</code> or a function. All other values, including <code class="gatsby-code-text">null</code>, are not allowed. <a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14119" target="_blank" rel="nofollow noopener noreferrer">#14119</a></li>
</ul>
<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>
<ul>
<li>Support Hooks in the shallow renderer. (<a href="https://github.com/trueadm" target="_blank" rel="nofollow noopener noreferrer">@trueadm</a> in <a href="https://github.com/facebook/react/pull/14567" target="_blank" rel="nofollow noopener noreferrer">#14567</a>)</li>
<li>Fix wrong state in <code class="gatsby-code-text">shouldComponentUpdate</code> in the presence of <code class="gatsby-code-text">getDerivedStateFromProps</code> for Shallow Renderer. (<a href="https://github.com/chenesan" target="_blank" rel="nofollow noopener noreferrer">@chenesan</a> in <a href="https://github.com/facebook/react/pull/14613" target="_blank" rel="nofollow noopener noreferrer">#14613</a>)</li>
<li>Add <code class="gatsby-code-text">ReactTestRenderer.act()</code> and <code class="gatsby-code-text">ReactTestUtils.act()</code> for batching updates so that tests more closely match real behavior. (<a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/14744" target="_blank" rel="nofollow noopener noreferrer">#14744</a>)</li>
</ul>
<h3 id="eslint-plugin-react-hooks"><a href="#eslint-plugin-react-hooks" 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>ESLint Plugin: React Hooks </h3>
<ul>
<li>Initial <a href="https://www.npmjs.com/package/eslint-plugin-react-hooks" target="_blank" rel="nofollow noopener noreferrer">release</a>. (<a href="https://github.com/calebmer" target="_blank" rel="nofollow noopener noreferrer">@calebmer</a> in <a href="https://github.com/facebook/react/pull/13968" target="_blank" rel="nofollow noopener noreferrer">#13968</a>)</li>
<li>Fix reporting after encountering a loop. (<a href="https://github.com/calebmer" target="_blank" rel="nofollow noopener noreferrer">@calebmer</a> and <a href="https://github.com/Yurickh" target="_blank" rel="nofollow noopener noreferrer">@Yurickh</a> in <a href="https://github.com/facebook/react/pull/14661" target="_blank" rel="nofollow noopener noreferrer">#14661</a>)</li>
<li>Don’t consider throwing to be a rule violation. (<a href="https://github.com/sophiebits" target="_blank" rel="nofollow noopener noreferrer">@sophiebits</a> in <a href="https://github.com/facebook/react/pull/14040" target="_blank" rel="nofollow noopener noreferrer">#14040</a>)</li>
</ul>
<h2 id="hooks-changelog-since-alpha-versions"><a href="#hooks-changelog-since-alpha-versions" 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>Hooks Changelog Since Alpha Versions </h2>
<p>The above changelog contains all notable changes since our last <strong>stable</strong> release (16.7.0). <a href="/docs/faq-versioning.html">As with all our minor releases</a>, none of the changes break backwards compatibility.</p>
<p>If you’re currently using Hooks from an alpha build of React, note that this release does contain some small breaking changes to Hooks. <strong>We don’t recommend depending on alphas in production code.</strong> We publish them so we can make changes in response to community feedback before the API is stable.</p>
<p>Here are all breaking changes to Hooks that have been made since the first alpha release:</p>
<ul>
<li>Remove <code class="gatsby-code-text">useMutationEffect</code>. (<a href="https://github.com/sophiebits" target="_blank" rel="nofollow noopener noreferrer">@sophiebits</a> in <a href="https://github.com/facebook/react/pull/14336" target="_blank" rel="nofollow noopener noreferrer">#14336</a>)</li>
<li>Rename <code class="gatsby-code-text">useImperativeMethods</code> to <code class="gatsby-code-text">useImperativeHandle</code>. (<a href="https://github.com/threepointone" target="_blank" rel="nofollow noopener noreferrer">@threepointone</a> in <a href="https://github.com/facebook/react/pull/14565" target="_blank" rel="nofollow noopener noreferrer">#14565</a>)</li>
<li>Bail out of rendering on identical values for <code class="gatsby-code-text">useState</code> and <code class="gatsby-code-text">useReducer</code> Hooks. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14569" target="_blank" rel="nofollow noopener noreferrer">#14569</a>)</li>
<li>Don’t compare the first argument passed to <code class="gatsby-code-text">useEffect</code>/<code class="gatsby-code-text">useMemo</code>/<code class="gatsby-code-text">useCallback</code> Hooks. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14594" target="_blank" rel="nofollow noopener noreferrer">#14594</a>)</li>
<li>Use <code class="gatsby-code-text">Object.is</code> algorithm for comparing <code class="gatsby-code-text">useState</code> and <code class="gatsby-code-text">useReducer</code> values. (<a href="https://github.com/Jessidhia" target="_blank" rel="nofollow noopener noreferrer">@Jessidhia</a> in <a href="https://github.com/facebook/react/pull/14752" target="_blank" rel="nofollow noopener noreferrer">#14752</a>)</li>
<li>Render components with Hooks twice in Strict Mode (DEV-only). (<a href="https://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/14654" target="_blank" rel="nofollow noopener noreferrer">#14654</a>)</li>
<li>Improve the <code class="gatsby-code-text">useReducer</code> Hook lazy initialization API. (<a href="https://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14723" target="_blank" rel="nofollow noopener noreferrer">#14723</a>)</li>
</ul>]]></description><link>https://reactjs.org/blog/2019/02/06/react-v16.8.0.html</link><guid isPermaLink="false">https://reactjs.org/blog/2019/02/06/react-v16.8.0.html</guid><pubDate>Wed, 06 Feb 2019 00:00:00 GMT</pubDate></item><item><title><![CDATA[React v16.7: No, This Is Not the One With Hooks]]></title><description><![CDATA[<p>Our latest release includes an important performance bugfix for <code class="gatsby-code-text">React.lazy</code>. Although there are no API changes, we’re releasing it as a minor instead of a patch.</p>
<h2 id="why-is-this-bugfix-a-minor-instead-of-a-patch"><a href="#why-is-this-bugfix-a-minor-instead-of-a-patch" 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>Why Is This Bugfix a Minor Instead of a Patch? </h2>
<p>React follows <a href="/docs/faq-versioning.html">semantic versioning</a>. Typically, this means that we use patch versions for bugfixes, and minors for new (non-breaking) features. However, we reserve the option to release minor versions even if they do not include new features. The motivation is to reserve patches for changes that have a very low chance of breaking. Patches are the most important type of release because they sometimes contain critical bugfixes. That means patch releases have a higher bar for reliability. It’s unacceptable for a patch to introduce additional bugs, because if people come to distrust patches, it compromises our ability to fix critical bugs when they arise — for example, to fix a security vulnerability.</p>
<p>We never intend to ship bugs. React has a hard-earned reputation for stability, and we intend to keep it that way. We thoroughly test every version of React before releasing. This includes unit tests, generative (fuzzy) tests, integration tests, and internal dogfooding across tens of thousands of components. However, sometimes we make mistakes. That’s why, going forward, our policy will be that if a release contains non-trivial changes, we will bump the minor version, even if the external behavior is the same. We’ll also bump the minor when changing <code class="gatsby-code-text">unstable_</code>-prefixed APIs.</p>
<h2 id="can-i-use-hooks-yet"><a href="#can-i-use-hooks-yet" 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>Can I Use Hooks Yet? </h2>
<p>Not yet, but soon!</p>
<p>At React Conf, we said that 16.7 would be the first release to include Hooks. This was a mistake. We shouldn’t have attached a specific version number to an unreleased feature. We’ll avoid this in the future.</p>
<p>Although 16.7 does not include Hooks, please do not infer anything about the timeline of the Hooks launch. Our plans for Hooks are unchanged:</p>
<ul>
<li>The <a href="https://github.com/reactjs/rfcs/pull/68" target="_blank" rel="nofollow noopener noreferrer">Hooks proposal</a> was accepted (<a href="https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884" target="_blank" rel="nofollow noopener noreferrer">with minor planned changes in response to feedback</a>).</li>
<li>The <a href="https://github.com/facebook/react/commit/7bee9fbdd49aa5b9365a94b0ddf6db04bc1bf51c" target="_blank" rel="nofollow noopener noreferrer">implementation</a> was merged into the React repo (behind a feature flag).</li>
<li>We’re currently in the testing phase, and you can expect a public release within a few months.</li>
</ul>
<p>We’ve heard from many people who want to start using Hooks in their apps. We also can’t wait to ship them! But because Hooks changes how we write React components, we are taking extra time to get the details right. We appreciate your patience as we prepare this exciting new feature for widespread, ahem, <em>use</em>.</p>
<p>Learn more about <a href="/blog/2018/11/27/react-16-roadmap.html">our roadmap</a> in our previous post.</p>
<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>
<p>React v16.7.0 is available on the npm registry.</p>
<p>To install React 16 with Yarn, run:</p>
<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@^16.7.0 react-dom@^16.7.0</code></pre></div>
<p>To install React 16 with npm, run:</p>
<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> --save react@^16.7.0 react-dom@^16.7.0</code></pre></div>
<p>We also provide UMD builds of React via a CDN:</p>
<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@16/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>
<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@16/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>
<p>Refer to the documentation for <a href="/docs/installation.html">detailed installation instructions</a>.</p>
<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>
<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>
<ul>
<li>Fix performance of <code class="gatsby-code-text">React.lazy</code> for large numbers of lazily-loaded components. (<a href="http://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14429" target="_blank" rel="nofollow noopener noreferrer">#14429</a>)</li>
<li>Clear fields on unmount to avoid memory leaks. (<a href="http://github.com/trueadm" target="_blank" rel="nofollow noopener noreferrer">@trueadm</a> in <a href="https://github.com/facebook/react/pull/14276" target="_blank" rel="nofollow noopener noreferrer">#14276</a>)</li>
<li>Fix bug with SSR and context when mixing <code class="gatsby-code-text">react-dom/server@16.6</code> and <code class="gatsby-code-text">react@&lt;16.6</code>. (<a href="http://github.com/gaearon" target="_blank" rel="nofollow noopener noreferrer">@gaearon</a> in <a href="https://github.com/facebook/react/pull/14291" target="_blank" rel="nofollow noopener noreferrer">#14291</a>)</li>
<li>Fix a performance regression in profiling mode. (<a href="http://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">@bvaughn</a> in <a href="https://github.com/facebook/react/pull/14383" target="_blank" rel="nofollow noopener noreferrer">#14383</a>)</li>
</ul>
<h3 id="scheduler-experimental"><a href="#scheduler-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>Scheduler (Experimental) </h3>
<ul>
<li>Post to MessageChannel instead of window. (<a href="http://github.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">@acdlite</a> in <a href="https://github.com/facebook/react/pull/14234" target="_blank" rel="nofollow noopener noreferrer">#14234</a>)</li>
<li>Reduce serialization overhead. (<a href="http://github.com/developit" target="_blank" rel="nofollow noopener noreferrer">@developit</a> in <a href="https://github.com/facebook/react/pull/14249" target="_blank" rel="nofollow noopener noreferrer">#14249</a>)</li>
<li>Fix fallback to <code class="gatsby-code-text">setTimeout</code> in testing environments. (<a href="http://github.com/bvaughn" target="_blank" rel="nofollow noopener noreferrer">@bvaughn</a> in <a href="https://github.com/facebook/react/pull/14358" target="_blank" rel="nofollow noopener noreferrer">#14358</a>)</li>
<li>Add methods for debugging. (<a href="http://github.com/mrkev" target="_blank" rel="nofollow noopener noreferrer">@mrkev</a> in <a href="https://github.com/facebook/react/pull/14053" target="_blank" rel="nofollow noopener noreferrer">#14053</a>)</li>
</ul>]]></description><link>https://reactjs.org/blog/2018/12/19/react-v-16-7.html</link><guid isPermaLink="false">https://reactjs.org/blog/2018/12/19/react-v-16-7.html</guid><pubDate>Wed, 19 Dec 2018 00:00:00 GMT</pubDate></item><item><title><![CDATA[React 16.x Roadmap]]></title><description><![CDATA[<p>You might have heard about features like “Hooks”, “Suspense”, and “Concurrent Rendering” in the previous blog posts and talks. In this post, we’ll look at how they fit together and the expected timeline for their availability in a stable release of React.</p>
<blockquote>
<p>An Update from August, 2019</p>
<p>You can find an update to this roadmap in the <a href="/blog/2019/08/08/react-v16.9.0.html#an-update-to-the-roadmap">React 16.9 release blog post</a>.</p>
</blockquote>
<h2 id="tldr"><a href="#tldr" 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>tl;dr </h2>
<p>We plan to split the rollout of new React features into the following milestones:</p>
<ul>
<li>React 16.6 with <a href="#react-166-shipped-the-one-with-suspense-for-code-splitting">Suspense for Code Splitting</a> (<em>already shipped</em>)</li>
<li>A minor 16.x release with <a href="#react-16x-q1-2019-the-one-with-hooks">React Hooks</a> (~Q1 2019)</li>
<li>A minor 16.x release with <a href="#react-16x-q2-2019-the-one-with-concurrent-mode">Concurrent Mode</a> (~Q2 2019)</li>
<li>A minor 16.x release with <a href="#react-16x-mid-2019-the-one-with-suspense-for-data-fetching">Suspense for Data Fetching</a> (~mid 2019)</li>
</ul>
<p><em>(The original version of this post used exact version numbers. We edited it to reflect that there might need to be a few other minor releases in the middle between these ones.)</em></p>
<p>These are estimates, and the details may change as we’re further along. There’s at least two more projects we plan to complete in 2019. They require more exploration and aren’t tied to a particular release yet:</p>
<ul>
<li><a href="#modernizing-react-dom">Modernizing React DOM</a></li>
<li><a href="#suspense-for-server-rendering">Suspense for Server Rendering</a></li>
</ul>
<p>We expect to get more clarity on their timeline in the coming months.</p>
<blockquote>
<p>Note</p>
<p>This post is just a roadmap — there is nothing in it that requires your immediate attention. When each of these features are released, we’ll publish a full blog post announcing them.</p>
</blockquote>
<h2 id="release-timeline"><a href="#release-timeline" 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>Release Timeline </h2>
<p>We have a single vision for how all of these features fit together, but we’re releasing each part as soon as it is ready so that you can test and start using them sooner. The API design doesn’t always make sense when looking at one piece in isolation; this post lays out the major parts of our plan to help you see the whole picture. (See our <a href="/docs/faq-versioning.html">versioning policy</a> to learn more about our commitment to stability.)</p>
<p>The gradual release strategy helps us refine the APIs, but the transitional period when some things aren’t ready can be confusing. Let’s look at what these different features mean for your app, how they relate to each other, and when you can expect to start learning and using them.</p>
<h3 id="react-166-shipped-the-one-with-suspense-for-code-splitting"><a href="#react-166-shipped-the-one-with-suspense-for-code-splitting" 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><a href="/blog/2018/10/23/react-v-16-6.html">React 16.6</a> (shipped): The One with Suspense for Code Splitting </h3>
<p><em>Suspense</em> refers to React’s new ability to “suspend” rendering while components are waiting for something, and display a loading indicator. In React 16.6, Suspense supports only one use case: lazy loading components with <code class="gatsby-code-text">React.lazy()</code> and <code class="gatsby-code-text">&lt;React.Suspense></code>.</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// This component is loaded dynamically</span>
<span class="token keyword">const</span> OtherComponent <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">lazy</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">import</span><span class="token punctuation">(</span><span class="token string">'./OtherComponent'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">MyComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</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">React.Suspense</span></span> <span class="token attr-name">fallback</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</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">Spinner</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">OtherComponent</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">React.Suspense</span></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>
<p>Code splitting with <code class="gatsby-code-text">React.lazy()</code> with <code class="gatsby-code-text">&lt;React.Suspense></code> is documented <a href="/docs/code-splitting.html#reactlazy">in the Code Splitting guide</a>. You can find another practical explanation in <a href="https://medium.com/@pomber/lazy-loading-and-preloading-components-in-react-16-6-804de091c82d" target="_blank" rel="nofollow noopener noreferrer">this article</a>.</p>
<p>We have been using Suspense for code splitting at Facebook since July, and expect it to be stable. There’s been a few regressions in the initial public release in 16.6.0, but they were fixed in 16.6.3.</p>
<p>Code splitting is just the first step for Suspense. Our longer term vision for Suspense involves letting it handle data fetching too (and integrate with libraries like Apollo). In addition to a convenient programming model, Suspense also provides better user experience in Concurrent Mode. You’ll find information about these topics further below.</p>
<p><strong>Status in React DOM:</strong> Available since React 16.6.0.</p>
<p><strong>Status in React DOM Server:</strong> Suspense is not available in the server renderer yet. This isn’t for the lack of attention. We’ve started work on a new asynchronous server renderer that will support Suspense, but it’s a large project and will take a good chunk of 2019 to complete.</p>
<p><strong>Status in React Native:</strong> Bundle splitting isn’t very useful in React Native, but there’s nothing technically preventing <code class="gatsby-code-text">React.lazy()</code> and <code class="gatsby-code-text">&lt;Suspense></code> from working when given a Promise to a module.</p>
<p><strong>Recommendation:</strong> If you only do client rendering, we recommend widely adopting <code class="gatsby-code-text">React.lazy()</code> and <code class="gatsby-code-text">&lt;React.Suspense></code> for code splitting React components. If you do server rendering, you’ll have to wait with adoption until the new server renderer is ready.</p>
<h3 id="react-16x-q1-2019-the-one-with-hooks"><a href="#react-16x-q1-2019-the-one-with-hooks" 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 16.x (~Q1 2019): The One with Hooks </h3>
<p><em>Hooks</em> let you use features like state and lifecycle from function components. They also let you reuse stateful logic between components without introducing extra nesting in your tree.</p>
<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">Example</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// Declare a new state variable, which we'll call "count"</span>
  <span class="token keyword">const</span> <span class="token punctuation">[</span>count<span class="token punctuation">,</span> setCount<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

  <span class="token keyword">return</span> <span class="token punctuation">(</span>
   <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">></span></span><span class="token plain-text">
     </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">You clicked </span><span class="token punctuation">{</span>count<span class="token punctuation">}</span><span class="token plain-text"> times</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">></span></span><span class="token plain-text">
     </span><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><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">setCount</span><span class="token punctuation">(</span>count <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">
       Click me
     </span><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 plain-text">
   </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</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>
<p>Hooks <a href="/docs/hooks-intro.html">introduction</a> and <a href="/docs/hooks-overview.html">overview</a> are good places to start. Watch <a href="https://www.youtube.com/watch?v=V-QO-KO90iQ" target="_blank" rel="nofollow noopener noreferrer">these talks</a> for a video introduction and a deep dive. The <a href="/docs/hooks-faq.html">FAQ</a> should answer most of your further questions. To learn more about the motivation behind Hooks, you can read <a href="https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889" target="_blank" rel="nofollow noopener noreferrer">this article</a>. Some of the rationale for the API design of Hooks is explained in <a href="https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884" target="_blank" rel="nofollow noopener noreferrer">this RFC thread reply</a>.</p>
<p>We have been dogfooding Hooks at Facebook since September. We don’t expect major bugs in the implementation. Hooks are only available in the 16.7 alpha versions of React. Some of their API is expected to change in the final version (see the end of <a href="https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884" target="_blank" rel="nofollow noopener noreferrer">this comment</a> for details). It is possible that the minor release with Hooks might not be React 16.7.</p>
<p>Hooks represent our vision for the future of React. They solve both problems that React users experience directly (“wrapper hell” of render props and higher-order components, duplication of logic in lifecycle methods), and the issues we’ve encountered optimizing React at scale (such as difficulties in inlining components with a compiler). Hooks don’t deprecate classes. However, if Hooks are successful, it is possible that in a future <em>major</em> release class support might move to a separate package, reducing the default bundle size of React.</p>
<p><strong>Status in React DOM:</strong> The first version of <code class="gatsby-code-text">react</code> and <code class="gatsby-code-text">react-dom</code> supporting Hooks is <code class="gatsby-code-text">16.7.0-alpha.0</code>. We expect to publish more alphas over the next months (at the time of writing, the latest one is <code class="gatsby-code-text">16.7.0-alpha.2</code>). You can try them by installing <code class="gatsby-code-text">react@next</code> with <code class="gatsby-code-text">react-dom@next</code>. Don’t forget to update <code class="gatsby-code-text">react-dom</code> — otherwise Hooks won’t work.</p>
<p><strong>Status in React DOM Server:</strong> The same 16.7 alpha versions of <code class="gatsby-code-text">react-dom</code> fully support Hooks with <code class="gatsby-code-text">react-dom/server</code>.</p>
<p><strong>Status in React Native:</strong> There is no officially supported way to try Hooks in React Native yet. If you’re feeling adventurous, check out <a href="https://github.com/facebook/react-native/issues/21967" target="_blank" rel="nofollow noopener noreferrer">this thread</a> for unofficial instructions. There is a known issue with <code class="gatsby-code-text">useEffect</code> firing too late which still needs to be solved.</p>
<p><strong>Recommendation:</strong> When you’re ready, we encourage you to start trying Hooks in new components you write. Make sure everyone on your team is on board with using them and familiar with this documentation. We don’t recommend rewriting your existing classes to Hooks unless you planned to rewrite them anyway (e.g. to fix bugs). Read more about the adoption strategy <a href="/docs/hooks-faq.html#adoption-strategy">here</a>.</p>
<h3 id="react-16x-q2-2019-the-one-with-concurrent-mode"><a href="#react-16x-q2-2019-the-one-with-concurrent-mode" 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 16.x (~Q2 2019): The One with Concurrent Mode </h3>
<p><em>Concurrent Mode</em> lets React apps be more responsive by rendering component trees without blocking the main thread. It is opt-in and allows React to interrupt a long-running render (for example, rendering a news feed story) to handle a high-priority event (for example, text input or hover). Concurrent Mode also improves the user experience of Suspense by skipping unnecessary loading states on fast connections.</p>
<blockquote>
<p>Note</p>
<p>You might have previously heard Concurrent Mode being referred to as <a href="/blog/2018/03/27/update-on-async-rendering.html">“async mode”</a>. We’ve changed the name to Concurrent Mode to highlight React’s ability to perform work on different priority levels. This sets it apart from other approaches to async rendering.</p>
</blockquote>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Two ways to opt in:</span>

<span class="token comment">// 1. Part of an app (not final API)</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>React.unstable_ConcurrentMode</span><span class="token punctuation">></span></span><span class="token plain-text">
  </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Something</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>React.unstable_ConcurrentMode</span><span class="token punctuation">></span></span>

<span class="token comment">// 2. Whole app (not final API)</span>
ReactDOM<span class="token punctuation">.</span><span class="token function">unstable_createRoot</span><span class="token punctuation">(</span>domNode<span class="token punctuation">)</span><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><span class="token punctuation">;</span></code></pre></div>
<p>There is no documentation written for the Concurrent Mode yet. It is important to highlight that the conceptual model will likely be unfamiliar at first. Documenting its benefits, how to use it efficiently, and its pitfalls is a high priority for us, and will be a prerequisite for calling it stable. Until then, <a href="https://www.youtube.com/watch?v=ByBPyMBTzM0" target="_blank" rel="nofollow noopener noreferrer">Andrew’s talk</a> is the best introduction available.</p>
<p>Concurrent Mode is <em>much</em> less polished than Hooks. Some APIs aren’t properly “wired up” yet and don’t do what they’re expected to. At the time of writing this post, we don’t recommend using it for anything except very early experimentation. We don’t expect many bugs in Concurrent Mode itself, but note that components that produce warnings in <a href="https://reactjs.org/docs/strict-mode.html" target="_blank" rel="nofollow noopener noreferrer"><code class="gatsby-code-text">&lt;React.StrictMode></code></a> may not work correctly. On a separate note, we’ve seen that Concurrent Mode <em>surfaces</em> performance problems in other code which can sometimes be mistaken for performance issues in Concurrent Mode itself. For example, a stray <code class="gatsby-code-text">setInterval(fn, 1)</code> call that runs every millisecond would have a worse effect in Concurrent Mode. We plan to publish more guidance about diagnosing and fixing issues like this as part of this release’s documentation.</p>
<p>Concurrent Mode is a big part of our vision for React. For CPU-bound work, it allows non-blocking rendering and keeps your app responsive while rendering complex component trees. That’s demoed in the first part of <a href="/blog/2018/03/01/sneak-peek-beyond-react-16.html">our JSConf Iceland talk</a>. Concurrent Mode also makes Suspense better. It lets you avoid flickering a loading indicator if the network is fast enough. It’s hard to explain without seeing so <a href="https://www.youtube.com/watch?v=ByBPyMBTzM0" target="_blank" rel="nofollow noopener noreferrer">Andrew’s talk</a> is the best resource available today. Concurrent Mode relies on a cooperative main thread <a href="https://github.com/facebook/react/tree/main/packages/scheduler" target="_blank" rel="nofollow noopener noreferrer">scheduler</a>, and we are <a href="https://www.youtube.com/watch?v=mDdgfyRB5kg" target="_blank" rel="nofollow noopener noreferrer">collaborating with the Chrome team</a> to eventually move this functionality into the browser itself.</p>
<p><strong>Status in React DOM:</strong> A <em>very</em> unstable version of Concurrent Mode is available behind an <code class="gatsby-code-text">unstable_</code> prefix in React 16.6 but we don’t recommend trying it unless you’re willing to often run into walls or missing features. The 16.7 alphas include <code class="gatsby-code-text">React.ConcurrentMode</code> and <code class="gatsby-code-text">ReactDOM.createRoot</code> without an <code class="gatsby-code-text">unstable_</code> prefix, but we’ll likely keep the prefix in 16.7, and only document and mark Concurrent Mode as stable in this future minor release.</p>
<p><strong>Status in React DOM Server:</strong> Concurrent Mode doesn’t directly affect server rendering. It will work with the existing server renderer.</p>
<p><strong>Status in React Native:</strong> The current plan is to delay enabling Concurrent Mode in React Native until <a href="https://github.com/react-native-community/discussions-and-proposals/issues/4" target="_blank" rel="nofollow noopener noreferrer">React Fabric</a> project is near completion.</p>
<p><strong>Recommendation:</strong> If you wish to adopt Concurrent Mode in the future, wrapping some component subtrees in <a href="https://reactjs.org/docs/strict-mode.html" target="_blank" rel="nofollow noopener noreferrer"><code class="gatsby-code-text">&lt;React.StrictMode></code></a> and fixing the resulting warnings is a good first step. In general it’s not expected that legacy code would immediately be compatible. For example, at Facebook we mostly intend to use the Concurrent Mode in the more recently developed codebases, and keep the legacy ones running in the synchronous mode for the near future.</p>
<h3 id="react-16x-mid-2019-the-one-with-suspense-for-data-fetching"><a href="#react-16x-mid-2019-the-one-with-suspense-for-data-fetching" 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 16.x (~mid 2019): The One with Suspense for Data Fetching </h3>
<p>As mentioned earlier, <em>Suspense</em> refers to React’s ability to “suspend” rendering while components are waiting for something, and display a loading indicator. In the already shipped React 16.6, the only supported use case for Suspense is code splitting. In this future minor release, we’d like to provide officially supported ways to use it for data fetching too. We’ll provide a reference implementation of a basic “React Cache” that’s compatible with Suspense, but you can also write your own. Data fetching libraries like Apollo and Relay will be able to integrate with Suspense by following a simple specification that we’ll document.</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// React Cache for simple data fetching (not final API)</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>unstable_createResource<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-cache'</span><span class="token punctuation">;</span>

<span class="token comment">// Tell React Cache how to fetch your data</span>
<span class="token keyword">const</span> TodoResource <span class="token operator">=</span> <span class="token function">unstable_createResource</span><span class="token punctuation">(</span>fetchTodo<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">Todo</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token comment">// Suspends until the data is in the cache</span>
  <span class="token keyword">const</span> todo <span class="token operator">=</span> TodoResource<span class="token punctuation">.</span><span class="token function">read</span><span class="token punctuation">(</span>props<span class="token punctuation">.</span>id<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>li</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>todo<span class="token punctuation">.</span>title<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>li</span><span class="token punctuation">></span></span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">function</span> <span class="token function">App</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">return</span> <span class="token punctuation">(</span>
    <span class="token comment">// Same Suspense component you already use for code splitting</span>
    <span class="token comment">// would be able to handle data fetching too.</span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">React.Suspense</span></span> <span class="token attr-name">fallback</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</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">Spinner</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text">
        </span><span class="token punctuation">{</span><span class="token comment">/* Siblings fetch in parallel */</span><span class="token punctuation">}</span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Todo</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>1<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
        </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">Todo</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>2<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token plain-text">
      </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>ul</span><span class="token punctuation">></span></span><span class="token plain-text">
    </span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span><span class="token class-name">React.Suspense</span></span><span class="token punctuation">></span></span>
  <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// Other libraries like Apollo and Relay can also</span>
<span class="token comment">// provide Suspense integrations with similar APIs.</span></code></pre></div>
<p>There is no official documentation for how to fetch data with Suspense yet, but you can find some early information in <a href="https://youtu.be/ByBPyMBTzM0?t=1312" target="_blank" rel="nofollow noopener noreferrer">this talk</a> and <a href="https://github.com/facebook/react/blob/main/packages/react-devtools/CHANGELOG.md#suspense-toggle" target="_blank" rel="nofollow noopener noreferrer">this small demo</a>. We’ll write documentation for React Cache (and how to write your own Suspense-compatible library) closer to this React release, but if you’re curious, you can find its very early source code <a href="https://github.com/facebook/react/blob/main/packages/react-cache/src/ReactCache.js" target="_blank" rel="nofollow noopener noreferrer">here</a>.</p>
<p>The low-level Suspense mechanism (suspending rendering and showing a fallback) is expected to be stable even in React 16.6. We’ve used it for code splitting in production for months. However, the higher-level APIs for data fetching are very unstable. React Cache is rapidly changing, and will change at least a few more times. There are some low-level APIs that are <a href="https://github.com/reactjs/rfcs/pull/89" target="_blank" rel="nofollow noopener noreferrer">missing</a> for a good higher-level API to be possible. We don’t recommend using React Cache anywhere except very early experiments. Note that React Cache itself isn’t strictly tied to React releases, but the current alphas lack basic features as cache invalidation, and you’ll run into a wall very soon. We expect to have something usable with this React release.</p>
<p>Eventually we’d like most data fetching to happen through Suspense but it will take a long time until all integrations are ready. In practice we expect it to be adopted very incrementally, and often through layers like Apollo or Relay rather than directly. Missing higher level APIs aren’t the only obstacle — there are also some important UI patterns we don’t support yet such as <a href="https://github.com/facebook/react/issues/14248" target="_blank" rel="nofollow noopener noreferrer">showing progress indicator outside of the loading view hierarchy</a>. As always, we will communicate our progress in the release notes on this blog.</p>
<p><strong>Status in React DOM and React Native:</strong> Technically, a compatible cache would already work with <code class="gatsby-code-text">&lt;React.Suspense></code> in React 16.6. However, we don’t expect to have a good cache implementation until this React minor release. If you’re feeling adventurous, you can try to write your own cache by looking at the React Cache alphas. However, note that the mental model is sufficiently different that there’s a high risk of misunderstanding it until the docs are ready.</p>
<p><strong>Status in React DOM Server:</strong> Suspense is not available in the server renderer yet. As we mentioned earlier, we’ve started work on a new asynchronous server renderer that will support Suspense, but it’s a large project and will take a good chunk of 2019 to complete.</p>
<p><strong>Recommendation:</strong> Wait for this minor React release in order to use Suspense for data fetching. Don’t try to use Suspense features in 16.6 for it; it’s not supported. However, your existing <code class="gatsby-code-text">&lt;Suspense></code> components for code splitting will be able to show loading states for data too when Suspense for Data Fetching becomes officially supported.</p>
<h2 id="other-projects"><a href="#other-projects" 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 Projects </h2>
<h3 id="modernizing-react-dom"><a href="#modernizing-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>Modernizing React DOM </h3>
<p>We started an investigation into <a href="https://github.com/facebook/react/issues/13525" target="_blank" rel="nofollow noopener noreferrer">simplifying and modernizing</a> ReactDOM, with a goal of reduced bundle size and aligning closer with the browser behavior. It is still early to say which specific bullet points will “make it” because the project is in an exploratory phase. We will communicate our progress on that issue.</p>
<h3 id="suspense-for-server-rendering"><a href="#suspense-for-server-rendering" 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>Suspense for Server Rendering </h3>
<p>We started designing a new server renderer that supports Suspense (including waiting for asynchronous data on the server without double rendering) and progressively loading and hydrating page content in chunks for best user experience. You can watch an overview of its early prototype in <a href="https://www.youtube.com/watch?v=z-6JC0_cOns" target="_blank" rel="nofollow noopener noreferrer">this talk</a>. The new server renderer is going to be our major focus in 2019, but it’s too early to say anything about its release schedule. Its development, as always, <a href="https://github.com/facebook/react/pulls?utf8=%E2%9C%93&#x26;q=is%3Apr+is%3Aopen+fizz" target="_blank" rel="nofollow noopener noreferrer">will happen on GitHub</a>.</p>
<hr>
<p>And that’s about it! As you can see, there’s a lot here to keep us busy but we expect much progress in the coming months.</p>
<p>We hope this post gives you an idea of what we’re working on, what you can use today, and what you can expect to use in the future. While there’s a lot of discussion about new features on social media platforms, you won’t miss anything important if you read this blog.</p>
<p>We’re always open to feedback, and love to hear from you in the <a href="https://github.com/reactjs/rfcs" target="_blank" rel="nofollow noopener noreferrer">RFC repository</a>, <a href="https://github.com/facebook/react/issues" target="_blank" rel="nofollow noopener noreferrer">the issue tracker</a>, and <a href="https://mobile.twitter.com/reactjs" target="_blank" rel="nofollow noopener noreferrer">on Twitter</a>.</p>]]></description><link>https://reactjs.org/blog/2018/11/27/react-16-roadmap.html</link><guid isPermaLink="false">https://reactjs.org/blog/2018/11/27/react-16-roadmap.html</guid><pubDate>Tue, 27 Nov 2018 00:00:00 GMT</pubDate></item></channel></rss>