<?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>Tue, 18 Apr 2023 22:30:42 GMT</lastBuildDate><item><title><![CDATA[How to Upgrade to the React 18 Release Candidate]]></title><description><![CDATA[<p>Our next major version, React 18, is available today as a Release Candidate (RC). As we shared at <a href="https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html" target="_blank" rel="nofollow noopener noreferrer">React Conf</a>, React 18 introduces features powered by our new concurrent renderer, with a gradual adoption strategy for existing applications. In this post, we will guide you through the steps for upgrading to React 18.</p>
<p>If you’d like to help us test React 18, follow the steps in this upgrade guide and <a href="https://github.com/facebook/react/issues/new/choose" target="_blank" rel="nofollow noopener noreferrer">report any issues</a> you encounter so we can fix them before the stable release.</p>
<p><em>Note for React Native users: React 18 will ship in React Native with the New React Native Architecture. For more information, see the <a href="https://www.youtube.com/watch?v=FZ0cG47msEk&#x26;t=1530s" target="_blank" rel="nofollow noopener noreferrer">React Conf keynote here</a>.</em></p>
<h2 id="installing"><a href="#installing" 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>Installing</h2>
<p>To install the latest React 18 RC, use the <code class="gatsby-code-text">@rc</code> tag:</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@rc react-dom@rc</code></pre></div>
<p>Or if you’re using yarn:</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@rc react-dom@rc</code></pre></div>
<h2 id="updates-to-client-rendering-apis"><a href="#updates-to-client-rendering-apis" 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>Updates to Client Rendering APIs</h2>
<p>When you first install React 18, you will see a warning in the console:</p>
<blockquote>
<p>ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it’s running React 17. Learn more: <a href="https://reactjs.org/link/switch-to-createroot" target="_blank" rel="nofollow noopener noreferrer">https://reactjs.org/link/switch-to-createroot</a></p>
</blockquote>
<p>React 18 introduces a new root API which provides better ergonomics for managing roots. The new root API also enables the new concurrent renderer, which allows you to opt-into concurrent features.</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Before</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> render <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> container <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">'app'</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 tag"><span class="token tag"><span class="token punctuation">&lt;</span><span class="token class-name">App</span></span> <span class="token attr-name">tab</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>home<span class="token punctuation">"</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 class="token comment">// After</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> createRoot <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom/client'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> container <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">'app'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> root <span class="token operator">=</span> <span class="token function">createRoot</span><span class="token punctuation">(</span>container<span class="token punctuation">)</span><span class="token punctuation">;</span>
root<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 attr-name">tab</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>home<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>We’ve also changed <code class="gatsby-code-text">unmountComponentAtNode</code> to <code class="gatsby-code-text">root.unmount</code>:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Before</span>
<span class="token function">unmountComponentAtNode</span><span class="token punctuation">(</span>container<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// After</span>
root<span class="token punctuation">.</span><span class="token function">unmount</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>We’ve also removed the callback from render, since it usually does not have the expected result when using Suspense:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Before</span>
<span class="token keyword">const</span> container <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">'app'</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 attr-name">tab</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>home<span class="token punctuation">"</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 class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
  console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'rendered'</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 comment">// After</span>
<span class="token keyword">function</span> <span class="token function">AppWithCallbackAfterRender</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <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>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'rendered'</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">return</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 attr-name">tab</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>home<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token punctuation">}</span>

<span class="token keyword">const</span> container <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">'app'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> root <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">createRoot</span><span class="token punctuation">(</span>container<span class="token punctuation">)</span><span class="token punctuation">;</span>
root<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">AppWithCallbackAfterRender</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<blockquote>
<p>Note: There is no one-to-one replacement for the old render callback API — it depends on your use case. See the working group post for <a href="https://github.com/reactwg/react-18/discussions/5" target="_blank" rel="nofollow noopener noreferrer">Replacing render with createRoot</a> for more information.</p>
</blockquote>
<p>Finally, if your app uses server-side rendering with hydration, upgrade <code class="gatsby-code-text">hydrate</code> to <code class="gatsby-code-text">hydrateRoot</code>:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Before</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> hydrate <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> container <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">'app'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">hydrate</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 attr-name">tab</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>home<span class="token punctuation">"</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 class="token comment">// After</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span> hydrateRoot <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom/client'</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> container <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">'app'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> root <span class="token operator">=</span> <span class="token function">hydrateRoot</span><span class="token punctuation">(</span>container<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 attr-name">tab</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>home<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Unlike with createRoot, you don't need a separate root.render() call here.</span></code></pre></div>
<p>For more information, see the <a href="https://github.com/reactwg/react-18/discussions/5" target="_blank" rel="nofollow noopener noreferrer">working group discussion here</a>.</p>
<h2 id="updates-to-server-rendering-apis"><a href="#updates-to-server-rendering-apis" 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>Updates to Server Rendering APIs</h2>
<p>In this release, we’re revamping our <code class="gatsby-code-text">react-dom/server</code> APIs to fully support Suspense on the server and Streaming SSR. As part of these changes, we’re deprecating the old Node streaming API, which does not support incremental Suspense streaming on the server.</p>
<p>Using this API will now warn:</p>
<ul>
<li><code class="gatsby-code-text">renderToNodeStream</code>: <strong>Deprecated ⛔️️</strong></li>
</ul>
<p>Instead, for streaming in Node environments, use:</p>
<ul>
<li><code class="gatsby-code-text">renderToPipeableStream</code>: <strong>New ✨</strong></li>
</ul>
<p>We’re also introducing a new API to support streaming SSR with Suspense for modern edge runtime environments, such as Deno and Cloudflare workers:</p>
<ul>
<li><code class="gatsby-code-text">renderToReadableStream</code>: <strong>New ✨</strong></li>
</ul>
<p>The following APIs will continue working, but with limited support for Suspense:</p>
<ul>
<li><code class="gatsby-code-text">renderToString</code>: <strong>Limited</strong> ⚠️</li>
<li><code class="gatsby-code-text">renderToStaticMarkup</code>: <strong>Limited</strong> ⚠️</li>
</ul>
<p>Finally, this API will continue to work for rendering e-mails:</p>
<ul>
<li><code class="gatsby-code-text">renderToStaticNodeStream</code></li>
</ul>
<p>For more information on the changes to server rendering APIs, see the working group post on <a href="https://github.com/reactwg/react-18/discussions/22" target="_blank" rel="nofollow noopener noreferrer">Upgrading to React 18 on the server</a>, a <a href="https://github.com/reactwg/react-18/discussions/37" target="_blank" rel="nofollow noopener noreferrer">deep dive on the new Suspense SSR Architecture</a>, and <a href="https://twitter.com/shaundai" target="_blank" rel="nofollow noopener noreferrer">Shaundai Person’s</a> talk on <a href="https://www.youtube.com/watch?v=pj5N-Khihgc" target="_blank" rel="nofollow noopener noreferrer">Streaming Server Rendering with Suspense</a> at React Conf 2021.</p>
<h2 id="automatic-batching"><a href="#automatic-batching" 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>Automatic Batching</h2>
<p>React 18 adds out-of-the-box performance improvements by doing more batching by default. Batching is when React groups multiple state updates into a single re-render for better performance. Before React 18, we only batched updates inside React event handlers. Updates inside of promises, setTimeout, native event handlers, or any other event were not batched in React by default:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Before React 18 only React events were batched</span>

<span class="token keyword">function</span> <span class="token function">handleClick</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">setCount</span><span class="token punctuation">(</span><span class="token parameter">c</span> <span class="token operator">=></span> c <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">setFlag</span><span class="token punctuation">(</span><span class="token parameter">f</span> <span class="token operator">=></span> <span class="token operator">!</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// React will only re-render once at the end (that's batching!)</span>
<span class="token punctuation">}</span>

<span class="token function">setTimeout</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 function">setCount</span><span class="token punctuation">(</span><span class="token parameter">c</span> <span class="token operator">=></span> c <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">setFlag</span><span class="token punctuation">(</span><span class="token parameter">f</span> <span class="token operator">=></span> <span class="token operator">!</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// React will render twice, once for each state update (no batching)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>Starting in React 18 with <code class="gatsby-code-text">createRoot</code>, all updates will be automatically batched, no matter where they originate from. This means that updates inside of timeouts, promises, native event handlers or any other event will batch the same way as updates inside of React events:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// After React 18 updates inside of timeouts, promises,</span>
<span class="token comment">// native event handlers or any other event are batched.</span>

<span class="token keyword">function</span> <span class="token function">handleClick</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">setCount</span><span class="token punctuation">(</span><span class="token parameter">c</span> <span class="token operator">=></span> c <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">setFlag</span><span class="token punctuation">(</span><span class="token parameter">f</span> <span class="token operator">=></span> <span class="token operator">!</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// React will only re-render once at the end (that's batching!)</span>
<span class="token punctuation">}</span>

<span class="token function">setTimeout</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 function">setCount</span><span class="token punctuation">(</span><span class="token parameter">c</span> <span class="token operator">=></span> c <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token function">setFlag</span><span class="token punctuation">(</span><span class="token parameter">f</span> <span class="token operator">=></span> <span class="token operator">!</span>f<span class="token punctuation">)</span><span class="token punctuation">;</span>
  <span class="token comment">// React will only re-render once at the end (that's batching!)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>
<p>This is a breaking change, but we expect this to result in less work rendering, and therefore better performance in your applications. To opt-out of automatic batching, you can use <code class="gatsby-code-text">flushSync</code>:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">import</span> <span class="token punctuation">{</span> flushSync <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom'</span><span class="token punctuation">;</span>

<span class="token keyword">function</span> <span class="token function">handleClick</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token function">flushSync</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 function">setCounter</span><span class="token punctuation">(</span><span class="token parameter">c</span> <span class="token operator">=></span> c <span class="token operator">+</span> <span class="token number">1</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 comment">// React has updated the DOM by now</span>
  <span class="token function">flushSync</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 function">setFlag</span><span class="token punctuation">(</span><span class="token parameter">f</span> <span class="token operator">=></span> <span class="token operator">!</span>f<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 comment">// React has updated the DOM by now</span>
<span class="token punctuation">}</span></code></pre></div>
<p>For more information, see the <a href="https://github.com/reactwg/react-18/discussions/21" target="_blank" rel="nofollow noopener noreferrer">Automatic batching deep dive</a>.</p>
<h2 id="new-apis-for-libraries"><a href="#new-apis-for-libraries" 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 APIs for Libraries</h2>
<p>In the React 18 Working Group we worked with library maintainers to create new APIs needed to support concurrent rendering for use cases specific to their use case in areas like styles, external stores, and accessibility. To support React 18, some libraries may need to switch to one of the following APIs:</p>
<ul>
<li><code class="gatsby-code-text">useId</code> is a new hook for generating unique IDs on both the client and server, while avoiding hydration mismatches. This solves an issue that already exists in React 17 and below, but it’s even more important in React 18 because of how our streaming server renderer delivers HTML out-of-order. For more information see the <a href="https://github.com/reactwg/react-18/discussions/111" target="_blank" rel="nofollow noopener noreferrer">useId post in the working group</a>.</li>
<li><code class="gatsby-code-text">useSyncExternalStore</code> is a new hook that allows external stores to support concurrent reads by forcing updates to the store to be synchronous. This new API is recommended for any library that integrates with state external to React. For more information, see the <a href="https://github.com/reactwg/react-18/discussions/70" target="_blank" rel="nofollow noopener noreferrer">useSyncExternalStore overview post</a> and <a href="https://github.com/reactwg/react-18/discussions/86" target="_blank" rel="nofollow noopener noreferrer">useSyncExternalStore API details</a>.</li>
<li><code class="gatsby-code-text">useInsertionEffect</code> is a new hook that allows CSS-in-JS libraries to address performance issues of injecting styles in render. Unless you’ve already built a CSS-in-JS library we don’t expect you to ever use this. This hook will run after the DOM is mutated, but before layout effects read the new layout. This solves an issue that already exists in React 17 and below, but is even more important in React 18 because React yields to the browser during concurrent rendering, giving it a chance to recalculate layout. For more information, see the <a href="https://github.com/reactwg/react-18/discussions/110" target="_blank" rel="nofollow noopener noreferrer">Library Upgrade Guide for <code class="gatsby-code-text">&lt;style></code></a>.</li>
</ul>
<p>React 18 also introduces new APIs for concurrent rendering such as <code class="gatsby-code-text">startTransition</code> and <code class="gatsby-code-text">useDeferredValue</code>, which we will share more about in the upcoming stable release post.</p>
<h2 id="updates-to-strict-mode"><a href="#updates-to-strict-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>Updates to Strict Mode</h2>
<p>In the future, we’d like to add a feature that allows React to add and remove sections of the UI while preserving state. For example, when a user tabs away from a screen and back, React should be able to immediately show the previous screen. To do this, React would unmount and remount trees using the same component state as before.</p>
<p>This feature will give React better performance out-of-the-box, but requires components to be resilient to effects being mounted and destroyed multiple times. Most effects will work without any changes, but some effects assume they are only mounted or destroyed once.</p>
<p>To help surface these issues, React 18 introduces a new development-only check to Strict Mode. This new check will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount.</p>
<p>Before this change, React would mount the component and create the effects:</p>
<div class="gatsby-highlight" data-language="text"><pre class="gatsby-code-text"><code class="gatsby-code-text">* React mounts the component.
    * Layout effects are created.
    * Effect effects are created.</code></pre></div>
<p>With Strict Mode in React 18, React will simulate unmounting and remounting the component in development mode:</p>
<div class="gatsby-highlight" data-language="text"><pre class="gatsby-code-text"><code class="gatsby-code-text">* React mounts the component.
    * Layout effects are created.
    * Effect effects are created.
* React simulates unmounting the component.
    * Layout effects are destroyed.
    * Effects are destroyed.
* React simulates mounting the component with the previous state.
    * Layout effect setup code runs
    * Effect setup code runs</code></pre></div>
<p>For more information, see the Working Group posts for <a href="https://github.com/reactwg/react-18/discussions/19" target="_blank" rel="nofollow noopener noreferrer">Adding Strict Effects to Strict Mode</a> and <a href="https://github.com/reactwg/react-18/discussions/18" target="_blank" rel="nofollow noopener noreferrer">How to Support Strict Effects</a>.</p>
<h2 id="configuring-your-testing-environment"><a href="#configuring-your-testing-environment" 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>Configuring Your Testing Environment</h2>
<p>When you first update your tests to use <code class="gatsby-code-text">createRoot</code>, you may see this warning in your test console:</p>
<blockquote>
<p>The current testing environment is not configured to support act(…)</p>
</blockquote>
<p>To fix this, set <code class="gatsby-code-text">globalThis.IS_REACT_ACT_ENVIRONMENT</code> to <code class="gatsby-code-text">true</code> before running your test:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// In your test setup file</span>
globalThis<span class="token punctuation">.</span><span class="token constant">IS_REACT_ACT_ENVIRONMENT</span> <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span></code></pre></div>
<p>The purpose of the flag is to tell React that it’s running in a unit test-like environment. React will log helpful warnings if you forget to wrap an update with <code class="gatsby-code-text">act</code>.</p>
<p>You can also set the flag to <code class="gatsby-code-text">false</code> to tell React that <code class="gatsby-code-text">act</code> isn’t needed. This can be useful for end-to-end tests that simulate a full browser environment.</p>
<p>Eventually, we expect testing libraries will configure this for you automatically. For example, the <a href="https://github.com/testing-library/react-testing-library/issues/509#issuecomment-917989936" target="_blank" rel="nofollow noopener noreferrer">next version of React Testing Library has built-in support for React 18</a> without any additional configuration.</p>
<p><a href="https://github.com/reactwg/react-18/discussions/102" target="_blank" rel="nofollow noopener noreferrer">More background on the the <code class="gatsby-code-text">act</code> testing API and related changes</a> is available in the working group.</p>
<h2 id="dropping-support-for-internet-explorer"><a href="#dropping-support-for-internet-explorer" 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>Dropping Support for Internet Explorer</h2>
<p>In this release, React is dropping support for Internet Explorer, which is <a href="https://blogs.windows.com/windowsexperience/2021/05/19/the-future-of-internet-explorer-on-windows-10-is-in-microsoft-edge" target="_blank" rel="nofollow noopener noreferrer">going out of support on June 15, 2022</a>. We’re making this change now because new features introduced in React 18 are built using modern browser features such as microtasks which cannot be adequately polyfilled in IE.</p>
<p>If you need to support Internet Explorer we recommend you stay with React 17.</p>
<h2 id="other-changes"><a href="#other-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 Changes</h2>
<ul>
<li><a href="https://github.com/reactwg/react-18/discussions/82" target="_blank" rel="nofollow noopener noreferrer">Update to remove the “setState on unmounted component” warning</a></li>
<li><a href="https://github.com/reactwg/react-18/discussions/72" target="_blank" rel="nofollow noopener noreferrer">Suspense no longer requires a <code class="gatsby-code-text">fallback</code> prop to capture</a></li>
<li><a href="https://github.com/reactwg/react-18/discussions/75" target="_blank" rel="nofollow noopener noreferrer">Components can now render undefined</a></li>
<li><a href="https://github.com/facebook/react/pull/23355" target="_blank" rel="nofollow noopener noreferrer">Deprecated renderSubtreeIntoContainer</a></li>
<li><a href="https://github.com/reactwg/react-18/discussions/96" target="_blank" rel="nofollow noopener noreferrer">StrictMode updated to not silence double logging by default</a></li>
</ul>]]></description><link>https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html</link><guid isPermaLink="false">https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html</guid><pubDate>Tue, 08 Mar 2022 00:00:00 GMT</pubDate></item><item><title><![CDATA[React Conf 2021 Recap]]></title><description><![CDATA[<p>Last week we hosted our 6th React Conf.  In previous years, we’ve used the React Conf stage to deliver industry changing announcements such as <a href="https://engineering.fb.com/2015/03/26/android/react-native-bringing-modern-web-techniques-to-mobile/" target="_blank" rel="nofollow noopener noreferrer"><em>React Native</em></a> and <a href="https://reactjs.org/docs/hooks-intro.html" target="_blank" rel="nofollow noopener noreferrer"><em>React Hooks</em></a>. This year, we shared our multi-platform vision for React, starting with the release of React 18 and gradual adoption of concurrent features.</p>
<p>This was the first time React Conf was hosted online, and it was streamed for free, translated to 8 different languages. Participants from all over the world joined our conference Discord and the replay event for accessibility in all timezones. Over 50,000 people registered, with over 60,000 views of 19 talks, and 5,000 participants in Discord across both events.</p>
<p>All the talks are <a href="https://www.youtube.com/watch?v=FZ0cG47msEk&#x26;list=PLNG_1j3cPCaZZ7etkzWA7JfdmKWT0pMsa" target="_blank" rel="nofollow noopener noreferrer">available to stream online</a>.</p>
<p>Here’s a summary of what was shared on stage:</p>
<h2 id="react-18-and-concurrent-features"><a href="#react-18-and-concurrent-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>React 18 and concurrent features </h2>
<p>In the keynote, we shared our vision for the future of React starting with React 18.</p>
<p>React 18 adds the long-awaited concurrent renderer and updates to Suspense without any major breaking changes. Apps can upgrade to React 18 and begin gradually adopting concurrent features with the amount of effort on par with any other major release.</p>
<p><strong>This means there is no concurrent mode, only concurrent features.</strong></p>
<p>In the keynote, we also shared our vision for Suspense, Server Components, new React working groups, and our long-term many-platform vision for React Native.</p>
<p>Watch the full keynote from <a href="https://twitter.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">Andrew Clark</a>, <a href="https://twitter.com/_jstejada" target="_blank" rel="nofollow noopener noreferrer">Juan Tejada</a>, <a href="https://twitter.com/sugarpirate_" target="_blank" rel="nofollow noopener noreferrer">Lauren Tan</a>, and <a href="https://twitter.com/rickhanlonii" target="_blank" rel="nofollow noopener noreferrer">Rick Hanlon</a> here:</p>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe style="margin-top:10px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " src="https://www.youtube.com/embed/FZ0cG47msEk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
<h2 id="react-18-for-application-developers"><a href="#react-18-for-application-developers" 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 18 for Application Developers </h2>
<p>In the keynote, we also announced that the React 18 RC is available to try now. Pending further feedback, this is the exact version of React that we will publish to stable early next year.</p>
<p>To try the React 18 RC, upgrade your dependencies:</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@rc react-dom@rc</code></pre></div>
<p>and switch to the new <code class="gatsby-code-text">createRoot</code> API:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// before</span>
<span class="token keyword">const</span> container <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> container<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">// after</span>
<span class="token keyword">const</span> container <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>
<span class="token keyword">const</span> root <span class="token operator">=</span> ReactDOM<span class="token punctuation">.</span><span class="token function">createRoot</span><span class="token punctuation">(</span>container<span class="token punctuation">)</span><span class="token punctuation">;</span>
root<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>For a demo of upgrading to React 18, see <a href="https://twitter.com/shrutikapoor08" target="_blank" rel="nofollow noopener noreferrer">Shruti Kapoor</a>’s talk here:</p>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe style="margin-top:10px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " src="https://www.youtube.com/embed/ytudH8je5ko" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
<h2 id="streaming-server-rendering-with-suspense"><a href="#streaming-server-rendering-with-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>Streaming Server Rendering with Suspense </h2>
<p>React 18 also includes improvements to server-side rendering performance using Suspense.</p>
<p>Streaming server rendering lets you generate HTML from React components on the server, and stream that HTML to your users. In React 18, you can use <code class="gatsby-code-text">Suspense</code> to break down your app into smaller independent units which can be streamed independently of each other without blocking the rest of the app. This means users will see your content sooner and be able to start interacting with it much faster.</p>
<p>For a deep dive, see <a href="https://twitter.com/shaundai" target="_blank" rel="nofollow noopener noreferrer">Shaundai Person</a>’s talk here:</p>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe style="margin-top:10px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " src="https://www.youtube.com/embed/pj5N-Khihgc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
<h2 id="the-first-react-working-group"><a href="#the-first-react-working-group" 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 first React working group </h2>
<p>For React 18, we created our first Working Group to collaborate with a panel of experts, developers, library maintainers, and educators. Together we worked to create our gradual adoption strategy and refine new APIs such as <code class="gatsby-code-text">useId</code>, <code class="gatsby-code-text">useSyncExternalStore</code>, and <code class="gatsby-code-text">useInsertionEffect</code>.</p>
<p>For an overview of this work, see <a href="https://twitter.com/aakansha1216" target="_blank" rel="nofollow noopener noreferrer">Aakansha’ Doshi</a>’s talk:</p>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe style="margin-top:10px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " src="https://www.youtube.com/embed/qn7gRClrC9U" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
<h2 id="react-developer-tooling"><a href="#react-developer-tooling" 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 Developer Tooling </h2>
<p>To support the new features in this release, we also announced the newly formed React DevTools team and a new Timeline Profiler to help developers debug their React apps.</p>
<p>For more information and a demo of new DevTools features, see <a href="https://twitter.com/brian_d_vaughn" target="_blank" rel="nofollow noopener noreferrer">Brian Vaughn</a>’s talk:</p>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe style="margin-top:10px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " src="https://www.youtube.com/embed/oxDfrke8rZg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
<h2 id="react-without-memo"><a href="#react-without-memo" 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 without memo </h2>
<p>Looking further into the future, <a href="https://twitter.com/Huxpro" target="_blank" rel="nofollow noopener noreferrer">Xuan Huang (黄玄)</a> shared an update from our React Labs research into an auto-memoizing compiler. Check out this talk for more information and a demo of the compiler prototype:</p>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe style="margin-top:10px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " src="https://www.youtube.com/embed/lGEMwh32soc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
<h2 id="react-docs-keynote"><a href="#react-docs-keynote" 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 docs keynote </h2>
<p><a href="https://twitter.com/rachelnabors" target="_blank" rel="nofollow noopener noreferrer">Rachel Nabors</a> kicked off a section of talks about learning and designing with React with a keynote about our investment in React’s <a href="https://beta.reactjs.org/" target="_blank" rel="nofollow noopener noreferrer">new docs</a>:</p>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe style="margin-top:10px; position: absolute; top: 0; left: 0; width: 100%; height: 100%; " src="https://www.youtube.com/embed/mneDaMYOKP8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> </div>
<h1 id="and-more"><a href="#and-more" 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>And more… </h1>
<p><strong>We also heard talks on learning and designing with React:</strong></p>
<ul>
<li>Debbie O’Brien: <a href="https://youtu.be/-7odLW_hG7s" target="_blank" rel="nofollow noopener noreferrer">Things I learnt from the new React docs</a>.</li>
<li>Sarah Rainsberger: <a href="https://youtu.be/5X-WEQflCL0" target="_blank" rel="nofollow noopener noreferrer">Learning in the Browser</a>.</li>
<li>Linton Ye: <a href="https://youtu.be/7cPWmID5XAk" target="_blank" rel="nofollow noopener noreferrer">The ROI of Designing with React</a>.</li>
<li>Delba de Oliveira: <a href="https://youtu.be/zL8cz2W0z34" target="_blank" rel="nofollow noopener noreferrer">Interactive playgrounds with React</a>.</li>
</ul>
<p><strong>Talks from the Relay, React Native, and PyTorch teams:</strong></p>
<ul>
<li>Robert Balicki: <a href="https://youtu.be/lhVGdErZuN4" target="_blank" rel="nofollow noopener noreferrer">Re-introducing Relay</a>.</li>
<li>Eric Rozell and Steven Moyes: <a href="https://youtu.be/9L4FFrvwJwY" target="_blank" rel="nofollow noopener noreferrer">React Native Desktop</a>.</li>
<li>Roman Rädle: <a href="https://youtu.be/NLj73vrc2I8" target="_blank" rel="nofollow noopener noreferrer">On-device Machine Learning for React Native</a></li>
</ul>
<p><strong>And talks from the community on accessibility, tooling, and Server Components:</strong></p>
<ul>
<li>Daishi Kato: <a href="https://youtu.be/oPfSC5bQPR8" target="_blank" rel="nofollow noopener noreferrer">React 18 for External Store Libraries</a>.</li>
<li>Diego Haz: <a href="https://youtu.be/dcm8fjBfro8" target="_blank" rel="nofollow noopener noreferrer">Building Accessible Components in React 18</a>.</li>
<li>Tafu Nakazaki: <a href="https://youtu.be/S4a0QlsH0pU" target="_blank" rel="nofollow noopener noreferrer">Accessible Japanese Form Components with React</a>.</li>
<li>Lyle Troxell: <a href="https://youtu.be/b3l4WxipFsE" target="_blank" rel="nofollow noopener noreferrer">UI tools for artists</a>.</li>
<li>Helen Lin: <a href="https://youtu.be/HS6vIYkSNks" target="_blank" rel="nofollow noopener noreferrer">Hydrogen + React 18</a>.</li>
</ul>
<h1 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 </h1>
<p>This was our first year planning a conference ourselves, and we have a lot of people to thank.</p>
<p>First, thanks to all of our speakers <a href="https://twitter.com/aakansha1216" target="_blank" rel="nofollow noopener noreferrer">Aakansha Doshi</a>, <a href="https://twitter.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">Andrew Clark</a>, <a href="https://twitter.com/brian_d_vaughn" target="_blank" rel="nofollow noopener noreferrer">Brian Vaughn</a>, <a href="https://twitter.com/dai_shi" target="_blank" rel="nofollow noopener noreferrer">Daishi Kato</a>, <a href="https://twitter.com/debs_obrien" target="_blank" rel="nofollow noopener noreferrer">Debbie O’Brien</a>, <a href="https://twitter.com/delba_oliveira" target="_blank" rel="nofollow noopener noreferrer">Delba de Oliveira</a>, <a href="https://twitter.com/diegohaz" target="_blank" rel="nofollow noopener noreferrer">Diego Haz</a>, <a href="https://twitter.com/EricRozell" target="_blank" rel="nofollow noopener noreferrer">Eric Rozell</a>, <a href="https://twitter.com/wizardlyhel" target="_blank" rel="nofollow noopener noreferrer">Helen Lin</a>, <a href="https://twitter.com/_jstejada" target="_blank" rel="nofollow noopener noreferrer">Juan Tejada</a>, <a href="https://twitter.com/sugarpirate_" target="_blank" rel="nofollow noopener noreferrer">Lauren Tan</a>, <a href="https://twitter.com/lintonye" target="_blank" rel="nofollow noopener noreferrer">Linton Ye</a>, <a href="https://twitter.com/lyle" target="_blank" rel="nofollow noopener noreferrer">Lyle Troxell</a>, <a href="https://twitter.com/rachelnabors" target="_blank" rel="nofollow noopener noreferrer">Rachel Nabors</a>, <a href="https://twitter.com/rickhanlonii" target="_blank" rel="nofollow noopener noreferrer">Rick Hanlon</a>, <a href="https://twitter.com/StatisticsFTW" target="_blank" rel="nofollow noopener noreferrer">Robert Balicki</a>, <a href="https://twitter.com/raedle" target="_blank" rel="nofollow noopener noreferrer">Roman Rädle</a>, <a href="https://twitter.com/sarah11918" target="_blank" rel="nofollow noopener noreferrer">Sarah Rainsberger</a>, <a href="https://twitter.com/shaundai" target="_blank" rel="nofollow noopener noreferrer">Shaundai Person</a>, <a href="https://twitter.com/shrutikapoor08" target="_blank" rel="nofollow noopener noreferrer">Shruti Kapoor</a>, <a href="https://twitter.com/moyessa" target="_blank" rel="nofollow noopener noreferrer">Steven Moyes</a>, <a href="https://twitter.com/hawaiiman0" target="_blank" rel="nofollow noopener noreferrer">Tafu Nakazaki</a>, and  <a href="https://twitter.com/Huxpro" target="_blank" rel="nofollow noopener noreferrer">Xuan Huang (黄玄)</a>.</p>
<p>Thanks to everyone who helped provide feedback on talks including <a href="https://twitter.com/acdlite" target="_blank" rel="nofollow noopener noreferrer">Andrew Clark</a>, <a href="https://twitter.com/dan_abramov" target="_blank" rel="nofollow noopener noreferrer">Dan Abramov</a>, <a href="https://twitter.com/mcc_abe" target="_blank" rel="nofollow noopener noreferrer">Dave McCabe</a>, <a href="https://twitter.com/Eli_White" target="_blank" rel="nofollow noopener noreferrer">Eli White</a>, <a href="https://twitter.com/en_JS" target="_blank" rel="nofollow noopener noreferrer">Joe Savona</a>,  <a href="https://twitter.com/sugarpirate_" target="_blank" rel="nofollow noopener noreferrer">Lauren Tan</a>, <a href="https://twitter.com/rachelnabors" target="_blank" rel="nofollow noopener noreferrer">Rachel Nabors</a>, and <a href="https://twitter.com/yungsters" target="_blank" rel="nofollow noopener noreferrer">Tim Yung</a>.</p>
<p>Thanks to <a href="https://twitter.com/sugarpirate_" target="_blank" rel="nofollow noopener noreferrer">Lauren Tan</a> for setting up the conference Discord and serving as our Discord admin.</p>
<p>Thanks to <a href="https://twitter.com/sethwebster" target="_blank" rel="nofollow noopener noreferrer">Seth Webster</a> for feedback on overall direction and making sure we were focused on diversity and inclusion.</p>
<p>Thanks to <a href="https://twitter.com/rachelnabors" target="_blank" rel="nofollow noopener noreferrer">Rachel Nabors</a> for spearheading our moderation effort, and <a href="https://twitter.com/AishaBlake" target="_blank" rel="nofollow noopener noreferrer">Aisha Blake</a> for creating our moderation guide, leading our moderation team, training the translators and moderators, and helping to moderate both events.</p>
<p>Thanks to our moderators <a href="https://twitter.com/jtannady" target="_blank" rel="nofollow noopener noreferrer">Jesslyn Tannady</a>, <a href="https://twitter.com/missuze" target="_blank" rel="nofollow noopener noreferrer">Suzie Grange</a>, <a href="https://twitter.com/beccaliz" target="_blank" rel="nofollow noopener noreferrer">Becca Bailey</a>, <a href="https://twitter.com/lunaleaps" target="_blank" rel="nofollow noopener noreferrer">Luna Wei</a>, <a href="https://twitter.com/jsjoeio" target="_blank" rel="nofollow noopener noreferrer">Joe Previte</a>, <a href="https://twitter.com/Cortinico" target="_blank" rel="nofollow noopener noreferrer">Nicola Corti</a>, <a href="https://twitter.com/gweterings" target="_blank" rel="nofollow noopener noreferrer">Gijs Weterings</a>, <a href="https://twitter.com/claudiopro" target="_blank" rel="nofollow noopener noreferrer">Claudio Procida</a>, Julia Neumann, Mengdi Chen, Jean Zhang, Ricky Li, and <a href="https://twitter.com/Huxpro" target="_blank" rel="nofollow noopener noreferrer">Xuan Huang (黄玄)</a>.</p>
<p>Thanks to <a href="https://twitter.com/manjula_dube" target="_blank" rel="nofollow noopener noreferrer">Manjula Dube</a>, <a href="https://twitter.com/apheri0" target="_blank" rel="nofollow noopener noreferrer">Sahil Mhapsekar</a>, and Vihang Patel from <a href="https://www.reactindia.io/" target="_blank" rel="nofollow noopener noreferrer">React India</a>, and <a href="https://twitter.com/jasmine_xby" target="_blank" rel="nofollow noopener noreferrer">Jasmine Xie</a>, <a href="https://twitter.com/QCL15" target="_blank" rel="nofollow noopener noreferrer">QiChang Li</a>, and <a href="https://twitter.com/anneincoding" target="_blank" rel="nofollow noopener noreferrer">YanLun Li</a> from <a href="https://twitter.com/ReactChina" target="_blank" rel="nofollow noopener noreferrer">React China</a> for helping moderate our replay event and keep it engaging for the community.</p>
<p>Thanks to Vercel for publishing their <a href="https://vercel.com/virtual-event-starter-kit" target="_blank" rel="nofollow noopener noreferrer">Virtual Event Starter Kit</a>, which the conference website was built on, and to <a href="https://twitter.com/leeerob" target="_blank" rel="nofollow noopener noreferrer">Lee Robinson</a> and <a href="https://twitter.com/delba_oliveira" target="_blank" rel="nofollow noopener noreferrer">Delba de Oliveira</a> for sharing their experience running Next.js Conf.</p>
<p>Thanks to <a href="https://twitter.com/wifelette" target="_blank" rel="nofollow noopener noreferrer">Leah Silber</a> for sharing her experience running conferences, learnings from running <a href="https://rustconf.com/" target="_blank" rel="nofollow noopener noreferrer">RustConf</a>, and for her book <a href="https://leanpub.com/eventdriven/" target="_blank" rel="nofollow noopener noreferrer">Event Driven</a> and the advice it contains for running conferences.</p>
<p>Thanks to <a href="https://twitter.com/_phzn" target="_blank" rel="nofollow noopener noreferrer">Kevin Lewis</a> and <a href="https://twitter.com/rachelnabors" target="_blank" rel="nofollow noopener noreferrer">Rachel Nabors</a> for sharing their experience running Women of React Conf.</p>
<p>Thanks to <a href="https://twitter.com/aakansha1216" target="_blank" rel="nofollow noopener noreferrer">Aakansha Doshi</a>, <a href="https://twitter.com/laurieontech" target="_blank" rel="nofollow noopener noreferrer">Laurie Barth</a>, <a href="https://twitter.com/chantastic" target="_blank" rel="nofollow noopener noreferrer">Michael Chan</a>, and <a href="https://twitter.com/shaundai" target="_blank" rel="nofollow noopener noreferrer">Shaundai Person</a> for their advice and ideas throughout planning.</p>
<p>Thanks to <a href="https://twitter.com/lebo" target="_blank" rel="nofollow noopener noreferrer">Dan Lebowitz</a> for help designing and building the conference website and tickets.</p>
<p>Thanks to Laura Podolak Waddell, Desmond Osei-Acheampong, Mark Rossi, Josh Toberman and others on the Facebook Video Productions team for recording the videos for the Keynote and Meta employee talks.</p>
<p>Thanks to our partner HitPlay for helping to organize the conference, editing all the videos in the stream, translating all the talks, and moderating the Discord in multiple languages.</p>
<p>Finally, thanks to all of our participants for making this a great React Conf!</p>]]></description><link>https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html</link><guid isPermaLink="false">https://reactjs.org/blog/2021/12/17/react-conf-2021-recap.html</guid><pubDate>Fri, 17 Dec 2021 00:00:00 GMT</pubDate></item><item><title><![CDATA[The Plan for React 18]]></title><description><![CDATA[<blockquote>
<p>Update Nov. 15th, 2021</p>
<p>React 18 is now in beta. More information about the status of the release is <a href="https://github.com/reactwg/react-18/discussions/112" target="_blank" rel="nofollow noopener noreferrer">available in the React 18 Working Group post</a>.</p>
</blockquote>
<p>The React team is excited to share a few updates:</p>
<ol>
<li>We’ve started work on the React 18 release, which will be our next major version.</li>
<li>We’ve created a Working Group to prepare the community for gradual adoption of new features in React 18.</li>
<li>We’ve published a React 18 Alpha so that library authors can try it and provide feedback.</li>
</ol>
<p>These updates are primarily aimed at maintainers of third-party libraries. If you’re learning, teaching, or using React to build user-facing applications, you can safely ignore this post. But you are welcome to follow the discussions in the React 18 Working Group if you’re curious!</p>
<h2 id="whats-coming-in-react-18"><a href="#whats-coming-in-react-18" 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 coming in React 18 </h2>
<p>When it’s released, React 18 will include out-of-the-box improvements (like <a href="https://github.com/reactwg/react-18/discussions/21" target="_blank" rel="nofollow noopener noreferrer">automatic batching</a>), new APIs (like <a href="https://github.com/reactwg/react-18/discussions/41" target="_blank" rel="nofollow noopener noreferrer"><code class="gatsby-code-text">startTransition</code></a>), and a <a href="https://github.com/reactwg/react-18/discussions/37" target="_blank" rel="nofollow noopener noreferrer">new streaming server renderer</a> with built-in support for <code class="gatsby-code-text">React.lazy</code>.</p>
<p>These features are possible thanks to a new opt-in mechanism we’re adding in React 18. It’s called “concurrent rendering” and it lets React prepare multiple versions of the UI at the same time. This change is mostly behind-the-scenes, but it unlocks new possibilities to improve both real and perceived performance of your app.</p>
<p>If you’ve been following our research into the future of React (we don’t expect you to!), you might have heard of something called “concurrent mode” or that it might break your app. In response to this feedback from the community, we’ve redesigned the upgrade strategy for gradual adoption. Instead of an all-or-nothing “mode”, concurrent rendering will only be enabled for updates triggered by one of the new features. In practice, this means <strong>you will be able to adopt React 18 without rewrites and try the new features at your own pace.</strong></p>
<h2 id="a-gradual-adoption-strategy"><a href="#a-gradual-adoption-strategy" 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 gradual adoption strategy </h2>
<p>Since concurrency in React 18 is opt-in, there are no significant out-of-the-box breaking changes to component behavior. <strong>You can upgrade to React 18 with minimal or no changes to your application code, with a level of effort comparable to a typical major React release</strong>. Based on our experience converting several apps to React 18, we expect that many users will be able to upgrade within a single afternoon.</p>
<p>We successfully shipped concurrent features to tens of thousands of components at Facebook, and in our experience, we’ve found that most React components “just work” without additional changes. We’re committed to making sure this is a smooth upgrade for the entire community, so today we’re announcing the React 18 Working Group.</p>
<h2 id="working-with-the-community"><a href="#working-with-the-community" 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>Working with the community </h2>
<p>We’re trying something new for this release: We’ve invited a panel of experts, developers, library authors, and educators from across the React community to participate in our <a href="https://github.com/reactwg/react-18" target="_blank" rel="nofollow noopener noreferrer">React 18 Working Group</a> to provide feedback, ask questions, and collaborate on the release. We couldn’t invite everyone we wanted to this initial, small group, but if this experiment works out, we hope there will be more in the future!</p>
<p><strong>The goal of the React 18 Working Group is to prepare the ecosystem for a smooth, gradual adoption of React 18 by existing applications and libraries.</strong> The Working Group is hosted on <a href="https://github.com/reactwg/react-18/discussions" target="_blank" rel="nofollow noopener noreferrer">GitHub Discussions</a> and is available for the public to read. Members of the working group can leave feedback, ask questions, and share ideas. The core team will also use the discussions repo to share our research findings. As the stable release gets closer, any important information will also be posted on this blog.</p>
<p>For more information on upgrading to React 18, or additional resources about the release, see the <a href="https://github.com/reactwg/react-18/discussions/4" target="_blank" rel="nofollow noopener noreferrer">React 18 announcement post</a>.</p>
<h2 id="accessing-the-react-18-working-group"><a href="#accessing-the-react-18-working-group" 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>Accessing the React 18 Working Group </h2>
<p>Everyone can read the discussions in the <a href="https://github.com/reactwg/react-18" target="_blank" rel="nofollow noopener noreferrer">React 18 Working Group repo</a>.</p>
<p>Because we expect an initial surge of interest in the Working Group, only invited members will be allowed to create or comment on threads. However, the threads are fully visible to the public, so everyone has access to the same information. We believe this is a good compromise between creating a productive environment for working group members, while maintaining transparency with the wider community.</p>
<p>As always, you can submit bug reports, questions, and general feedback to our <a href="https://github.com/facebook/react/issues" target="_blank" rel="nofollow noopener noreferrer">issue tracker</a>.</p>
<h2 id="how-to-try-react-18-alpha-today"><a href="#how-to-try-react-18-alpha-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>How to try React 18 Alpha today </h2>
<p>New alphas are <a href="https://github.com/reactwg/react-18/discussions/9" target="_blank" rel="nofollow noopener noreferrer">regularly published to npm using the <code class="gatsby-code-text">@alpha</code> tag</a>. These releases are built using the most recent commit to our main repo. When a feature or bugfix is merged, it will appear in an alpha the following weekday.</p>
<p>There may be significant behavioral or API changes between alpha releases. Please remember that <strong>alpha releases are not recommended for user-facing, production applications</strong>.</p>
<h2 id="projected-react-18-release-timeline"><a href="#projected-react-18-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>Projected React 18 release timeline </h2>
<p>We don’t have a specific release date scheduled, but we expect it will take several months of feedback and iteration before React 18 is ready for most production applications.</p>
<ul>
<li>Library Alpha: Available today</li>
<li>Public Beta: At least several months</li>
<li>Release Candidate (RC): At least several weeks after Beta</li>
<li>General Availability: At least several weeks after RC</li>
</ul>
<p>More details about our projected release timeline are <a href="https://github.com/reactwg/react-18/discussions/9" target="_blank" rel="nofollow noopener noreferrer">available in the Working Group</a>. We’ll post updates on this blog when we’re closer to a public release.</p>]]></description><link>https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html</link><guid isPermaLink="false">https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html</guid><pubDate>Tue, 08 Jun 2021 00:00:00 GMT</pubDate></item><item><title><![CDATA[Introducing Zero-Bundle-Size React Server Components]]></title><description><![CDATA[<p>2020 has been a long year. As it comes to an end we wanted to share a special Holiday Update on our research into zero-bundle-size <strong>React Server Components</strong>.</p>
<p>To introduce React Server Components, we have prepared a talk and a demo. If you want, you can check them out during the holidays, or later when work picks back up in the new year.</p>
<br>
<div class="gatsby-resp-iframe-wrapper" style="padding-bottom: 56.25%; position: relative; height: 0; overflow: hidden; " > <iframe src="https://www.youtube.com/embed/TQQPAU21ZUw" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen style=" position: absolute; top: 0; left: 0; width: 100%; height: 100%; "></iframe> </div>
<p><strong>React Server Components are still in research and development.</strong> We are sharing this work in the spirit of transparency and to get initial feedback from the React community. There will be plenty of time for that, so <strong>don’t feel like you have to catch up right now!</strong></p>
<p>If you want to check them out, we recommend to go in the following order:</p>
<ol>
<li><strong>Watch the talk</strong> to learn about React Server Components and see the demo.</li>
<li><strong><a href="http://github.com/reactjs/server-components-demo" target="_blank" rel="nofollow noopener noreferrer">Clone the demo</a></strong> to play with React Server Components on your computer.</li>
<li><strong><a href="https://github.com/reactjs/rfcs/pull/188" target="_blank" rel="nofollow noopener noreferrer">Read the RFC (with FAQ at the end)</a></strong> for a deeper technical breakdown and to provide feedback.</li>
</ol>
<p>We are excited to hear from you on the RFC or in replies to the <a href="https://twitter.com/reactjs" target="_blank" rel="nofollow noopener noreferrer">@reactjs</a> Twitter handle. Happy holidays, stay safe, and see you next year!</p>]]></description><link>https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html</link><guid isPermaLink="false">https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html</guid><pubDate>Mon, 21 Dec 2020 00:00:00 GMT</pubDate></item><item><title><![CDATA[React v17.0]]></title><description><![CDATA[<p>Today, we are releasing React 17! We’ve written at length about the role of the React 17 release and the changes it contains in <a href="/blog/2020/08/10/react-v17-rc.html">the React 17 RC blog post</a>. This post is a brief summary of it, so if you’ve already read the RC post, you can skip this one.</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>In particular, React 17 is a “stepping stone” release that makes it safer to embed a tree managed by one version of React inside a tree managed by a different version of React.</p>
<p>It also makes it easier to embed React into apps built with other technologies.</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><strong>React 17 enables gradual React upgrades.</strong> When you upgrade from React 15 to 16 (or, this time, 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. <strong>For most apps, upgrading all at once is still the best solution.</strong> 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 makes sense to consider, and React 17 lets those apps not get left behind.</p>
<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>To enable gradual updates, we’ve needed to make some changes to the React event system. React 17 is a major release because these changes are potentially breaking. You can check out our <a href="/docs/faq-versioning.html#breaking-changes">versioning FAQ</a> to learn more about our commitment to stability.</p>
<p>In React 17, React will no longer attach event handlers at the <code class="gatsby-code-text">document</code> level under the hood. Instead, it will attach them to the root DOM container into which your React tree is rendered:</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>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>
<p>If you run into issues with this change, <a href="/blog/2020/08/10/react-v17-rc.html#fixing-potential-issues">here’s a common way to resolve them</a>.</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><a href="/blog/2020/08/10/react-v17-rc.html#other-breaking-changes">The React 17 RC blog post</a> describes the rest of the breaking changes in React 17.</p>
<p>We’ve only had to change fewer than twenty components out of 100,000+ in the Facebook product code to work with these changes, so <strong>we expect that most apps can upgrade to React 17 without too much trouble</strong>. Please <a href="https://github.com/facebook/react/issues" target="_blank" rel="nofollow noopener noreferrer">tell us</a> if you run into problems.</p>
<h2 id="new-jsx-transform"><a href="#new-jsx-transform" 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 JSX Transform </h2>
<p>React 17 supports the <a href="/blog/2020/09/22/introducing-the-new-jsx-transform.html">new JSX transform</a>. We’ve also backported support for it to React 16.14.0, React 15.7.0, and 0.14.10. Note that it is completely opt-in, and you don’t have to use it. The classic JSX transform will keep working, and there are no plans to stop supporting it.</p>
<h2 id="react-native"><a href="#react-native" 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 Native </h2>
<p>React Native has a separate release schedule. We landed the support for React 17 in React Native 0.64. As always, you can track the release discussions on the React Native Community releases <a href="https://github.com/react-native-community/releases" 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>
<p>To install React 17 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 react-dom@17.0.0</code></pre></div>
<p>To install React 17 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 react-dom@17.0.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@17.0.0/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/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/10/20/react-v17.html</link><guid isPermaLink="false">https://reactjs.org/blog/2020/10/20/react-v17.html</guid><pubDate>Tue, 20 Oct 2020 00:00:00 GMT</pubDate></item><item><title><![CDATA[Introducing the New JSX Transform]]></title><description><![CDATA[<p>Although React 17 <a href="/blog/2020/08/10/react-v17-rc.html">doesn’t contain new features</a>, it will provide support for a new version of the JSX transform. In this post, we will describe what it is and how to try it.</p>
<h2 id="whats-a-jsx-transform"><a href="#whats-a-jsx-transform" 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 a JSX Transform? </h2>
<p>Browsers don’t understand JSX out of the box, so most React users rely on a compiler like Babel or TypeScript to <strong>transform JSX code into regular JavaScript</strong>. Many preconfigured toolkits like Create React App or Next.js also include a JSX transform under the hood.</p>
<p>Together with the React 17 release, we’ve wanted to make a few improvements to the JSX transform, but we didn’t want to break existing setups. This is why we <a href="https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154httpsgithubcombabelbabelpull11154" target="_blank" rel="nofollow noopener noreferrer">worked with Babel</a> to <strong>offer a new, rewritten version of the JSX transform</strong> for people who would like to upgrade.</p>
<p>Upgrading to the new transform is completely optional, but it has a few benefits:</p>
<ul>
<li>With the new transform, you can <strong>use JSX without importing React</strong>.</li>
<li>Depending on your setup, its compiled output may <strong>slightly improve the bundle size</strong>.</li>
<li>It will enable future improvements that <strong>reduce the number of concepts</strong> you need to learn React.</li>
</ul>
<p><strong>This upgrade will not change the JSX syntax and is not required.</strong> The old JSX transform will keep working as usual, and there are no plans to remove the support for it.</p>
<p><a href="/blog/2020/08/10/react-v17-rc.html">React 17 RC</a> already includes support for the new transform, so go give it a try! To make it easier to adopt, <strong>we’ve also backported its support</strong> to React 16.14.0, React 15.7.0, and React 0.14.10. You can find the upgrade instructions for different tools <a href="#how-to-upgrade-to-the-new-jsx-transform">below</a>.</p>
<p>Now let’s take a closer look at the differences between the old and the new transform.</p>
<h2 id="whats-different-in-the-new-transform"><a href="#whats-different-in-the-new-transform" 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 Different in the New Transform? </h2>
<p>When you use JSX, the compiler transforms it into React function calls that the browser can understand. <strong>The old JSX transform</strong> turned JSX into <code class="gatsby-code-text">React.createElement(...)</code> calls.</p>
<p>For example, let’s say your source code looks like this:</p>
<div class="gatsby-highlight" 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">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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello World</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>
<span class="token punctuation">}</span></code></pre></div>
<p>Under the hood, the old JSX transform turns it into regular JavaScript:</p>
<div class="gatsby-highlight" 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">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> React<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">'h1'</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token string">'Hello world'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div>
<blockquote>
<p>Note</p>
<p><strong>Your source code doesn’t need to change in any way.</strong> We’re describing how the JSX transform turns your JSX source code into the JavaScript code a browser can understand.</p>
</blockquote>
<p>However, this is not perfect:</p>
<ul>
<li>Because JSX was compiled into <code class="gatsby-code-text">React.createElement</code>, <code class="gatsby-code-text">React</code> needed to be in scope if you used JSX.</li>
<li>There are some <a href="https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#motivation" target="_blank" rel="nofollow noopener noreferrer">performance improvements and simplifications</a> that <code class="gatsby-code-text">React.createElement</code> does not allow.</li>
</ul>
<p>To solve these issues, React 17 introduces two new entry points to the React package that are intended to only be used by compilers like Babel and TypeScript. Instead of transforming JSX to <code class="gatsby-code-text">React.createElement</code>, <strong>the new JSX transform</strong> automatically imports special functions from those new entry points in the React package and calls them.</p>
<p>Let’s say that your source code looks like this:</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">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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello World</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>
<span class="token punctuation">}</span></code></pre></div>
<p>This is what the new JSX transform compiles it to:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// Inserted by a compiler (don't import it yourself!)</span>
<span class="token keyword">import</span> <span class="token punctuation">{</span>jsx <span class="token keyword">as</span> _jsx<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react/jsx-runtime'</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 function">_jsx</span><span class="token punctuation">(</span><span class="token string">'h1'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">children</span><span class="token operator">:</span> <span class="token string">'Hello world'</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>Note how our original code <strong>did not need to import React</strong> to use JSX anymore! (But we would still need to import React in order to use Hooks or other exports that React provides.)</p>
<p><strong>This change is fully compatible with all of the existing JSX code</strong>, so you won’t have to change your components. If you’re curious, you can check out the <a href="https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md#detailed-design" target="_blank" rel="nofollow noopener noreferrer">technical RFC</a> for more details about how the new transform works.</p>
<blockquote>
<p>Note</p>
<p>The functions inside <code class="gatsby-code-text">react/jsx-runtime</code> and <code class="gatsby-code-text">react/jsx-dev-runtime</code> must only be used by the compiler transform. If you need to manually create elements in your code, you should keep using <code class="gatsby-code-text">React.createElement</code>. It will continue to work and is not going away.</p>
</blockquote>
<h2 id="how-to-upgrade-to-the-new-jsx-transform"><a href="#how-to-upgrade-to-the-new-jsx-transform" 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 to Upgrade to the New JSX Transform </h2>
<p>If you aren’t ready to upgrade to the new JSX transform or if you are using JSX for another library, don’t worry. The old transform will not be removed and will continue to be supported.</p>
<p>If you want to upgrade, you will need two things:</p>
<ul>
<li><strong>A version of React that supports the new transform</strong> (<a href="/blog/2020/08/10/react-v17-rc.html">React 17 RC</a> and higher supports it, but we’ve also released React 16.14.0, React 15.7.0, and React 0.14.10 for people who are still on the older major versions).</li>
<li><strong>A compatible compiler</strong> (see instructions for different tools below).</li>
</ul>
<p>Since the new JSX transform doesn’t require React to be in scope, <a href="#removing-unused-react-imports">we’ve also prepared an automated script</a> that will remove the unnecessary imports from your codebase.</p>
<h3 id="create-react-app"><a href="#create-react-app" 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>Create React App </h3>
<p>Create React App <a href="https://github.com/facebook/create-react-app/releases/tag/v4.0.0" target="_blank" rel="nofollow noopener noreferrer">4.0.0</a>+ uses the new transform for compatible React versions.</p>
<h3 id="nextjs"><a href="#nextjs" 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.js </h3>
<p>Next.js <a href="https://github.com/vercel/next.js/releases/tag/v9.5.3" target="_blank" rel="nofollow noopener noreferrer">v9.5.3</a>+ uses the new transform for compatible React versions.</p>
<h3 id="gatsby"><a href="#gatsby" 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>Gatsby </h3>
<p>Gatsby <a href="https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/CHANGELOG.md#22452-2020-08-28" target="_blank" rel="nofollow noopener noreferrer">v2.24.5</a>+ uses the new transform for compatible React versions.</p>
<blockquote>
<p>Note</p>
<p>If you get <a href="https://github.com/gatsbyjs/gatsby/issues/26979" target="_blank" rel="nofollow noopener noreferrer">this Gatsby error</a> after upgrading to React 17 RC, run <code class="gatsby-code-text">npm update</code> to fix it.</p>
</blockquote>
<h3 id="manual-babel-setup"><a href="#manual-babel-setup" 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>Manual Babel Setup </h3>
<p>Support for the new JSX transform is available in Babel <a href="https://babeljs.io/blog/2020/03/16/7.9.0" target="_blank" rel="nofollow noopener noreferrer">v7.9.0</a> and above.</p>
<p>First, you’ll need to update to the latest Babel and plugin transform.</p>
<p>If you are using <code class="gatsby-code-text">@babel/plugin-transform-react-jsx</code>:</p>
<div class="gatsby-highlight" data-language="bash"><pre class="gatsby-code-bash"><code class="gatsby-code-bash"><span class="token comment"># for npm users</span>
<span class="token function">npm</span> update @babel/core @babel/plugin-transform-react-jsx</code></pre></div>
<div class="gatsby-highlight" data-language="bash"><pre class="gatsby-code-bash"><code class="gatsby-code-bash"><span class="token comment"># for yarn users</span>
<span class="token function">yarn</span> upgrade @babel/core @babel/plugin-transform-react-jsx</code></pre></div>
<p>If you are using <code class="gatsby-code-text">@babel/preset-react</code>:</p>
<div class="gatsby-highlight" data-language="bash"><pre class="gatsby-code-bash"><code class="gatsby-code-bash"><span class="token comment"># for npm users</span>
<span class="token function">npm</span> update @babel/core @babel/preset-react</code></pre></div>
<div class="gatsby-highlight" data-language="bash"><pre class="gatsby-code-bash"><code class="gatsby-code-bash"><span class="token comment"># for yarn users</span>
<span class="token function">yarn</span> upgrade @babel/core @babel/preset-react</code></pre></div>
<p>Currently, the old transform <code class="gatsby-code-text">{"runtime": "classic"}</code> is the default option. To enable the new transform, you can pass <code class="gatsby-code-text">{"runtime": "automatic"}</code> as an option to <code class="gatsby-code-text">@babel/plugin-transform-react-jsx</code> or <code class="gatsby-code-text">@babel/preset-react</code>:</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// If you are using @babel/preset-react</span>
<span class="token punctuation">{</span>
  <span class="token string-property property">"presets"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
    <span class="token punctuation">[</span><span class="token string">"@babel/preset-react"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
      <span class="token string-property property">"runtime"</span><span class="token operator">:</span> <span class="token string">"automatic"</span>
    <span class="token punctuation">}</span><span class="token punctuation">]</span>
  <span class="token punctuation">]</span>
<span class="token punctuation">}</span></code></pre></div>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token comment">// If you're using @babel/plugin-transform-react-jsx</span>
<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 punctuation">[</span><span class="token string">"@babel/plugin-transform-react-jsx"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
      <span class="token string-property property">"runtime"</span><span class="token operator">:</span> <span class="token string">"automatic"</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>Starting from Babel 8, <code class="gatsby-code-text">"automatic"</code> will be the default runtime for both plugins. For more information, check out the Babel documentation for <a href="https://babeljs.io/docs/en/babel-plugin-transform-react-jsx" target="_blank" rel="nofollow noopener noreferrer">@babel/plugin-transform-react-jsx</a> and <a href="https://babeljs.io/docs/en/babel-preset-react" target="_blank" rel="nofollow noopener noreferrer">@babel/preset-react</a>.</p>
<blockquote>
<p>Note</p>
<p>If you use JSX with a library other than React, you can use <a href="https://babeljs.io/docs/en/babel-preset-react#importsource" target="_blank" rel="nofollow noopener noreferrer">the <code class="gatsby-code-text">importSource</code> option</a> to import from that library instead — as long as it provides the necessary entry points. Alternatively, you can keep using the classic transform which will continue to be supported.</p>
<p>If you’re a library author and you are implementing the <code class="gatsby-code-text">/jsx-runtime</code> entry point for your library, keep in mind that <a href="https://github.com/facebook/react/issues/20031#issuecomment-710346866" target="_blank" rel="nofollow noopener noreferrer">there is a case</a> in which even the new transform has to fall back to <code class="gatsby-code-text">createElement</code> for backwards compatibility. In that case, it will auto-import <code class="gatsby-code-text">createElement</code> directly from the <em>root</em> entry point specified by <code class="gatsby-code-text">importSource</code>.</p>
</blockquote>
<h3 id="eslint"><a href="#eslint" 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 </h3>
<p>If you are using <a href="https://github.com/yannickcr/eslint-plugin-react" target="_blank" rel="nofollow noopener noreferrer">eslint-plugin-react</a>, the <code class="gatsby-code-text">react/jsx-uses-react</code> and <code class="gatsby-code-text">react/react-in-jsx-scope</code> rules are no longer necessary and can be turned off or removed.</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 comment">// ...</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/jsx-uses-react"</span><span class="token operator">:</span> <span class="token string">"off"</span><span class="token punctuation">,</span>
    <span class="token string-property property">"react/react-in-jsx-scope"</span><span class="token operator">:</span> <span class="token string">"off"</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre></div>
<h3 id="typescript"><a href="#typescript" 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>TypeScript </h3>
<p>TypeScript supports the new JSX transform in <a href="https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#jsx-factories" target="_blank" rel="nofollow noopener noreferrer">v4.1</a> and up.</p>
<h3 id="flow"><a href="#flow" 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>Flow </h3>
<p>Flow supports the new JSX transform in <a href="https://github.com/facebook/flow/releases/tag/v0.126.0" target="_blank" rel="nofollow noopener noreferrer">v0.126.0</a> and up, by adding <code class="gatsby-code-text">react.runtime=automatic</code> to your Flow configuration options. </p>
<h2 id="removing-unused-react-imports"><a href="#removing-unused-react-imports" 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 Unused React Imports </h2>
<p>Because the new JSX transform will automatically import the necessary <code class="gatsby-code-text">react/jsx-runtime</code> functions, React will no longer need to be in scope when you use JSX. This might lead to unused React imports in your code. It doesn’t hurt to keep them, but if you’d like to remove them, we recommend running a <a href="https://medium.com/@cpojer/effective-javascript-codemods-5a6686bb46fb" target="_blank" rel="nofollow noopener noreferrer">“codemod”</a> script to remove 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 update-react-imports</code></pre></div>
<blockquote>
<p>Note</p>
<p>If you’re getting errors when running the codemod, try specifying a different JavaScript dialect when <code class="gatsby-code-text">npx react-codemod update-react-imports</code> asks you to choose one. In particular, at this moment the “JavaScript with Flow” setting supports newer syntax than the “JavaScript” setting even if you don’t use Flow. <a href="https://github.com/reactjs/react-codemod/issues" target="_blank" rel="nofollow noopener noreferrer">File an issue</a> if you run into problems.</p>
<p>Keep in mind that the codemod output will not always match your project’s coding style, so you might want to run <a href="https://prettier.io/" target="_blank" rel="nofollow noopener noreferrer">Prettier</a> after the codemod finishes for consistent formatting.</p>
</blockquote>
<p>Running this codemod will:</p>
<ul>
<li>Remove all unused React imports as a result of upgrading to the new JSX transform.</li>
<li>Change all default React imports (i.e. <code class="gatsby-code-text">import React from "react"</code>) to destructured named imports (ex. <code class="gatsby-code-text">import { useState } from "react"</code>) which is the preferred style going into the future. This codemod <strong>will not</strong> affect the existing namespace imports (i.e. <code class="gatsby-code-text">import * as React from "react"</code>) which is also a valid style. The default imports will keep working in React 17, but in the longer term we encourage moving away from them.</li>
</ul>
<p>For example,</p>
<div class="gatsby-highlight" 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">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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello World</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>
<span class="token punctuation">}</span></code></pre></div>
<p>will be replaced with</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">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 tag"><span class="token tag"><span class="token punctuation">&lt;</span>h1</span><span class="token punctuation">></span></span><span class="token plain-text">Hello World</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>
<span class="token punctuation">}</span></code></pre></div>
<p>If you use some other import from React — for example, a Hook — then the codemod will convert it to a named import.</p>
<p>For example,</p>
<div class="gatsby-highlight" 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">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">const</span> <span class="token punctuation">[</span>text<span class="token punctuation">,</span> setText<span class="token punctuation">]</span> <span class="token operator">=</span> React<span class="token punctuation">.</span><span class="token function">useState</span><span class="token punctuation">(</span><span class="token string">'Hello World'</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>h1</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>text<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 punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div>
<p>will be replaced with</p>
<div class="gatsby-highlight" data-language="jsx"><pre class="gatsby-code-jsx"><code class="gatsby-code-jsx"><span class="token keyword">import</span> <span class="token punctuation">{</span> useState <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react'</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">const</span> <span class="token punctuation">[</span>text<span class="token punctuation">,</span> setText<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token function">useState</span><span class="token punctuation">(</span><span class="token string">'Hello World'</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>h1</span><span class="token punctuation">></span></span><span class="token punctuation">{</span>text<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 punctuation">;</span>
<span class="token punctuation">}</span></code></pre></div>
<p>In addition to cleaning up unused imports, this will also help you prepare for a future major version of React (not React 17) which will support ES Modules and not have a default export.</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 Babel, TypeScript, Create React App, Next.js, Gatsby, ESLint, and Flow maintainers for their help implementing and integrating the new JSX transform. We also want to thank the React community for their feedback and discussion on the related <a href="https://github.com/reactjs/rfcs/pull/107" target="_blank" rel="nofollow noopener noreferrer">technical RFC</a>.</p>]]></description><link>https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html</link><guid isPermaLink="false">https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html</guid><pubDate>Tue, 22 Sep 2020 00:00:00 GMT</pubDate></item><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></channel></rss>