<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://reactnative.dev/blog</id>
    <title>React Native Blog</title>
    <updated>2023-01-12T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://reactnative.dev/blog"/>
    <subtitle>React Native Blog</subtitle>
    <icon>https://reactnative.dev/img/favicon.ico</icon>
    <rights>Copyright © 2023 Meta Platforms, Inc.</rights>
    <entry>
        <title type="html"><![CDATA[React Native 0.71: TypeScript by Default, Flexbox Gap, and more...]]></title>
        <id>/2023/01/12/version-071</id>
        <link href="https://reactnative.dev/blog/2023/01/12/version-071"/>
        <updated>2023-01-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we’re releasing React Native version 0.71! This is a feature-packed release including:]]></summary>
        <content type="html"><![CDATA[<p>Today we’re releasing React Native version 0.71! This is a feature-packed release including:</p><ul><li><a href="/blog/2023/01/12/version-071#typescript-by-default">TypeScript by default</a></li><li><a href="/blog/2023/01/12/version-071#simplifying-layouts-with-flexbox-gap">Simplifying layouts with Flexbox Gap</a></li><li><a href="/blog/2023/01/12/version-071#web-inspired-props-for-accessibility-styles-and-events">Web-inspired props for accessibility, styles, and events</a></li><li><a href="/blog/2023/01/12/version-071#restoring-proptypes">Restoring PropTypes</a></li><li><a href="/blog/2023/01/12/version-071#developer-experience-improvements">Developer Experience Improvements</a></li><li><a href="/blog/2023/01/12/version-071#new-architecture">New Architecture Updates</a></li></ul><p>In this post we’ll cover some of the highlights of 0.71.</p><div class="theme-admonition theme-admonition-info alert alert--info admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_yySL"><p>For a full list of changes, check out <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v071" target="_blank" rel="noopener noreferrer">CHANGELOG.md</a>.</p></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="typescript-by-default">TypeScript by default<a class="hash-link" href="#typescript-by-default" title="Direct link to heading">​</a></h2><p>In this release, we’re investing in the TypeScript experience of React Native.</p><p>Starting with 0.71, when you create a new React Native app via the React Native CLI you'll get a TypeScript app by default. The new project is already set up with a <code>tsconfig.json</code> so out of the box your IDE will help you write typed code right away.</p><p>We’re also offering built-in, more accurate TypeScript declarations directly from the <code>react-native</code> package. This means you won’t need <code>@types/react-native</code> any longer, and the types will be updated in lockstep with React Native releases.</p><p>Finally, our documentation has been updated to feature TypeScript for all examples.</p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_yySL"><p>After upgrading to React Native 0.71, we recommend removing <code>@types/react-native</code> from your package.json <code>devDependencies</code>.</p></div></div><p>For more details on this change, including migration steps and how this affects Flow users, check out our previous post <a href="https://reactnative.dev/blog/2023/01/03/typescript-first" target="_blank" rel="noopener noreferrer">First-class Support for TypeScript</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="simplifying-layouts-with-flexbox-gap">Simplifying layouts with Flexbox gap<a class="hash-link" href="#simplifying-layouts-with-flexbox-gap" title="Direct link to heading">​</a></h2><p>With React Native you can flexibly layout components on different screen sizes using Flexbox. Browsers have supported the Flexbox properties <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/gap" target="_blank" rel="noopener noreferrer">gap</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap" target="_blank" rel="noopener noreferrer">rowGap</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/column-gap" target="_blank" rel="noopener noreferrer">columnGap</a>, which allow you to specify the amount of space between all items in a Flexbox.</p><p>These properties have been long requested in React Native, and 0.71 adds initial support for gaps defined using pixel values. In future versions, we will add support for more values, such as percentages.</p><p>To see why this is useful, imagine trying to build a responsive layout with variably sized cards, 10px apart from each other, hugging the edges of the parent container. Trying to accomplish this layout with child margins can be tricky.</p><p>The following shows a layout where we start by giving each child <code>margin: 10</code> style:</p><p><img loading="lazy" alt="Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin around them cause the boxes to have margin around all sides. On the right, the same diagram is shown highlighted to demonstrate the margin on all sides." src="/assets/images/FlexboxGapBefore-1f7eddd7d1d7b84cc7c0e1c5a53c8144.png" width="679" height="201" class="img_SS3x"></p><p>Margins are applied uniformly to the edges of all children and don’t collapse under Flexbox, giving us spacing at the exterior of the cards, and double the space on the interior compared to what we wanted. We can get around this by applying non-uniform margins, using negative margins on the parent, halving our intended spacing, etc, but it can be made much easier.</p><p>With flex gap, this layout can be achieved by setting <code>gap: 10</code> on the container for a 10 pixel gap between the interior of the cards:</p><p><img loading="lazy" alt="Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin only on the inner sides and not the outer sides of the boxes due to the Flexbox gap property. On the right, the same diagram is shown highlighted to demonstrate the margin only on the inner sides." src="/assets/images/FlexboxGapAfter-4dd42d529a3e531d81da25361f8975ed.png" width="679" height="201" class="img_SS3x"></p><p>For more information on Flexbox gaps, see <a href="https://css-tricks.com/minding-the-gap/#aa-flexbox-gaps" target="_blank" rel="noopener noreferrer">this blogpost from CSS Tricks</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="web-inspired-props-for-accessibility-styles-and-events">Web-inspired props for accessibility, styles, and events<a class="hash-link" href="#web-inspired-props-for-accessibility-styles-and-events" title="Direct link to heading">​</a></h2><p>This release includes a number of new props inspired by web standards to align React Native’s APIs across many platforms. These new props are purely additive so there are no expected migrations or change of behavior for equivalent accessibility, behavior, or style props.</p><p>For any new prop alias introduced, if there is an existing prop with a different name and both are specified, the new alias prop value will take precedence. For example, this release adds a <code>src</code> prop alias for <code>source</code> on the Image component to align with the <code>src</code> prop on web. If both <code>src</code> and <code>source</code> are provided, the new <code>src</code> prop will be used.</p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_yySL"><p>For more background on aligning React Native to web standards, check out this <a href="https://github.com/necolas/discussions-and-proposals/blob/reduce-fragmentation/proposals/0000-reduce-fragmentation.md" target="_blank" rel="noopener noreferrer">proposal</a> and <a href="https://github.com/react-native-community/discussions-and-proposals/pull/496" target="_blank" rel="noopener noreferrer">related discussion</a>.</p></div></div><h4 class="anchor anchorWithStickyNavbar_JmGV" id="accessibility">Accessibility<a class="hash-link" href="#accessibility" title="Direct link to heading">​</a></h4><p>We introduced ARIA props as alias to existing React Native accessibility props.</p><p>These props now exist on all core components of React Native:<code>aria-label</code>, <code>aria-labelledby</code>,<code>aria-modal</code>, <code>id</code>, <code>aria-busy</code>, <code>aria-checked</code>, <code>aria-disabled</code>, <code>aria-expanded</code>, <code>aria-selected</code>, <code>aria-valuemax</code>, <code>aria-valuemin</code>, <code>aria-valuenow</code>, and <code>aria-valuetext</code>.</p><p>We also introduced equivalent web behavior for: <code>aria-hidden</code>, <code>aria-live</code>, <code>role</code>, and <code>tabIndex</code>.</p><p>See this <a href="https://github.com/facebook/react-native/issues/34424" target="_blank" rel="noopener noreferrer">issue</a> for more details.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="component-specific-behavior">Component-Specific Behavior<a class="hash-link" href="#component-specific-behavior" title="Direct link to heading">​</a></h4><p>There were also props introduced to align prop names with equivalent DOM prop names for core components.</p><ul><li><strong>Image</strong>: <code>alt</code>, <code>tintColor</code>, <code>crossOrigin</code>, <code>height</code>, <code>referrerPolicy</code>, <code>src</code>, <code>srcSet</code>, and <code>width</code>.</li><li><strong>TextInput</strong>: <code>autoComplete</code>, <code>enterKeyHint</code>, <code>inputMode</code>, <code>readOnly</code>, and <code>rows</code>.</li></ul><p>See this <a href="https://github.com/facebook/react-native/issues/34424" target="_blank" rel="noopener noreferrer">issue</a> for more details.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="styles">Styles<a class="hash-link" href="#styles" title="Direct link to heading">​</a></h4><p>To align with certain CSS styles, there have been feature extensions for the following styles:</p><ul><li><a href="https://reactnative.dev/docs/layout-props#aspectratio" target="_blank" rel="noopener noreferrer"><code>aspectRatio</code></a> now supports string values</li><li><a href="https://reactnative.dev/docs/text-style-props#fontvariant" target="_blank" rel="noopener noreferrer"><code>fontVariant</code></a> now supports space-separated string values</li><li><a href="https://reactnative.dev/docs/text-style-props#fontWeight" target="_blank" rel="noopener noreferrer"><code>fontWeight</code></a> now supports number values</li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform" target="_blank" rel="noopener noreferrer"><code>transform</code></a> now supports string values</li></ul><p>The following aliases have been added to shadow existing React Native styles:</p><ul><li><a href="https://reactnative.dev/docs/image#objectfit" target="_blank" rel="noopener noreferrer"><code>objectFit</code></a></li><li><a href="https://reactnative.dev/docs/view-style-props#pointerevents" target="_blank" rel="noopener noreferrer"><code>pointerEvents</code></a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/user-select" target="_blank" rel="noopener noreferrer"><code>userSelect</code></a></li><li><a href="https://reactnative.dev/docs/text-style-props#verticalalign-android" target="_blank" rel="noopener noreferrer"><code>verticalAlign</code></a></li></ul><p>See this <a href="https://github.com/facebook/react-native/issues/34425" target="_blank" rel="noopener noreferrer">issue</a> for more details.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="events">Events<a class="hash-link" href="#events" title="Direct link to heading">​</a></h4><p>Finally, we also added an opt-in implementation of <a href="https://w3c.github.io/pointerevents" target="_blank" rel="noopener noreferrer">PointerEvents</a></p><p>Once enabled, the following handlers on <code>View</code> will support hover:</p><ul><li><code>onPointerOver</code>, <code>onPointerOut</code></li><li><code>onPointerEnter</code>, <code>onPointerLeave</code></li></ul><p>These events are also implemented in <code>Pressability</code> for new opt-in support for hover.</p><p>To enable these features, set the following flags to true:</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">ReactNativeFeatureFlags</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native/Libraries/ReactNative/ReactNativeFeatureFlags'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// enable the JS-side of the w3c PointerEvent implementation</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">ReactNativeFeatureFlags</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method-variable function-variable method function property-access" style="color:#79b6f2">shouldEmitW3CPointerEvents</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// enable hover events in Pressibility to be backed by the PointerEvent implementation.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// shouldEmitW3CPointerEvents should also be true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">ReactNativeFeatureFlags</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method-variable function-variable method function property-access" style="color:#79b6f2">shouldPressibilityUseW3CPointerEventsForHover</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_yySL"><p>You’ll also need to enable React feature flags on your <a href="https://reactnative.dev/blog/2022/12/13/pointer-events-in-react-native#android-specific" target="_blank" rel="noopener noreferrer">Android</a> and <a href="https://reactnative.dev/blog/2022/12/13/pointer-events-in-react-native#ios-specific" target="_blank" rel="noopener noreferrer">iOS</a> native setup.</p></div></div><p>Check out our dedicated <a href="https://reactnative.dev/blog/2022/12/13/pointer-events-in-react-native" target="_blank" rel="noopener noreferrer">PointerEvents post</a> to learn more.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="restoring-proptypes">Restoring PropTypes<a class="hash-link" href="#restoring-proptypes" title="Direct link to heading">​</a></h2><p>React Native’s prop types, such as <code>ViewPropTypes</code> and <code>Text.propTypes</code>, were deprecated in 0.66 and accessing them would output deprecation warnings. When they were removed in 0.68, many developers began experiencing errors when upgrading to the latest version of React Native.</p><p>After some investigation, we realized that a couple issues prevented the community from taking action on the deprecation warnings. First, the deprecation warning was not always actionable which caused people to ignore them (<a href="https://github.com/facebook/react-native/pull/34650" target="_blank" rel="noopener noreferrer">issue one</a>, <a href="https://github.com/react-native-community/cli/pull/1699" target="_blank" rel="noopener noreferrer">issue two</a>). Second, the deprecation warnings were being <a href="https://github.com/facebook/react-native/commit/fa2842d" target="_blank" rel="noopener noreferrer">incorrectly filtered</a> by <code>LogBox.ignoreLogs</code>. Both of these have now been fixed, but we want to give people more time to upgrade the deprecated call sites.</p><p>So in this release we are adding back React Native’s propTypes so that it is easier for people to upgrade and migrate their code to avoid using them. The <code>deprecated-react-native-prop-types</code> package has also been updated for all of the props in 0.71. In the future, we plan to proceed with the deprecation and remove prop types once again. We expect that when we revisit the removal, the community will experience significantly fewer issues.</p><div class="theme-admonition theme-admonition-caution alert alert--warning admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_yySL"><p>As part of this change, we are also removing the console filtering from <code>LogBox.ignoreLog</code>. This means logs that you have previously filtered with <code>Logbox.ignoreLog</code> will start appearing again in the console when you upgrade.</p><p>This is expected, because it allows logs such as deprecation warnings to be found and fixed.</p></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="developer-experience-improvements">Developer Experience Improvements<a class="hash-link" href="#developer-experience-improvements" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_JmGV" id="react-devtools">React DevTools<a class="hash-link" href="#react-devtools" title="Direct link to heading">​</a></h3><p>In this release, we've brought two popular React DevTools features on web to React Native.</p><p>"Click to inspect" is the option in the top left corner of React Dev Tools that allows you to click on an item in the app to inspect it in Dev Tools, similar to the Chrome element inspector.</p><p>Component highlighting will highlight the element you select in DevTools in the app so you can see which React components line up with which on-screen elements.</p><p>Here are both features in action:</p><p><img loading="lazy" alt="Video of the behavior described above in action. On the left is a React Native app running in an iPhone simulator. On the right is the React DevTools. In both workflows, clicking on an item in the DevTools highlights the corresponding components in the app." src="/assets/images/ElementInspecting-e5670278b9a3562ca492742318251950.gif" width="946" height="608" class="img_SS3x"></p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="hermes">Hermes<a class="hash-link" href="#hermes" title="Direct link to heading">​</a></h3><p>In React Native 0.70, we made <a href="https://reactnative.dev/blog/2022/07/08/hermes-as-the-default" target="_blank" rel="noopener noreferrer">Hermes the default engine for React Native</a>.</p><p>In React Native 0.71, we’re upgrading Hermes with a few notable improvements:</p><ul><li><strong>Improve source maps</strong>: By loading source maps over the network with Metro we’ve restored the ability to use source maps in recent versions of Chrome Dev Tools outside of Flipper.</li><li><strong>Improve <code>JSON.parse</code> performance</strong>: This version includes a performance optimization that improves the performance of <code>JSON.parse</code> up to 30%.</li><li><strong>Add support for <code>.at()</code></strong>: Hermes now <a href="https://github.com/facebook/hermes/issues/823" target="_blank" rel="noopener noreferrer">supports</a><code>.at()</code> for <code>String</code>, <code>TypedArray</code>, and <code>Array</code>.</li></ul><p>For a full list of changes see <a href="https://github.com/reactwg/react-native-releases/discussions/41#discussioncomment-4089256" target="_blank" rel="noopener noreferrer">the Road to 71 issue</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="new-architecture">New Architecture<a class="hash-link" href="#new-architecture" title="Direct link to heading">​</a></h3><p>This release brings many improvements to the experimental New Architecture experience based on user feedback and reports we collected so far.</p><ul><li><strong>Reduced build times</strong>: The new distribution model uses Maven Central, which allows us to greatly reduce the build time on Android, resolves many build problems on Windows, and provides a more seamless experience with the New Architecture. <a href="https://github.com/reactwg/react-native-new-architecture/discussions/105" target="_blank" rel="noopener noreferrer">Read more here</a>.</li><li><strong>Write less C++ code</strong>: You can now enable the New Architecture without having to add any C++ code in your app and the CLI app template has been cleaned of all the C++ code and the CMake files. <a href="https://github.com/reactwg/react-native-new-architecture/discussions/101" target="_blank" rel="noopener noreferrer">Read more here</a>.</li><li><strong>Better encapsulation of iOS app setup</strong>: On iOS, we followed a similar approach to Android and encapsulated most of the logic to set up the New Architecture in the <code>RCTAppDelegate</code> class, which will simplify upgrades in the future with fewer manual breaking changes.</li><li><strong>Better dependency management on iOS</strong>: For library maintainers, we've added a new <code>install_module_dependencies</code> function to call inside your package <code>podspec</code> which will install all the required dependencies for the New Architecture.</li><li><strong>Bug fixes and better IDE support</strong>: we fixed several bugs and issues (like <a href="https://github.com/reactwg/react-native-new-architecture/discussions/102" target="_blank" rel="noopener noreferrer">better IDE support for Android</a>) that were reported by our users in the <a href="https://github.com/reactwg/react-native-new-architecture/discussions" target="_blank" rel="noopener noreferrer">New Architecture Working Group</a>.</li></ul><p>As a reminder, the New Architecture is still an experimental API experience as we iterate on changes to make adoption easier. Please try out the new simplified steps in the <a href="https://reactnative.dev/docs/new-architecture-intro" target="_blank" rel="noopener noreferrer">New Architecture documentation</a> and post any feedback you have to the <a href="https://github.com/reactwg/react-native-new-architecture/discussions" target="_blank" rel="noopener noreferrer">New Architecture Working Group</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="other-notable-fixes">Other Notable Fixes<a class="hash-link" href="#other-notable-fixes" title="Direct link to heading">​</a></h3><ul><li><strong>Better stack frame collapsing</strong>: We've <a href="https://github.com/react-native-community/cli/pull/1699" target="_blank" rel="noopener noreferrer">updated the list of internal frames</a> for React Native so LogBox will show your code more often rather than internal React Native frames, helping you to debug issues faster.</li><li><strong>Build time improvements:</strong> We migrated assets to Maven Central for prefabs to improve build times (both iOS and Android) for Hermes in both the current and new architectures.</li><li><strong>Android template improvements</strong>: The Android template was heavily cleaned and now fully relies on the React Native Gradle Plugin. You can find the configuration instructions directly inside the template or in the <a href="https://reactnative.dev/docs/react-native-gradle-plugin" target="_blank" rel="noopener noreferrer">new dedicated page on the website</a>.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="breaking-changes">Breaking changes<a class="hash-link" href="#breaking-changes" title="Direct link to heading">​</a></h2><ul><li><strong>Changes to Console Logging:</strong> <code>LogBox.ignoreLog</code> no longer filters console logs. This means you will start seeing logs in the console that you have silenced in LogBox. See <a href="https://github.com/facebook/react-native/pull/34476#issuecomment-1240667794" target="_blank" rel="noopener noreferrer">this comment</a> for more details.</li><li><strong>Removed AsyncStorage and MaskedViewIOS</strong>: These components have been deprecated since version <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#deprecated-8" target="_blank" rel="noopener noreferrer">0.59</a>, so it’s time we remove them entirely. For alternatives, please check <a href="https://reactnative.directory/" target="_blank" rel="noopener noreferrer">React Native Directory</a> for community packages that cover those use cases.</li><li><strong>JSCRuntime moved to react-jsc:</strong> react-jsi is now split into react-jsc and react-jsi. If you use JSCRuntime, you will need to add react-jsc as a dependency (<a href="https://github.com/facebook/react-native/commit/6b129d81ed8cab301775d2a04971e255df9290de" target="_blank" rel="noopener noreferrer">facebook/react-native@6b129d8</a>).</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="acknowledgements">Acknowledgements<a class="hash-link" href="#acknowledgements" title="Direct link to heading">​</a></h2><p>This release is possible thanks to the work of 70+ contributors adding over 1000 commits.</p><p>We especially want to thank those who contributed to these major React Native projects:</p><ul><li><strong>Flexbox Gap Support</strong>: <a href="https://github.com/intergalacticspacehighway" target="_blank" rel="noopener noreferrer">@intergalacticspacehighway</a> and <a href="https://github.com/jacobp100" target="_blank" rel="noopener noreferrer">@jacobp100</a>.</li><li><strong>Web-inspired props</strong>: <a href="https://github.com/gabrieldonadel" target="_blank" rel="noopener noreferrer">@gabrieldonadel</a> <a href="https://github.com/dakshbhardwaj" target="_blank" rel="noopener noreferrer">@dakshbhardwaj</a> <a href="https://github.com/dhruvtailor7" target="_blank" rel="noopener noreferrer">@dhruvtailor7</a> <a href="https://github.com/ankit-tailor" target="_blank" rel="noopener noreferrer">@ankit-tailor</a> <a href="https://github.com/madhav23bansal" target="_blank" rel="noopener noreferrer">@madhav23bansal</a>.</li><li><strong>Codegen Improvements</strong>: <a href="http://github.com/AntoineDoubovetzky" target="_blank" rel="noopener noreferrer">@AntoineDoubovetzky</a>, <a href="http://github.com/MaeIg" target="_blank" rel="noopener noreferrer">@MaeIg</a>, <a href="http://github.com/Marcoo09" target="_blank" rel="noopener noreferrer">@Marcoo09</a>, <a href="http://github.com/Naturalclar" target="_blank" rel="noopener noreferrer">@Naturalclar</a>, <a href="http://github.com/Pranav-yadav" target="_blank" rel="noopener noreferrer">@Pranav-yadav</a>, <a href="http://github.com/ZihanChen-MSFT" target="_blank" rel="noopener noreferrer">@ZihanChen-MSFT</a>, <a href="http://github.com/dakshbhardwaj" target="_blank" rel="noopener noreferrer">@dakshbhardwaj</a>, <a href="http://github.com/dhruvtailor7" target="_blank" rel="noopener noreferrer">@dhruvtailor7</a>, <a href="http://github.com/gabrieldonadel" target="_blank" rel="noopener noreferrer">@gabrieldonadel</a>, <a href="http://github.com/harshsiri110" target="_blank" rel="noopener noreferrer">@harshsiri110</a>, <a href="http://github.com/ken0nek" target="_blank" rel="noopener noreferrer">@ken0nek</a>, <a href="http://github.com/kylemacabasco" target="_blank" rel="noopener noreferrer">@kylemacabasco</a>, <a href="http://github.com/matiassalles99" target="_blank" rel="noopener noreferrer">@matiassalles99</a>, <a href="http://github.com/mdaj06" target="_blank" rel="noopener noreferrer">@mdaj06</a>, <a href="http://github.com/mohitcharkha" target="_blank" rel="noopener noreferrer">@mohitcharkha</a>, <a href="http://github.com/tarunrajput" target="_blank" rel="noopener noreferrer">@tarunrajput</a>, <a href="http://github.com/vinayharwani13" target="_blank" rel="noopener noreferrer">@vinayharwani13</a>, <a href="http://github.com/youedd" target="_blank" rel="noopener noreferrer">@youedd</a>, <a href="http://github.com/byCedric" target="_blank" rel="noopener noreferrer">@byCedric</a>.</li></ul><p>Finally, thanks to <a href="https://github.com/cortinico" target="_blank" rel="noopener noreferrer">@cortinico</a>, <a href="https://github.com/kelset" target="_blank" rel="noopener noreferrer">@kelset</a>, <a href="https://github.com/dmytrorykun" target="_blank" rel="noopener noreferrer">@dmytrorykun</a>, <a href="https://github.com/cipolleschi" target="_blank" rel="noopener noreferrer">@cipolleschi</a>, and <a href="https://github.com/titozzz" target="_blank" rel="noopener noreferrer">@titozzz</a> for cutting this release!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="try-out-0710-now">Try out 0.71.0 now!<a class="hash-link" href="#try-out-0710-now" title="Direct link to heading">​</a></h2><p>For React Native CLI users, see the <a href="https://reactnative.dev/docs/upgrading" target="_blank" rel="noopener noreferrer">upgrade documentation</a> for how to update your existing project, or create a new project with <code>npx react-native init MyProject</code>.</p><p>React Native version 0.71 will be supported in Expo SDK version 48.</p><div class="theme-admonition theme-admonition-info alert alert--info admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_yySL"><p>0.71 is now the latest stable version of React Native and 0.68.x versions are now unsupported. For more information see <a href="https://github.com/reactwg/react-native-releases#releases-support-policy" target="_blank" rel="noopener noreferrer">React Native’s support policy</a>.</p></div></div>]]></content>
        <author>
            <name>Matt Carroll</name>
            <uri>https://github.com/mattcarrollcode</uri>
        </author>
        <author>
            <name>Nick Gerleman</name>
            <uri>https://github.com/NickGerleman</uri>
        </author>
        <author>
            <name>Nicola Corti</name>
            <uri>https://twitter.com/cortinico</uri>
        </author>
        <author>
            <name>Lorenzo Sciandra</name>
            <uri>https://twitter.com/kelset</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[First-class Support for TypeScript]]></title>
        <id>/2023/01/03/typescript-first</id>
        <link href="https://reactnative.dev/blog/2023/01/03/typescript-first"/>
        <updated>2023-01-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[With the release of 0.71, React Native is investing in the TypeScript experience with the following changes:]]></summary>
        <content type="html"><![CDATA[<p>With the release of 0.71, React Native is investing in the TypeScript experience with the following changes:</p><ul><li><a href="/blog/2023/01/03/typescript-first#new-app-template-is-typescript-by-default">New app template is TypeScript by default</a></li><li><a href="/blog/2023/01/03/typescript-first#declarations-shipped-with-react-native">TypeScript declarations shipped with React Native</a></li><li><a href="/blog/2023/01/03/typescript-first#documentation-is-typescript-first">React Native documentation is TypeScript First</a></li></ul><p>In this post we’ll cover what these changes mean for you as a TypeScript or Flow user.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="new-app-template-is-typescript-by-default">New App Template is TypeScript By Default<a class="hash-link" href="#new-app-template-is-typescript-by-default" title="Direct link to heading">​</a></h2><p>Starting with 0.71, when you create a new React Native app via the React Native CLI you'll get a TypeScript app by default!</p><div class="language-shell codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-shell codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">npx react-native init My71App --version </span><span class="token number" style="color:#5a9bcf">0.71</span><span class="token plain">.0</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><img loading="lazy" alt="Screenshot of an iPhone simulator running a new app generated by React Native CLI. Alongside the simulator is a screenshot of Visual Studio Code editor opened to &amp;quot;App.tsx&amp;quot; to illustrate it is running a TypeScript file." src="/assets/images/typescript-first-new-app-426f2230271f337ea5c67af38630f7b1.png" width="3036" height="1688" class="img_SS3x"></p><p>The starting point of a newly generated app will be <code>App.tsx</code> instead of <code>App.js</code> – fully TypeScript typed. The new project is already set up with a <code>tsconfig.json</code> so out of the box your IDE will help you write typed code right away!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="declarations-shipped-with-react-native">Declarations Shipped with React Native<a class="hash-link" href="#declarations-shipped-with-react-native" title="Direct link to heading">​</a></h2><p>0.71 is the first release with built-in TypeScript (TS) declarations.</p><p>Prior, TypeScript declarations for React Native were provided by <a href="https://www.npmjs.com/package/@types/react-native" target="_blank" rel="noopener noreferrer"><code>@types/react-native</code></a> hosted in the <a href="https://github.com/DefinitelyTyped/DefinitelyTyped" target="_blank" rel="noopener noreferrer">DefinitelyTyped</a> repository. The decision to co-locate TypeScript types with React Native source was for improved correctness and maintenance.</p><p><code>@types/react-native</code> only provides types for stable releases. This means if you ever wanted to develop with a pre-release version of React Native in TypeScript, you’d have to use types from an older release which may be inaccurate. Releasing <code>@types/react-native</code> is also error-prone. The releases lag React Native releases, and the process involves manually inspecting for type changes made to React Native’s public API and updating the TS declaration to match.</p><p>With TS types co-located with React Native source, there is more visibility and ownership of TS types. Our team is actively working on tools to maintain alignment between Flow and TS.</p><p>This change also removes a dependency for React Native users to manage. When upgrading to 0.71 or above, you can remove <code>@types/react-native</code> as a dependency. <a href="https://github.com/facebook/react-native/blob/main/template/tsconfig.json" target="_blank" rel="noopener noreferrer">Refer to the new app template on how to set up TypeScript support.</a></p><p>We plan to deprecate <code>@types/react-native</code> for versions 0.73 and onward. Concretely this means:</p><ul><li><code>@types/react-native</code> tracking React Native versions 0.71 and 0.72 will be released. They will be identical to the types in React Native on the relevant release branches.</li><li>For React Native 0.73 and onward, TS types will only be available from React Native.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="how-to-migrate">How to Migrate<a class="hash-link" href="#how-to-migrate" title="Direct link to heading">​</a></h3><p>Please migrate to the new co-located types at your earliest convenience. Here are more details on migrating based on your needs.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="app-maintainer">App Maintainer<a class="hash-link" href="#app-maintainer" title="Direct link to heading">​</a></h4><p>Once you upgrade to React Native &gt;= 0.71, you can remove the <code>@types/react-native</code> from your <code>devDependency</code>.</p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_yySL"><p>If you have warnings because a library you use references <code>@types/react-native</code> as a <code>peerDependency</code>, file an issue or open a PR for that library to use <a href="https://docs.npmjs.com/cli/v7/configuring-npm/package-json#peerdependenciesmeta" target="_blank" rel="noopener noreferrer">optional peerDependencies</a> and ignore the warning for now.</p></div></div><h4 class="anchor anchorWithStickyNavbar_JmGV" id="library-maintainer">Library Maintainer<a class="hash-link" href="#library-maintainer" title="Direct link to heading">​</a></h4><p>Libraries that target versions of React Native below 0.71 may use a <code>peerDependency</code> of <code>@types/react-native</code> to typecheck against the apps version of typings. This dependency should be marked as optional in <a href="https://docs.npmjs.com/cli/v7/configuring-npm/package-json#peerdependenciesmeta" target="_blank" rel="noopener noreferrer"><code>peerDependenciesMeta</code></a> so that the typings are not required for users without TypeScript or for 0.71 users where typings are built-in.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="maintainer-of-typescript-declarations-that-depend-on-typesreact-native">Maintainer of TypeScript declarations that depend on <code>@types/react-native</code><a class="hash-link" href="#maintainer-of-typescript-declarations-that-depend-on-typesreact-native" title="Direct link to heading">​</a></h4><p>Check out the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer">breaking changes introduced with 0.71</a> to see if you’re ready to migrate.</p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_yySL"><p>While 0.71 is in release candidate, you can reference the <a href="https://github.com/facebook/react-native/pull/35200/files" target="_blank" rel="noopener noreferrer">changelog PR</a>.</p></div></div><h3 class="anchor anchorWithStickyNavbar_JmGV" id="what-if-i-use-flow">What if I use Flow?<a class="hash-link" href="#what-if-i-use-flow" title="Direct link to heading">​</a></h3><p>Flow users can continue to typecheck applications targeting 0.71+ but configuration logic for it is no longer included out-of-the box in the template.</p><p>Flow users have previously upgraded React Native’s Flow types by merging in the <code>.flowconfig</code> from the new app template and manually updating <code>flow-bin</code>. The new app template no longer has a <code>.flowconfig</code>, but <a href="https://github.com/facebook/react-native/blob/main/.flowconfig" target="_blank" rel="noopener noreferrer">one is still present in the React Native repository</a> that can be used as a basis for your app.</p><p>If you need to start a new React Native app in Flow, you can reference the <a href="https://github.com/facebook/react-native/tree/0.70-stable/template" target="_blank" rel="noopener noreferrer">new app template from 0.70</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="what-if-i-find-a-bug-in-the-typescript-declaration">What if I find a bug in the TypeScript declaration?<a class="hash-link" href="#what-if-i-find-a-bug-in-the-typescript-declaration" title="Direct link to heading">​</a></h3><p>Regardless of whether you’re using built-in TS types or <code>@types/react-native</code>, if you find a bug please submit a PR to both <a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer">React Native</a> and <a href="https://github.com/DefinitelyTyped/DefinitelyTyped" target="_blank" rel="noopener noreferrer">DefinitelyTyped</a> repositories. If you don’t know how to fix it, please file a GitHub issue in the React Native repository and mention <a href="https://github.com/lunaleaps" target="_blank" rel="noopener noreferrer">@lunaleaps</a> on the issue.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="documentation-is-typescript-first">Documentation is TypeScript First<a class="hash-link" href="#documentation-is-typescript-first" title="Direct link to heading">​</a></h2><p>To ensure a consistent TypeScript experience, we have made several updates to the React Native documentation to reflect TypeScript as the new default language.</p><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_yySL"><p>These documentation updates refer to the 0.71 docs which are labelled as <a href="/docs/next/getting-started"><code>next</code></a> while 0.71 is in pre-release.</p></div></div><p>Code examples now allow inline TypeScript and over 170 interactive code examples have been updated to pass linting, formatting, and type-checking in the new template. Most examples are valid as both TypeScript and JavaScript. Where they are incompatible, you can view the example in either language.</p><p>If you spot a mistake or you have an improvement, remember that the website is also open source and we would love to see your PRs!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thank-you-to-the-react-native-typescript-community">Thank you to the React Native TypeScript community!<a class="hash-link" href="#thank-you-to-the-react-native-typescript-community" title="Direct link to heading">​</a></h2><p>In closing, we want to recognize all the work done over the years by the community to ensure that TypeScript is usable by React Native developers.</p><p>We want to thank all the <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-native/index.d.ts#L3" target="_blank" rel="noopener noreferrer">contributors</a> that have been maintaining <code>@types/react-native</code> since <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commit/efce0c25ec532a4651859f10eda49e97a5716a42" target="_blank" rel="noopener noreferrer">2015</a>! We see the effort and care you all have put into making sure React Native users have the best experience.</p><p>Thank you to <a href="https://github.com/acoates" target="_blank" rel="noopener noreferrer">@acoates</a>, <a href="https://github.com/eps1lon" target="_blank" rel="noopener noreferrer">@eps1lon</a>, <a href="https://github.com/kelset" target="_blank" rel="noopener noreferrer">@kelset</a>, <a href="https://github.com/tido64" target="_blank" rel="noopener noreferrer">@tido64</a>, <a href="https://github.com/Titozzz" target="_blank" rel="noopener noreferrer">@Titozzz</a>, and <a href="https://github.com/ZihanChen-MSFT" target="_blank" rel="noopener noreferrer">@ZihanChen-MSFT</a> for your help consulting, questioning, communicating and reviewing changes to move the TypeScript types to React Native.</p><p>Similarly, we want to thank the <a href="https://github.com/react-native-community/react-native-template-typescript/graphs/contributors" target="_blank" rel="noopener noreferrer">maintainers of <code>react-native-template-typescript</code></a> for supporting the TypeScript experience for new app development in React Native since day one.</p><p>We look forward to collaborating more directly in the React Native repository and continue improving the React Native developer experience!</p>]]></content>
        <author>
            <name>Luna Wei</name>
            <uri>https://twitter.com/lunaleaps</uri>
        </author>
        <author>
            <name>Nick Gerleman</name>
            <uri>https://github.com/NickGerleman</uri>
        </author>
        <category label="typescript" term="typescript"/>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Pointer Events in React Native]]></title>
        <id>/2022/12/13/pointer-events-in-react-native</id>
        <link href="https://reactnative.dev/blog/2022/12/13/pointer-events-in-react-native"/>
        <updated>2022-12-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we are sharing an experimental cross-platform pointer API for React Native. We’ll go over motivations, how it works, and its benefits to React Native users. There are instructions on how to enable and we’re excited to hear your feedback!]]></summary>
        <content type="html"><![CDATA[<p>Today we are sharing an experimental cross-platform pointer API for React Native. We’ll go over motivations, how it works, and its benefits to React Native users. There are instructions on how to enable and we’re excited to hear your feedback!</p><p>It’s been over a year since we shared <a href="https://reactnative.dev/blog/2021/08/26/many-platform-vision" target="_blank" rel="noopener noreferrer">our many platform vision</a> on the wins of building beyond mobile and how it sets a higher bar for all platforms. During this time, we've increased our investments in React Native for VR, Desktop, and Web. With differences in hardware and interactions on these platforms, it raised the question of how React Native should holistically handle input.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="going-beyond-touch">Going Beyond Touch<a class="hash-link" href="#going-beyond-touch" title="Direct link to heading">​</a></h3><p>Desktop and VR have historically relied on mouse and keyboard input where mobile is primarily touch. That narrative has evolved with touch-screen laptops and growing needs to support interactions via keyboard and pen on mobile. All of which the React Native touch event system is not equipped to handle.</p><p>As a result, users of out-of-tree platforms fork React Native and/or create custom native components and modules to support critical features like hover detection or left-click. This divergence leads to prop redundancy with event handlers serving similar purposes but for different platforms. It adds complexity to the framework and makes code-sharing between platforms tedious. For these reasons, the team was motivated to provide a cross-platform pointer API.</p><p>React Native aims to provide robust and expressive APIs to build for many platforms while maintaining characteristic platform experiences. Designing such an API is challenging yet thankfully there is prior art in the pointer space that React Native can leverage.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="looking-to-web">Looking to Web<a class="hash-link" href="#looking-to-web" title="Direct link to heading">​</a></h3><p>Web is a platform with similar challenges in scaling to many platforms while also considering future-proof design. The World Wide Web consortium (W3C) is tasked with setting standards and proposals to build a Web that is interoperable amongst different platforms and browsers.</p><p>Most relevant for our needs, the W3C has defined behavior for an abstract form of input, called a pointer. The <a href="https://www.w3.org/TR/pointerevents3/" target="_blank" rel="noopener noreferrer">Pointer Events</a> specification builds on mouse events and aims to provide a single set of events and interfaces for cross-device pointer input while still allowing for device-specific handling when necessary.</p><p>Following the Pointer Events specification provides React Native users many benefits. Beyond addressing the problems mentioned earlier, it raises the capabilities of platforms that haven’t historically had to consider multi-input type interactions. Think attaching a bluetooth mouse to your Android phone or the Apple pencil supporting hover on the iPad M2.</p><p>Being spec-complaint also provides opportunity for knowledge sharing between Web and React Native. Education of Web expectations around Pointer Events can doubly serve React Native developers. However, we also recognize that React Native requirements are different than web and our approach to specifications is best effort with well documented deviations so expectations are clear. There is related work of aligning certain Web standards to <a href="https://github.com/react-native-community/discussions-and-proposals/pull/496" target="_blank" rel="noopener noreferrer">reduce API fragmentation</a> in accessibility and performance APIs.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="porting-web-platform-tests">Porting Web Platform Tests<a class="hash-link" href="#porting-web-platform-tests" title="Direct link to heading">​</a></h2><p>While the Pointer Events specification provides interfaces and behavior descriptions of the API, we found it wasn’t specific enough for us to confidently make changes and point to the specification as verification. However, web browsers use another mechanism to ensure compliance and interoperability — the <a href="https://web-platform-tests.org/" target="_blank" rel="noopener noreferrer">Web Platform Tests</a>!</p><p>The Web Platform Tests are written to work against the browser’s imperative DOM APIs — unsupported by React Native as it uses its own view primitives. This means that we aren’t able to code-share the tests with browsers and instead have an analogous testing API for React Native that makes it easier to port those Web Platform Tests.</p><p>We implemented a new manual testing framework which we are now using for verifying our implementations through RNTester. These tests are tentatively named the RNTester Platform Tests and are still fairly basic. Our implementation provides an API to construct test cases as components themselves which are rendered and where the results are reported solely through the UI.</p><p><img loading="lazy" alt="GIF showing a side by side comparison of the &amp;quot;Pointer Events hoverable pointer attributes test&amp;quot; running in React Native (iOS) on the left, and Web (the original implementation) on the right." src="/assets/images/pointer-events-wpt-demo-f524c11634eb4f9b5a907c5730f27321.gif" width="960" height="540" class="img_SS3x"></p><p>These tests will continue to be helpful as we further the completeness of our Pointer Events implementation. These tests will also scale to test Pointer Events implementations on platforms beyond Android and iOS. As the number of tests in our suite increase we will be looking to automate the running of these tests so that we are better equipped to catch regressions in our implementations.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="how-it-works">How it works<a class="hash-link" href="#how-it-works" title="Direct link to heading">​</a></h2><p>Much of our Pointer Events implementation builds off existing infrastructure for dispatching touch events. On Android and iOS we leverage the relevant MotionEvent and UITouch events. The general flow of event dispatching is illustrated below.</p><p><img loading="lazy" alt="Diagram of code flow for interpreting Android and iOS UI input events into Pointer Events. On Android, input handlers &amp;quot;onTouchEvent&amp;quot; and &amp;quot;onHoverEvent&amp;quot; fire &amp;quot;MotionEvents&amp;quot; that are interpreted into Pointer Events and through JSI are dispatched to the React renderer. iOS takes a similar path with input handlers &amp;quot;touchesBegan&amp;quot;, &amp;quot;touchesMoved&amp;quot;, &amp;quot;touchesEnded&amp;quot;, and &amp;quot;hovering&amp;quot; interpreting &amp;quot;UITouch&amp;quot; and &amp;quot;UIEvent&amp;quot; into Pointer Events." src="/assets/images/pointer-events-code-flow-5f598d1362801753c43a1936f08a509d.png" width="1980" height="985" class="img_SS3x"></p><p>Using Android as an example, the general approach to leveraging platform events are:</p><ol><li>Iterate through all pointers of the <code>MotionEvent</code> and do a depth-first search to determine the target React view of each pointer and its ancestral path.</li><li>Map the category of <code>MotionEvent</code> to the relevant pointer events. There is a 1-to-many relationship between <code>MotionEvent</code> and <code>PointerEvent</code>. In the illustration of their relationship, dotted lines indicate fired events if the pointing device does not support hover.</li></ol><p><img loading="lazy" alt="A diagram illustrating the relationship of types of Android MotionEvents into Pointer Events fired. Some pointer events are conditionally fired if pointing device does not support hover. &amp;quot;ACTION_DOWN&amp;quot; and &amp;quot;ACTION_POINTER_DOWN&amp;quot; fire pointerdown and conditionally fire pointerenter, pointerover. &amp;quot;ACTION_MOVE&amp;quot; and &amp;quot;ACTION_HOVER_MOVE&amp;quot; fire pointerover, pointermove, pointerout, pointerup. &amp;quot;ACTION_UP&amp;quot; and &amp;quot;ACTION_POINTER_UP&amp;quot; fire pointerup and conditionally fire pointerout, pointerleave." src="/assets/images/pointer-events-motionevent-relationship-892a4a19c30a230188599cc520c57804.png" width="1506" height="700" class="img_SS3x"></p><ol><li>Build the <code>PointerEvent</code> interface with platform details from the <code>MotionEvent</code> and cached state of previous interactions. (Ex. <a href="https://w3c.github.io/pointerevents/#the-button-property" target="_blank" rel="noopener noreferrer">the <code>button</code> property</a>)</li><li>Dispatch the pointer events from Android to React Native’s <a href="https://github.com/facebook/react-native/blob/main/ReactCommon/react/renderer/core/EventQueueProcessor.cpp#L20" target="_blank" rel="noopener noreferrer">core event queue</a> and leverage JSI to call the <a href="https://github.com/facebook/react/blob/main/packages/react-native-renderer/src/ReactFabricEventEmitter.js#L83" target="_blank" rel="noopener noreferrer"><code>dispatchEvent</code></a> method in <code>react-native-renderer</code> which iterates through the React tree for the bubble and capture phase of the event.</li></ol><h2 class="anchor anchorWithStickyNavbar_JmGV" id="implementation-progress">Implementation Progress<a class="hash-link" href="#implementation-progress" title="Direct link to heading">​</a></h2><p>When it comes to our current progress of implementing the Pointer Events specification we’ve focused on a solid baseline implementation of the most common events that handle things like pressing, hovering, and moving.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="events">Events<a class="hash-link" href="#events" title="Direct link to heading">​</a></h3><table><thead><tr><th>Implemented</th><th>Work in Progress</th><th>Yet to be Implemented</th></tr></thead><tbody><tr><td>onPointerOver</td><td>onPointerCancel</td><td>onClick</td></tr><tr><td>onPointerEnter</td><td></td><td>onContextMenu</td></tr><tr><td>onPointerDown</td><td></td><td>onGotPointerCapture</td></tr><tr><td>onPointerMove</td><td></td><td>onLostPointerCapture</td></tr><tr><td>onPointerUp</td><td></td><td>onPointerRawUpdate</td></tr><tr><td>onPointerOut</td><td></td><td></td></tr><tr><td>onPointerLeave</td><td></td><td></td></tr></tbody></table><div class="theme-admonition theme-admonition-info alert alert--info admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_yySL"><p>onPointerCancel has been hooked up to the native platform’s "cancel" event but this does not necessarily correspond to when the web platform expects them to fire.</p></div></div><h3 class="anchor anchorWithStickyNavbar_JmGV" id="event-properties">Event Properties<a class="hash-link" href="#event-properties" title="Direct link to heading">​</a></h3><p>For each of the events mentioned above we’ve also implemented the majority of the properties expected in the PointerEvent object — though in React Native these are exposed through the <code>event.nativeEvent</code> property. You can find an enumeration of all the implemented properties in the <a href="https://github.com/facebook/react-native/blob/59ee57352738f030b41589a450209e51e44bbb06/Libraries/Types/CoreEventTypes.js#L175" target="_blank" rel="noopener noreferrer">event object’s Flowtype interface definition</a>. One notable exception to being completely implemented is the <code>relatedTarget</code> property as exposing a native view reference in this ad-hoc manner isn’t trivial.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="future-work-and-exploration">Future Work and Exploration<a class="hash-link" href="#future-work-and-exploration" title="Direct link to heading">​</a></h2><p>In addition to the events above there are also some other APIs related to Pointer Events. In the future, we plan to be implement these APIs as a part of this effort. These APIs include:</p><ul><li>Pointer Capture API<ul><li>Includes the imperative API exposed on element references including <code>setPointerCapture()</code>, <code>releasePointerCapture()</code>, and <code>hasPointerCapture()</code>.</li></ul></li><li><code>touch-action</code> style property<ul><li>The web uses this CSS property to declaratively negotiate gestures between the browser and a website’s own event handling code. In React Native this could be used for negotiating the event handling between a View’s pointer event handlers and a parent ScrollView.</li></ul></li><li><code>click</code>, <code>contextmenu</code>, <code>auxclick</code><ul><li><code>click</code> is an abstract definition of interaction that may be triggered through accessibility paradigms or other characteristic platform interactions.</li></ul></li></ul><p>Another benefit of the native Pointer Events implementation is that it will allow us to revisit and improve various forms of gesture handling currently limited only to touch events and handled in JavaScript by the Responder, Pressability, and PanResponder APIs.</p><p>Furthermore, we are continuing to explore including an implementation of the <code>EventTarget</code> interface for React Native host components (i.e. <code>add</code>/<code>removeEventListener</code>) which we believe will make possible more user-land abstractions for handling pointer interactions.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="trying-it-out">Trying it Out<a class="hash-link" href="#trying-it-out" title="Direct link to heading">​</a></h2><p>Our Pointer Events implementation is still experimental but we’re interested in getting feedback from the community on what we’ve shared. If you are interested in trying this API you’ll need to enable a couple feature flags:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="enable-feature-flags">Enable Feature Flags<a class="hash-link" href="#enable-feature-flags" title="Direct link to heading">​</a></h3><div class="theme-admonition theme-admonition-note alert alert--secondary admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_yySL"><p>Pointer Events are only implemented for the <a href="https://reactnative.dev/docs/the-new-architecture/use-app-template" target="_blank" rel="noopener noreferrer">New Architecture (Fabric)</a> and are only available for React Native 0.71+ which at the time of writing is a release candidate.</p></div></div><p>In your entry JavaScript file (index.js in the default React Native app template) you’ll need to enable the <code>shouldEmitW3CPointerEvents</code> flag for Pointer Events and <code>shouldPressibilityUseW3CPointerEventsForHover</code> to use Pointer Events in <code>Pressability</code>.</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">ReactNativeFeatureFlags</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native/Libraries/ReactNative/ReactNativeFeatureFlags'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// enable the JS-side of the w3c PointerEvent implementation</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">ReactNativeFeatureFlags</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method-variable function-variable method function property-access" style="color:#79b6f2">shouldEmitW3CPointerEvents</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// enable hover events in Pressibility to be backed by the PointerEvent implementation</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">ReactNativeFeatureFlags</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method-variable function-variable method function property-access" style="color:#79b6f2">shouldPressibilityUseW3CPointerEventsForHover</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_JmGV" id="ios-specific">iOS-specific<a class="hash-link" href="#ios-specific" title="Direct link to heading">​</a></h3><p>In order to ensure that the pointer events are sent from the native iOS renderer you’ll need to flip a native feature flag in your native app’s initialization code (typically <code>AppDelegate.mm</code>).</p><div class="language-objc codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-objc codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token macro property directive-hash" style="color:#2aa198">#</span><span class="token macro property directive keyword" style="color:#c5a5c5">import</span><span class="token macro property" style="color:#2aa198"> </span><span class="token macro property expression operator" style="color:#fc929e">&lt;</span><span class="token macro property expression" style="color:#2aa198">React</span><span class="token macro property expression operator" style="color:#fc929e">/</span><span class="token macro property expression" style="color:#2aa198">RCTConstants</span><span class="token macro property expression punctuation" style="color:#657b83">.</span><span class="token macro property expression" style="color:#2aa198">h</span><span class="token macro property expression operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">-</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">BOOL</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain">application</span><span class="token punctuation" style="color:#657b83">:</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">UIApplication </span><span class="token operator" style="color:#fc929e">*</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain">application didFinishLaunchingWithOptions</span><span class="token punctuation" style="color:#657b83">:</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">NSDictionary </span><span class="token operator" style="color:#fc929e">*</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain">launchOptions</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token function" style="color:#79b6f2">RCTSetDispatchW3CPointerEvents</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">YES</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token comment" style="color:#93a1a1">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Note that to ensure that the Pointer Event implementation can distinguish between mouse and touch pointers on iOS you need to add <a href="https://developer.apple.com/documentation/bundleresources/information_property_list/uiapplicationsupportsindirectinputevents" target="_blank" rel="noopener noreferrer"><code>UIApplicationSupportsIndirectInputEvents</code></a> to your Xcode project’s <code>info.plist</code>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="android-specific">Android-specific<a class="hash-link" href="#android-specific" title="Direct link to heading">​</a></h3><p>Similarly to iOS Android has a feature flag that you’ll need to enable in your app’s initialization — typically your <code>onCreate</code> for your root React activity or surface.</p><div class="language-java codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-java codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token import namespace" style="opacity:0.7">com</span><span class="token import namespace punctuation" style="opacity:0.7;color:#657b83">.</span><span class="token import namespace" style="opacity:0.7">facebook</span><span class="token import namespace punctuation" style="opacity:0.7;color:#657b83">.</span><span class="token import namespace" style="opacity:0.7">react</span><span class="token import namespace punctuation" style="opacity:0.7;color:#657b83">.</span><span class="token import namespace" style="opacity:0.7">config</span><span class="token import namespace punctuation" style="opacity:0.7;color:#657b83">.</span><span class="token import class-name" style="color:#fac863">ReactFeatureFlags</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">//... somewhere in initialization</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token annotation punctuation" style="color:#657b83">@Override</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">public</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">void</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">onCreate</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token class-name" style="color:#fac863">ReactFeatureFlags</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">dispatchPointerEvents </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_JmGV" id="javascript">JavaScript<a class="hash-link" href="#javascript" title="Direct link to heading">​</a></h3><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">onPointerOver</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">event</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string" style="color:#8dc891">'Over blue box offset: '</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    event</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">nativeEvent</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">offsetX</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    event</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">nativeEvent</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">offsetY</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// ... in some component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">View</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  onPointerOver</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">onPointerOver</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token punctuation" style="color:#657b83">{</span><span class="token literal-property property" style="color:#2aa198">height</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">width</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">backgroundColor</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'blue'</span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">/</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="feedback-welcome">Feedback Welcome<a class="hash-link" href="#feedback-welcome" title="Direct link to heading">​</a></h2><p>Today Pointer Events are used by our VR platform and powering the Oculus Store, but we're also looking for early community feedback on both our approach and what we have for an implementation so far. We are excited to share our further progress with you and if you have questions or thoughts around this work, join us on the <a href="https://github.com/react-native-community/discussions-and-proposals/discussions/557" target="_blank" rel="noopener noreferrer">dedicated discussion on Pointer Events</a>.</p>]]></content>
        <author>
            <name>Luna Wei</name>
            <uri>https://twitter.com/lunaleaps</uri>
        </author>
        <author>
            <name>Vincent Riemer</name>
            <uri>https://twitter.com/vincentriemer</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Core Contributor Summit 2022]]></title>
        <id>/2022/11/22/react-native-core-contributor-summit-2022</id>
        <link href="https://reactnative.dev/blog/2022/11/22/react-native-core-contributor-summit-2022"/>
        <updated>2022-11-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[After years of pandemic and online-only events, we really felt it was time to bring the Core Contributors of React Native together!]]></summary>
        <content type="html"><![CDATA[<p>After years of pandemic and online-only events, we really felt it was time to bring the Core Contributors of React Native together!</p><p>That’s why at the beginning of September, we gathered some of the active core contributors of React Native, library maintainers, and the Meta’s React Native and Metro teams to the <strong>Core Contributor Summit 2022</strong>. <a href="https://www.callstack.com/" target="_blank" rel="noopener noreferrer">Callstack</a> hosted the Summit in their HQ in Wrocław, Poland, as a part of the <a href="https://www.react-native.eu/" target="_blank" rel="noopener noreferrer">React Native EU</a> conference happening at the same time.</p><p>Together with the React Native core team, we devised a series of <strong>workshops</strong> in which the attendees could participate. The topics were:</p><ul><li>​​React Native Codegen &amp; TypeScript Support</li><li>​​React Native New Architecture Library Migration</li><li>​​React Native Monorepo</li><li>Metro Web and Ecosystem Alignment</li><li>Metro Simplified Release Workflow</li></ul><p>We were impressed by the amount of knowledge-sharing and collaboration over those two days. In this blog post, we’d like to give you a sneak peek of the results of this gathering.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="react-native-codegen--typescript-support">React Native Codegen &amp; TypeScript Support<a class="hash-link" href="#react-native-codegen--typescript-support" title="Direct link to heading">​</a></h3><p><a href="/docs/the-new-architecture/pillars-codegen">React Native’s Codegen</a> is a fundamental part of the New Architecture of React Native. Supporting and improving it is among our top priorities for the future of React Native. For instance, earlier this year, we added support for generic code starting from TypeScript specs rather than Flow.</p><p>In this session, we took the opportunity to onboard new contributors to Codegen, by explaining its core concept and describing how it works. We then focused on two major areas:</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="1-supporting-new-types-that-are-currently-unsupported-by-codegen-one-of-the-highly-requested-ones-was-the-string-union-types-in-typescript">1. Supporting <strong>new types</strong> that are currently unsupported by Codegen. One of the highly requested ones was the <a href="https://github.com/Titozzz/react-native/tree/codegen-string-union" target="_blank" rel="noopener noreferrer">string union types in TypeScript</a>.<a class="hash-link" href="#1-supporting-new-types-that-are-currently-unsupported-by-codegen-one-of-the-highly-requested-ones-was-the-string-union-types-in-typescript" title="Direct link to heading">​</a></h4><p>A team of a few people moved into a meeting room to tackle this task. They encountered and overcame some difficulties along the way, like how to run unit tests for Codegen. They spent quite some time understanding the code execution flow before starting to deal with the code. After some hours of collaborative work, they ended up with the first prototype that was able to recognize string unions. This experience was extremely useful in discussing design patterns and the ideal architecture we may want in the future.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="2-improving-auto-linking-for-ios-which-was-missing-a-use-case">2. Improving <strong><a href="https://github.com/facebook/react-native/pull/34580" target="_blank" rel="noopener noreferrer">auto-linking for iOS</a></strong>, which was missing a use case.<a class="hash-link" href="#2-improving-auto-linking-for-ios-which-was-missing-a-use-case" title="Direct link to heading">​</a></h4><p>Specifically, auto-linking could not work well in scenarios where libraries and the app were living together in a monorepo. Android already supported this use case but it was missing for iOS.</p><p>Working with the contributors on Codegen helped us realize that it wasn’t trivial to work in its codebase. For example, adding the support for one type required to copy-and-paste the same code in four different places: modules with specs written in Flow, modules with specs written in TypeScript, components with specs written in Flow, and components with specs written in TypeScript.</p><p>This realization pushed us to create an <a href="https://github.com/facebook/react-native/issues/34872" target="_blank" rel="noopener noreferrer">umbrella task</a> to reach out for help to the community in order to improve the status of the codebase toward a more maintainable one.</p><p>The participation was outstanding: we managed to quickly assign the first <strong>40 tasks in 5 days</strong>. At the end of October, the community completed <strong>47 tasks</strong> and many others are ready and waiting to be merged.</p><p>This initiative also contributed to the <a href="https://hacktoberfest.com/" target="_blank" rel="noopener noreferrer">Hacktoberfest</a> for all the people who contributed to these improvements!</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="react-native-new-architecture-library-migration">​​React Native New Architecture Library Migration<a class="hash-link" href="#react-native-new-architecture-library-migration" title="Direct link to heading">​</a></h3><p>The hot topic in the React Native space is the New Architecture. Having <strong>libraries</strong> that support the New Architecture is a crucial point in the <a href="/blog/2022/06/16/resources-migrating-your-react-native-library-to-the-new-architecture">migration for the whole ecosystem</a>. Therefore, we want to support library maintainers in migrating to the New Architectures.</p><p>Initially, this session started as a brainstorming, where the core contributors had the opportunity to ask the React Native team all the questions they had related to the New Architecture. This in-person feedback loop was crucial for both the core contributors to bring clarity and for the React Native team to collect feedback. Some of the shared feedback and concerns will end up being implemented in React Native 0.71.</p><p>We then moved to practically migrating as many libraries to the new architecture as possible. During this session, we kicked off the migration process for several community packages, such as <code>react-native-document-picker</code>, <code>react-native-store-review</code>, and <code>react-native-orientation</code>.</p><p>As a reminder, if you’re also migrating a library and need support in doing so, please reach out to our <a href="https://github.com/reactwg/react-native-new-architecture" target="_blank" rel="noopener noreferrer">New Architecture Working Group</a> on GitHub.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="react-native-monorepo">​​React Native Monorepo<a class="hash-link" href="#react-native-monorepo" title="Direct link to heading">​</a></h3><p>Releasing a new version of React Native is not trivial today. React Native is one of the most downloaded packages on NPM, and we want to make sure that our release process is smooth.</p><p>That’s why we want to refactor the <code>react-native</code> repository and implement the <strong>Monorepo RFC</strong> (<a href="https://github.com/react-native-community/discussions-and-proposals/pull/480" target="_blank" rel="noopener noreferrer">#480</a>).</p><p>In this session, we initially brainstormed and collected opinions from every contributor, as it’s crucial that we evolve our repository to reduce the breaking changes for our downstream dependencies.</p><p>We then started working on two fronts. First, we had to expand our Continuous Integration infrastructure to support our monorepo, adding <a href="https://verdaccio.org/" target="_blank" rel="noopener noreferrer">Verdaccio</a> to our testing infrastructure. We then started renaming &amp; adding scopes to several of our packages, resulting in 6 distinct contributions.</p><p>You can track the status of this effort under this <a href="https://github.com/facebook/react-native/issues/34692" target="_blank" rel="noopener noreferrer">umbrella issue</a> and we hope to share more on this effort in the near future.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="metro-web-and-ecosystem-alignment">Metro Web and Ecosystem Alignment<a class="hash-link" href="#metro-web-and-ecosystem-alignment" title="Direct link to heading">​</a></h3><p><a href="https://github.com/facebook/metro" target="_blank" rel="noopener noreferrer">Metro</a>, our JavaScript Bundler, is a foundational and integrated part of the React Native development experience and we want to make sure it works with the latest standards in the JS ecosystem.</p><p>The focus of this session was to discuss improving Metro's feature set to work better for web use cases and with the npm and bundler ecosystem. Two major areas of discussion:</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="1-adopting-the-exports-package-entry-points-specification">1. Adopting the <code>"exports"</code> (<a href="https://nodejs.org/api/packages.html#package-entry-points" target="_blank" rel="noopener noreferrer">package entry points</a>) specification<a class="hash-link" href="#1-adopting-the-exports-package-entry-points-specification" title="Direct link to heading">​</a></h4><p>From the <a href="https://nodejs.org/api/packages.html#package-entry-points" target="_blank" rel="noopener noreferrer">Node.js documentation</a>:</p><div class="theme-admonition theme-admonition-info alert alert--info admonition_uH4V"><div class="admonitionHeading_P5_N"><span class="admonitionIcon_MF44"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_yySL"><p>The <a href="https://nodejs.org/api/packages.html#exports" target="_blank" rel="noopener noreferrer">"exports"</a> provides a modern alternative to <a href="https://nodejs.org/api/packages.html#main" target="_blank" rel="noopener noreferrer">"main"</a> allowing multiple entry points to be defined, conditional entry resolution support between environments, and <strong>preventing any other entry points besides those defined in <a href="https://nodejs.org/api/packages.html#exports" target="_blank" rel="noopener noreferrer">"exports"</a></strong>. This encapsulation allows module authors to define the public interface for their package clearly.</p></div></div><p>Adopting the <code>"exports"</code> specification has a lot of potential. In this session, we debated on how to handle <a href="/docs/platform-specific-code#platform-specific-extensions">Platform Specific Code</a> with <code>"exports"</code>. Considering many factors, we came up with a fairly non-breaking rollout plan for <code>"exports"</code>, by adding a <code>"strict"</code> and <code>"non-strict"</code> mode to Metro resolver. We discussed how leveraging <a href="https://github.com/callstack/react-native-builder-bob" target="_blank" rel="noopener noreferrer">builder-bob</a> would help library creators adopt the strict mode without friction.</p><p>This discussion resulted in:</p><ol><li>An <a href="https://github.com/react-native-community/discussions-and-proposals/pull/534" target="_blank" rel="noopener noreferrer">RFC</a> for Metro on how package exports would work with React Native.</li><li>An <a href="https://github.com/nodejs/node/pull/45367" target="_blank" rel="noopener noreferrer">RFC</a> for Node.js to include “react-native” as a Community Condition.</li></ol><h4 class="anchor anchorWithStickyNavbar_JmGV" id="2-web-and-bundler-ecosystem">2. Web and bundler ecosystem<a class="hash-link" href="#2-web-and-bundler-ecosystem" title="Direct link to heading">​</a></h4><p>The Metro team shared progress from their partnership with Expo and the intent to continue this working model for upcoming bundle splitting and tree-shaking support. We touched again on ES module support and considered potential future features such as Yarn PnP and output optimization on the web. We discussed how Metro’s core shares logic and data structures with Jest and opportunities for more reuse.</p><p>Developers surfaced insightful use cases for bundle splitting and interoperability with third-party tooling. This led us to discuss potential extension points in Metro and improving current documentation.</p><p>This discussion provided us with good grounding for the next day's session on simplifying the release workflow.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="metro-simplified-release-workflow">Metro Simplified Release Workflow<a class="hash-link" href="#metro-simplified-release-workflow" title="Direct link to heading">​</a></h3><p>As mentioned, releasing React Native is not trivial.</p><p>Things get harder as we need to release React Native, the React Native CLI, and Metro. Those tools are connected to each other as React Native and the CLI both depend on Metro. This creates some friction when any of the packages releases a new version.</p><p>Currently, we manage this through direct communication and synchronized releases, but there is space for improvement.</p><p>In this session, we reconsidered the <strong>dependencies</strong> between React Native, Metro, and the CLI. We uncovered how some design decisions during the <a href="https://github.com/react-native-community/discussions-and-proposals/issues/6" target="_blank" rel="noopener noreferrer">“Lean Core” effort</a>, when we extracted the CLI from React Native, made these two projects codependent with some functionalities duplicated among efforts. The decisions back then made sense and allowed the CLI team to iterate faster than ever.</p><p>It was about time to revisit them and take the experience of both teams to figure out the way through. As a result, the Metro team will take over the <a href="https://github.com/react-native-community/cli/tree/main/packages/cli-plugin-metro" target="_blank" rel="noopener noreferrer"><code>@react-native-community/cli-plugin-metro</code></a> development, temporarily moving it back to the core of React Native, and then most likely to the Metro monorepo.</p><p><img loading="lazy" src="/assets/images/core-contributor-summit-2022-fe0899624299a2b699322a43a20cb7a3.jpg" width="1865" height="1252" class="img_SS3x"></p><p>The biggest takeaway, apart from three hours of drawing dependencies between the packages on the whiteboard, was for the CLI and Metro team to exchange their issues, experiences, and plans, resulting in a better understanding of each other.</p><p>We wouldn’t be able to achieve this level of cooperation without actually meeting each other.</p><hr><p>We’re still impressed by how spending several hours together for a couple of days resulted in so much knowledge-sharing and cross-pollination of ideas. During this summit, we planted the seeds for initiatives that will help us improve and re-shape the React Native ecosystem.</p><p>We want to say thank you again to <a href="https://www.callstack.com/" target="_blank" rel="noopener noreferrer">Callstack</a> for hosting us and to all the participants for joining us at the Core Contributor Summit 2022.</p><p>If you’re interested in joining the development of React Native, make sure you join our open initiatives and read the <a href="https://reactnative.dev/contributing/overview" target="_blank" rel="noopener noreferrer">contribution guide</a> we have on our website. We hope to meet you in person as well in the future!</p>]]></content>
        <author>
            <name>Michał Pierzchała</name>
            <uri>https://twitter.com/thymikee</uri>
        </author>
        <author>
            <name>Nicola Corti</name>
            <uri>https://twitter.com/cortinico</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.70]]></title>
        <id>/2022/09/05/version-070</id>
        <link href="https://reactnative.dev/blog/2022/09/05/version-070"/>
        <updated>2022-09-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are excited to release a new version of React Native, 0.70.0. This version comes with several improvements like a new unified configuration for Codegen, Hermes as default engine, and full CMake support for Android builds along with a refresh of the documentation for the New Architecture. Read on to learn more!]]></summary>
        <content type="html"><![CDATA[<p>We are excited to release a new version of React Native, 0.70.0. This version comes with several improvements like a new unified configuration for Codegen, Hermes as default engine, and full CMake support for Android builds along with a refresh of the documentation for the New Architecture. Read on to learn more!</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="sections">Sections<a class="hash-link" href="#sections" title="Direct link to heading">​</a></h3><ul><li><a href="/blog/2022/09/05/version-070#new-architectures-new-documentation">New Architecture’s New Documentation</a></li><li><a href="/blog/2022/09/05/version-070#hermes-as-default-engine">Hermes as default engine</a></li><li><a href="/blog/2022/09/05/version-070#a-new-unified-configuration-for-codegen">A new unified configuration for Codegen</a></li><li><a href="/blog/2022/09/05/version-070#android-auto-linking-for-new-architecture-libraries">Android Auto-linking for New Architecture libraries</a></li><li><a href="/blog/2022/09/05/version-070#full-cmake-support-for-android-builds">Full CMake support for Android builds</a></li><li><a href="/blog/2022/09/05/version-070#highlights-of-070">Highlights of 0.70</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="new-architectures-new-documentation">New Architecture’s New Documentation<a class="hash-link" href="#new-architectures-new-documentation" title="Direct link to heading">​</a></h2><p>Over the last few months, we have been working to add more content to the <a href="https://reactnative.dev/docs/next/the-new-architecture/landing-page" target="_blank" rel="noopener noreferrer">New Architecture</a> section of the documentation. In the new section you can find migration guides, examples and tutorials to get you up to speed.</p><p>Along with it, you can find new documents diving into <a href="https://reactnative.dev/docs/next/the-new-architecture/why" target="_blank" rel="noopener noreferrer">Why a New Architecture</a> and <a href="https://reactnative.dev/docs/next/the-new-architecture/pillars" target="_blank" rel="noopener noreferrer">the various parts of it</a>. We hope this helps you better understand the rationale behind the new APIs.</p><p>Any feedback is more than welcome, please let us know in the <a href="https://github.com/facebook/react-native-website" target="_blank" rel="noopener noreferrer">react-native-website</a> repository.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="hermes-as-default-engine">Hermes as default engine<a class="hash-link" href="#hermes-as-default-engine" title="Direct link to heading">​</a></h2><p>React Native 0.70 is the first version with Hermes, our in-house JS engine, enabled by default.</p><p>This is the result of collaborative effort between the Hermes team and the React Native team, alongside with the priceless contributions from the community. We worked to improve and fine tune Hermes to make it more performant and deliver highly requested features by the community.</p><p>You can read more about it in the <a href="https://reactnative.dev/blog/2022/07/08/hermes-as-the-default" target="_blank" rel="noopener noreferrer">official announcement blogpost</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="a-new-unified-configuration-for-codegen">A new unified configuration for Codegen<a class="hash-link" href="#a-new-unified-configuration-for-codegen" title="Direct link to heading">​</a></h2><p>With 0.70, we introduced a unified way to define the Codegen specs for both iOS and Android. Previously, you had to put the Android configuration in a separate <code>build.gradle</code> file.</p><p>Now, you can define it directly in the package.json with:</p><div class="language-json codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-json codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token property" style="color:#2aa198">"codegenConfig"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token property" style="color:#2aa198">"name"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"CustomAnimationView"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token property" style="color:#2aa198">"type"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"components"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token property" style="color:#2aa198">"jsSrcsDir"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"./src"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token property" style="color:#2aa198">"android"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token property" style="color:#2aa198">"javaPackageName"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"com.custom.animation"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This improvement provides a more consistent experience for library maintainers in migrating their codebases to the New Architecture.</p><p>If you are a library maintainer, please make sure to let us know how the process is going for you in <a href="https://github.com/reactwg/react-native-new-architecture/discussions/6" target="_blank" rel="noopener noreferrer">this discussion</a> in the <a href="https://github.com/reactwg/react-native-new-architecture" target="_blank" rel="noopener noreferrer">React Native New Architecture working group</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="android-auto-linking-for-new-architecture-libraries">Android Auto-linking for New Architecture libraries<a class="hash-link" href="#android-auto-linking-for-new-architecture-libraries" title="Direct link to heading">​</a></h2><p>With 0.70, users on New Architecture are able to automatically link libraries without any additional configuration on their Android.mk or CMake files.</p><p>Autolinking is a crucial part of the React Native development experience. It allows you to include external libraries with a <code>yarn add</code> command, without dealing with CocoaPods or Gradle setups.</p><p>The New Architecture required us to adapt the auto-linking features to support libraries which are using the Codegen and exposing native code to app developers.</p><p>While Autolinking worked well for New Architecture libraries on iOS, the same was not true for Android. With 0.70 we closed this gap and you can now keep on including libraries with <code>yarn add</code> to your project: they will be linked correctly on any architecture.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="full-cmake-support-for-android-builds">Full CMake support for Android builds<a class="hash-link" href="#full-cmake-support-for-android-builds" title="Direct link to heading">​</a></h2><p>Starting from 0.70, users can now use CMake to configure their Native builds. While we don’t expect app users to directly write C++ code, you still need an entry point for the native compilation.</p><p>From now on you can use a <code>CMakeLists.txt</code> file instead of an <code>Android.mk</code> file for anything Android/Native related in your project.</p><p>This change benefits both app and library users on the New Architecture as:</p><ul><li>The CMake file created in your app is way smaller (<a href="https://github.com/facebook/react-native/blob/9923ac1b524ae959abdf50a28a3094198015f77e/packages/rn-tester/android/app/src/main/jni/CMakeLists.txt#L6-L11" target="_blank" rel="noopener noreferrer">3 lines of code</a> versus <a href="https://github.com/facebook/react-native/blob/main/template/android/app/src/main/jni/Android.mk?rgh-link-date=2022-07-20T18%3A29%3A07Z" target="_blank" rel="noopener noreferrer">50+ for Android.mk files</a>). This makes for an easier update experience between React Native versions in the future and less code to maintain on your end.</li><li>Codegen is now generating both <code>Android.mk</code> and <code>CMakeLists.txt</code>, so libraries should not worry about doing anything if they're using the default setup we provide for New Architecture libraries.</li><li>The Auto-linking mentioned above will work with both CMake and Android.mk files out of the box.</li><li>Despite apps being free to use either <code>Android.mk</code> or CMake files, the recommended solution in the future would be CMake files (due to better documentation, tooling and ecosystem around CMake).</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="highlights-of-070">Highlights of 0.70<a class="hash-link" href="#highlights-of-070" title="Direct link to heading">​</a></h2><p>As mentioned above, some of the more important improvements in this release are centered around the New Architecture experience. However, there have been other notable changes, including:</p><ul><li>Fix for Catalyst is live, set <code>mac_catalyst_enabled</code> to <code>true</code> in Podfile (see <a href="https://react-native-community.github.io/upgrade-helper/?from=0.69.1&amp;to=0.70.0-rc.0" target="_blank" rel="noopener noreferrer">upgrade-helper</a> diff for details).</li><li>Bumping metro to 0.72.0 which will enable the new React JSX Transform: <a href="https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html" target="_blank" rel="noopener noreferrer">reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html</a>.</li><li>Removing <code>reactnativeutilsjni</code> as it is built from the same sources as <code>reactnativejni</code> which results in ~220 KBs saved from every Android APK build. (<a href="https://github.com/facebook/react-native/pull/34339" target="_blank" rel="noopener noreferrer">https://github.com/facebook/react-native/pull/34339</a>).</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="breaking-changes">Breaking changes<a class="hash-link" href="#breaking-changes" title="Direct link to heading">​</a></h3><p>There have also been a few breaking changes:</p><ul><li>Removed jest/preprocessor from the react-native package (<a href="https://github.com/facebook/react-native/commit/0301cb285b2e85b48a397fe58d565196654d9754" target="_blank" rel="noopener noreferrer">0301cb285b</a> by <a href="https://github.com/motiz88" target="_blank" rel="noopener noreferrer">@motiz88</a>)</li><li>Remove nonstandard <code>Promise.prototype.done</code> (<a href="https://github.com/facebook/react-native/commit/018d5cf985497273dd700b56168cf1cf64f498d5" target="_blank" rel="noopener noreferrer">018d5cf985</a> by <a href="https://github.com/motiz88" target="_blank" rel="noopener noreferrer">@motiz88</a>)</li></ul><p>Please also note that the version of Metro has been bumped to 0.72, which comes <a href="https://github.com/facebook/metro/releases/tag/v0.72.0" target="_blank" rel="noopener noreferrer">with 5 breaking changes</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="upgrades">Upgrades<a class="hash-link" href="#upgrades" title="Direct link to heading">​</a></h3><p>And we upgraded some of our dependencies:</p><ul><li>Bump RN CLI to v9.0.0</li><li>Bump Android Gradle Plugin to 7.2.1</li><li>Bump Gradle to 7.5.1</li><li>Bump RCT-Folly to 2021-07-22</li><li>Bump Metro to 0.72</li><li>Bump SoLoader to 0.10.4</li></ul><p>You can check out the full list of changes <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md" target="_blank" rel="noopener noreferrer">in the changelog</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="acknowledgements">Acknowledgements<a class="hash-link" href="#acknowledgements" title="Direct link to heading">​</a></h3><p>88 contributors with their 493 commits have helped to make this release possible - thanks everyone! We are also thankful to everyone else who gave their feedback to ensure this release would be as stable as possible.</p>]]></content>
        <author>
            <name>Dmytro Rykun</name>
            <uri>https://github.com/dmytrorykun</uri>
        </author>
        <author>
            <name>Thibault Malbranche</name>
            <uri>https://twitter.com/titozzz</uri>
        </author>
        <author>
            <name>Nicola Corti</name>
            <uri>https://twitter.com/cortinico</uri>
        </author>
        <author>
            <name>Lorenzo Sciandra</name>
            <uri>https://twitter.com/kelset</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Hermes as the Default]]></title>
        <id>/2022/07/08/hermes-as-the-default</id>
        <link href="https://reactnative.dev/blog/2022/07/08/hermes-as-the-default"/>
        <updated>2022-07-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Last October, we announced that we had started work towards making Hermes the default engine for all React Native apps.]]></summary>
        <content type="html"><![CDATA[<p>Last October, we <a href="https://engineering.fb.com/2019/07/12/android/hermes/" target="_blank" rel="noopener noreferrer">announced</a> that we had started work towards <strong>making</strong> <strong>Hermes the default engine for all React Native apps</strong>.</p><p>Hermes has provided a lot of value to React Native inside of Meta, and we believe the open-source community will benefit as well. Hermes is designed for resource constrained devices and optimizes for start up, app size, and memory consumption. One key difference between Hermes and other JS engines is its ability to compile JavaScript source code to bytecode ahead of time. This precompiled bytecode is bundled inside the binary, and saves the interpreter from having to perform this expensive step during app startup.</p><p>Since the announcement, a lot of work has gone into making Hermes better, and today, we are excited to share that <strong>React Native 0.70 will ship with Hermes as the default engine.</strong> This means that all new projects starting on v0.70 will have Hermes enabled by default. With the rollout coming up in July, we want to work closely with the community and make sure the transition is smooth and brings value to all users. This blogpost will go over what you can expect from the change, performance benchmarks, new features, and more. Note that you don’t need to wait for React Native 0.70 to start using Hermes - you can <strong>follow <a href="/docs/hermes#enabling-hermes">these instructions</a> to enable Hermes on your existing React Native app</strong>.</p><p>Note that while Hermes will be enabled by default in new React Native projects, support for other engines will continue.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="benchmarking">Benchmarking<a class="hash-link" href="#benchmarking" title="Direct link to heading">​</a></h2><p>We measured three different metrics important to app developers: TTI, binary size, and memory consumption. We used the React Native app <a href="https://github.com/mattermost/mattermost-mobile" target="_blank" rel="noopener noreferrer">Mattermost</a> for testing. We ran these experiments for both Android and iOS on high end hardware from 2020.</p><ul><li>TTI, or time to interactive, is the duration of time from the app being launched to the user being able to interact with it. For this benchmark, we define it as the time from pressing the app icon to the first screen being rendered. We also show screen recordings of starting up Mattermost.</li><li>The binary size was measured as APK size on android and IPA size on iOS.</li><li>The memory consumption data was collected by using the Mattermost app over the span of a couple minutes. The same actions were performed in the app on both engines.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="android-benchmarking-data">Android Benchmarking Data<a class="hash-link" href="#android-benchmarking-data" title="Direct link to heading">​</a></h2><p>All the android tests were performed on a Samsung Galaxy S20.</p><figure><img loading="lazy" src="/blog/assets/hermes-default-android-data.png" alt="Android Benchmarking Data" class="img_SS3x"></figure><h3 class="anchor anchorWithStickyNavbar_JmGV" id="tti-video">TTI Video<a class="hash-link" href="#tti-video" title="Direct link to heading">​</a></h3><figure><img loading="lazy" src="/blog/assets/hermes-default-android-video.gif" alt="Android TTI Video" class="img_SS3x"></figure><h2 class="anchor anchorWithStickyNavbar_JmGV" id="ios-benchmarking-data">iOS Benchmarking Data<a class="hash-link" href="#ios-benchmarking-data" title="Direct link to heading">​</a></h2><p>All the iOS tests were performed on an iPhone 12 Pro.</p><figure><img loading="lazy" src="/blog/assets/hermes-default-ios-data.png" alt="iOS Benchmarking Data" class="img_SS3x"></figure><h3 class="anchor anchorWithStickyNavbar_JmGV" id="tti-video-1">TTI Video<a class="hash-link" href="#tti-video-1" title="Direct link to heading">​</a></h3><figure><img loading="lazy" src="/blog/assets/hermes-default-ios-video.gif" alt="iOS TTI Video" class="img_SS3x"></figure><h3 class="anchor anchorWithStickyNavbar_JmGV" id="slowed-down-tti-video-to-better-show-the-difference-in-startup-time">Slowed Down TTI Video, to better show the difference in startup time.<a class="hash-link" href="#slowed-down-tti-video-to-better-show-the-difference-in-startup-time" title="Direct link to heading">​</a></h3><figure><img loading="lazy" src="/blog/assets/hermes-default-ios-slow-video.gif" alt="iOS Slowed Down TTI Video" class="img_SS3x"></figure><h2 class="anchor anchorWithStickyNavbar_JmGV" id="react-nativehermes-integration">React Native/Hermes Integration<a class="hash-link" href="#react-nativehermes-integration" title="Direct link to heading">​</a></h2><p>We addressed a long-standing problem that has caused compatibility issues and is a recurrent problem when releasing new React Native versions: React Native depended on Hermes via prebuilt binaries distributed through CocoaPods and npm, which makes it possible to have API or <a href="https://github.com/react-native-community/discussions-and-proposals/issues/257" target="_blank" rel="noopener noreferrer">ABI incompatibilities</a>. To solve this problem, starting on React Native 0.69, Hermes is built alongside every version of React Native. This ensures full compatibility with each version React Native. This also creates a much tighter integration. It unlocks a more rapid iteration time to develop features or deploy bug fixes, and will give us greater confidence in making sure big changes to Hermes are done correctly. There is more in-depth information on the new integration change <a href="https://github.com/facebook/react-native-website/pull/3159/files" target="_blank" rel="noopener noreferrer">here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="ios-intl">iOS Intl<a class="hash-link" href="#ios-intl" title="Direct link to heading">​</a></h2><p>We finished the iOS counterpart implementation for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl" target="_blank" rel="noopener noreferrer"><code>Intl</code></a>, the ECMAScript Internationalization API that provides a broad range of language sensitive functionality. This was a long-standing <a href="https://github.com/facebook/hermes/issues/23" target="_blank" rel="noopener noreferrer">gap</a> that prevented some developers from using Hermes. The Android implementation, done in partnership with Microsoft, was shipped in React Native 0.65. With React Native 0.70, developers will have native support on both platforms.</p><p>Typical implementations for <code>Intl</code> require importing large lookup tables or data like <a href="https://cldr.unicode.org/index" target="_blank" rel="noopener noreferrer">Unicode CLDR</a>. However, that can come with an expensive size increase of up to 6MB, so in order to avoid bloating the binary size of Hermes, we implemented <code>Intl</code> by calling into APIs exposed by iOS itself. This means we can take advantage of all the locale and internationalization data that comes with iOS already.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="ongoing-work">Ongoing Work<a class="hash-link" href="#ongoing-work" title="Direct link to heading">​</a></h2><p>As we continue evolving Hermes, we want to give the community a sense of our immediate priorities: improving developer experience and ensuring nobody avoids using Hermes due to lack of JavaScript language features. More specifically, we're:</p><ul><li>Enabling developers to run the sampling profiler directly from the Chrome devtools UI.</li><li>Adding support for <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt" target="_blank" rel="noopener noreferrer"><code>BigInt</code></a>, a long-standing request from the community that may block some developers from using Hermes as it can’t be polyfilled.</li><li>Adding support for <a href="https://github.com/facebook/hermes/issues/658" target="_blank" rel="noopener noreferrer"><code>WeakRef</code></a>, which will expose new memory management controls to developers.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="wrap-up">Wrap Up<a class="hash-link" href="#wrap-up" title="Direct link to heading">​</a></h2><p>Hermes becoming the default marks the beginning of a long-term journey. We are working on new features that will enable the community to write efficient apps for many years to come. We also encourage the community to reach out on our <a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer">GitHub Repo</a> to post any bugs, questions, feedback or ideas! We have created a <code>hermes</code> label that can be used for any Hermes-specific posts.</p>]]></content>
        <author>
            <name>Michael Leon</name>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.69]]></title>
        <id>/2022/06/21/version-069</id>
        <link href="https://reactnative.dev/blog/2022/06/21/version-069"/>
        <updated>2022-06-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are excited to release a new version of React Native, 0.69.0. This version comes with several improvements for the New Architecture of React Native and new features: React 18 support & bundled Hermes. Read on to learn more!]]></summary>
        <content type="html"><![CDATA[<p>We are excited to release a new version of React Native, 0.69.0. This version comes with several improvements for the New Architecture of React Native and new features: React 18 support &amp; bundled Hermes. Read on to learn more!</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="sections">Sections<a class="hash-link" href="#sections" title="Direct link to heading">​</a></h3><ul><li><a href="/blog/2022/06/21/version-069#react-18">React 18</a></li><li><a href="/blog/2022/06/21/version-069#bundled-hermes">Bundled Hermes</a></li><li><a href="/blog/2022/06/21/version-069#highlights-of-069">Highlights of 0.69</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="react-18">React 18<a class="hash-link" href="#react-18" title="Direct link to heading">​</a></h2><p>We are delighted to share with you that React Native 0.69 is the first release to support React 18. React 18 has brought <a href="https://reactjs.org/blog/2022/03/29/react-v18.html" target="_blank" rel="noopener noreferrer">lots of improvements</a>, like new hooks such as <code>useId</code>. Additionally, React 18 includes new concurrency features such as <code>useTransition</code> or full Suspense support.</p><p>On React Native 0.69, React 18 is enabled by default. However, if you have not migrated to the New Architecture, you will only be able to leverage the features that don't use concurrent rendering and concurrent features. The New Architecture has been built with concurrent rendering in mind but we cannot add that support for the old architecture.</p><p>You can learn more about the React 18 support in React Native <a href="/docs/next/react-18-and-react-native">here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="bundled-hermes">Bundled Hermes<a class="hash-link" href="#bundled-hermes" title="Direct link to heading">​</a></h2><p>Before this release, Hermes and React Native were released separately. That led to confusion on which version of Hermes is compatible with which version of React Native. To remedy this issue, starting with React Native 0.69 we will be shipping a compatible version of Hermes alongside React Native. Making this change will make using Hermes in React Native much more stable.</p><p>Using the proper version of Hermes is handled by React Native, however, make sure to follow the steps in the <a href="https://react-native-community.github.io/upgrade-helper/?from=0.68.2&amp;to=0.69.0" target="_blank" rel="noopener noreferrer">upgrade helper</a> to ensure the integration works as intended. If you don't have Hermes enabled already, you can follow the steps <a href="/docs/hermes">here</a> to do so. While we will continue supporting other JavaScript engines, we recommend everyone to migrate to Hermes to have the best experience and to make sure we can support you better.</p><p>Note that users on the New Architecture on Android will need to <strong>build Hermes from source</strong>. For building Hermes from source, Windows users will need to additionally follow <a href="/architecture/bundled-hermes#android-users-on-new-architecture-building-on-windows">these steps</a>.</p><p>If you are interested to learn more about how React Native bundles Hermes works under the hood, you can check out the deep-dive documentation <a href="/architecture/bundled-hermes">here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="new-architecture">New Architecture<a class="hash-link" href="#new-architecture" title="Direct link to heading">​</a></h2><p>We are continuing the roll-out of the New Architecture for both Android and iOS. If you have not migrated your app or library, yet, follow the steps <a href="/docs/new-architecture-intro">here</a>. You can also read the <a href="/blog/2022/06/16/resources-migrating-your-react-native-library-to-the-new-architecture">latest update</a> on tools and resources for the New Architecture to learn more.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="highlights-of-069">Highlights of 0.69<a class="hash-link" href="#highlights-of-069" title="Direct link to heading">​</a></h2><p>As mentioned above, the most important improvements in this release are centered around React 18 support and bundled Hermes. However, there have been other notable changes, including:</p><ul><li><a href="https://github.com/facebook/react-native/commit/982ca30de079d7e80bd0b50365d58b9048fb628f" target="_blank" rel="noopener noreferrer">Deprecating support</a> for iOS/tvOS SDK 11.0, version 12.4+ is now required</li><li><a href="https://github.com/facebook/react-native/commit/c5babd993a2bed2994ecc4710fa9e424b3e6cfc2" target="_blank" rel="noopener noreferrer">Better support</a> for M1 users developing for Android</li><li><a href="https://github.com/facebook/react-native/commit/0480f56c5b5478b6ebe5ad88e347cad2810bfb17" target="_blank" rel="noopener noreferrer">Addition</a> of the new <code>.xcode.env</code> configuration file for more deterministically sourcing the node executable</li><li><a href="https://github.com/facebook/react-native/commit/50c8e973f067d4ef1fc3c2eddd360a0709828968" target="_blank" rel="noopener noreferrer">React Native now uses</a> the latest status bar API from Android 11</li><li><a href="https://github.com/facebook/react-native/commit/c2e4ae39b8a5c6534a3fa4dae4130166eda15169" target="_blank" rel="noopener noreferrer">Support for C++17</a></li><li><a href="https://github.com/facebook/react-native/commit/1a1a304ed2023d60547aef65b1a7bf56467edf08" target="_blank" rel="noopener noreferrer">New</a> <code>hotkeysEnabled</code> option in the iOS debug menu</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="breaking-changes">Breaking changes<a class="hash-link" href="#breaking-changes" title="Direct link to heading">​</a></h3><p>There have also been a few breaking changes:</p><ul><li>React Native CLI has been bumped to a new major version of <a href="https://github.com/react-native-community/cli/releases/tag/v8.0.0" target="_blank" rel="noopener noreferrer">8.0</a>:<ul><li><code>link</code> and <code>unlink</code> commands have been removed in the favour of autolinking</li><li>Deprecated <code>initCompat</code> has been removed, use <code>init</code> command instead</li><li>Removed deprecated <code>run-android</code> properties</li><li>Removed <code>install</code> and <code>uninstall</code> commands</li><li>Removed assets and hooks from <code>react-native.config.js</code> – you'll need to remove these properties from your config</li><li><code>podspecPath</code> was removed from the iOS dependency config</li><li>Removed <code>--project-path</code> option from a <code>run-ios</code></li><li>Changed iOS source directory detection from looking for an Xcode project to looking for a Podfile</li></ul></li><li>Support for <code>console.disableYellowBox</code> <a href="https://github.com/facebook/react-native/commit/b633cc130533f0731b2577123282c4530e4f0abe" target="_blank" rel="noopener noreferrer">has been dropped</a></li><li>Already deprecated prop types have been removed (<a href="https://github.com/facebook/react-native/commit/cdfddb4dad7c69904850d7e5f089a32a1d3445d1" target="_blank" rel="noopener noreferrer">cdfddb4dad</a>, <a href="https://github.com/facebook/react-native/commit/3e229f27bc9c7556876ff776abf70147289d544b" target="_blank" rel="noopener noreferrer">3e229f27bc</a>, <a href="https://github.com/facebook/react-native/commit/10199b158138b8645550b5579df87e654213fe42" target="_blank" rel="noopener noreferrer">10199b1581</a>)</li><li><code>removeListener</code>, deprecated since RN 0.65, <a href="https://github.com/facebook/react-native/commit/8dfbed786b40082a7a222e00dc0a621c0695697d" target="_blank" rel="noopener noreferrer">was removed</a> from Appearance</li><li>If you were using <code>SegmentedComponentIOS</code>, you will now need to replace it with the third-party library, for example <a href="https://github.com/react-native-segmented-control/segmented-control" target="_blank" rel="noopener noreferrer">segmented-control</a> (<a href="https://github.com/facebook/react-native/commit/235f1685748442553e53f8ec6d904bc0314a8ae6" target="_blank" rel="noopener noreferrer">235f168574</a>)</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="upgrades">Upgrades<a class="hash-link" href="#upgrades" title="Direct link to heading">​</a></h3><p>And we upgraded some of our dependencies:</p><ul><li>Bump <a href="https://github.com/facebook/react-native/commit/200488e87cf4bc355e03c78cd814b97b23452117" target="_blank" rel="noopener noreferrer">of AGP to 7.1.1</a> - we recommend sticking to this version in your apps</li><li><code>boost</code> for Android was updated to 1.76 <a href="https://github.com/facebook/react-native/commit/5cd6367f0b86543274a15bb6d0e53a8545fed845" target="_blank" rel="noopener noreferrer">to align with iOS</a></li><li>Ruby <a href="https://github.com/facebook/react-native/commit/2c87b7466e098c5cd230e02b279fc7bc7a357615" target="_blank" rel="noopener noreferrer">was bumped to 2.7.5</a></li><li>Direct metro dependencies <a href="https://github.com/facebook/react-native/commit/b74e964e705c40834acad7020562e870cdad9db1" target="_blank" rel="noopener noreferrer">have been upgraded</a> to 0.70.1</li></ul><p>You can check out the full list of changes <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#0690" target="_blank" rel="noopener noreferrer">in the changelog</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="acknowledgements">Acknowledgements<a class="hash-link" href="#acknowledgements" title="Direct link to heading">​</a></h3><p>80 contributors with their 629 commits have helped to make this release possible - thanks everyone!</p><p>We are also thankful to the release testers, supporters, and everyone else who gave their feedback to ensure this release will be as stable as possible.</p>]]></content>
        <author>
            <name>Marek Fořt</name>
            <uri>https://twitter.com/marekfort</uri>
        </author>
        <author>
            <name>Nicola Corti</name>
            <uri>https://twitter.com/cortinico</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Helping migrate React Native libraries to the New Architecture]]></title>
        <id>/2022/06/16/resources-migrating-your-react-native-library-to-the-new-architecture</id>
        <link href="https://reactnative.dev/blog/2022/06/16/resources-migrating-your-react-native-library-to-the-new-architecture"/>
        <updated>2022-06-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[tl; dr: We are working on improving the resources supporting the React Native New Architecture. We have already released a repository to help migrate your app (RNNewArchitectureApp) and one for your libraries (RNNewArchitectureLibraries). We are also revamping the New Architecture guide on the Website and we created a GitHub Working Group to answer questions related to the New Architecture.]]></summary>
        <content type="html"><![CDATA[<p><strong>tl; dr</strong>: We are working on improving the resources supporting the React Native New Architecture. We have already released a repository to help migrate your app (<a href="https://github.com/react-native-community/RNNewArchitectureApp" target="_blank" rel="noopener noreferrer">RNNewArchitectureApp</a>) and one for your libraries (<a href="https://github.com/react-native-community/RNNewArchitectureLibraries" target="_blank" rel="noopener noreferrer">RNNewArchitectureLibraries</a>). We are also revamping the <a href="https://github.com/facebook/react-native-website/pull/3037" target="_blank" rel="noopener noreferrer">New Architecture guide</a> on the Website and we created a <a href="https://github.com/reactwg/react-native-new-architecture/discussions" target="_blank" rel="noopener noreferrer">GitHub Working Group</a> to answer questions related to the New Architecture.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="introduction">Introduction<a class="hash-link" href="#introduction" title="Direct link to heading">​</a></h2><p>In this post we are sharing an update on tools and resources to help you migrate your <strong>Native Modules</strong> and <strong>Native Components</strong> to their <strong>New Architecture</strong> equivalents, <strong>TurboModule</strong> and <strong>Fabric Components</strong>.</p><p>React Native users leverage vast number of open source libraries for building apps. For a complete and consistent ecosystem, it is necessary that these libraries migrate such that everyone can benefit from the unlocked capabilities and performance improvements of the New Architecture.</p><p>Here is what we’re working on to support library developers in migrating to the New Architecture:</p><ul><li><strong>Documentation:</strong> We are expanding the <a href="https://github.com/facebook/react-native-website/pull/3037" target="_blank" rel="noopener noreferrer">New Architecture guide</a> on the website to cover more concepts of the New Architecture and how to develop your components.</li><li><strong>Example Migrations:</strong> We’ve set up two repositories to demonstrate how to migrate a React Native app to the New Architecture (<a href="https://github.com/react-native-community/RNNewArchitectureApp" target="_blank" rel="noopener noreferrer">RNNewArchitectureApp</a>) and how to create a <strong>Fabric Component</strong> and a <strong>TurboModule</strong> that work with both architectures (<a href="https://github.com/react-native-community/RNNewArchitectureLibraries" target="_blank" rel="noopener noreferrer">RNNewArchitectureLibraries</a>).</li><li><strong>Support:</strong> Earlier this year, we created a <a href="https://github.com/reactwg/react-native-new-architecture/discussions" target="_blank" rel="noopener noreferrer">GitHub Working Group</a> dedicated to discussion and questions around the New Architecture.</li></ul><p>In this post, we will dig deeper into these resources and explain in more detail how you can use them most efficiently. Finally, we will provide a snapshot of the current migration state for the most used React Native libraries.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="documentation">Documentation<a class="hash-link" href="#documentation" title="Direct link to heading">​</a></h3><p>In the past 6 months, we’ve added a <a href="/docs/new-architecture-intro">guide on adopting the New Architecture</a> and an <a href="/architecture/overview">architecture deep-dive</a> on Fabric. We plan to expand this to include more guides and documentation around creating TurboModules, understanding CodeGen, and more. We plan to have updates to share by the 0.70 release.</p><p>Currently, the <strong>New Architecture</strong> guide covers how to <a href="/docs/new-architecture-app-intro">migrate your app</a> and <a href="/docs/new-architecture-library-intro">your libraries</a> to support the New Architecture properly.</p><p>If you are interested in the evolution of this guide, or have feedback, you can follow along on <a href="https://github.com/facebook/react-native-website/pull/3037" target="_blank" rel="noopener noreferrer">this</a> pull request.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="example-migrations">Example Migrations<a class="hash-link" href="#example-migrations" title="Direct link to heading">​</a></h3><p>For developers who may want to follow along in code, we’ve prepared two example repositories.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="rnnewarchitectureapp">RNNewArchitectureApp<a class="hash-link" href="#rnnewarchitectureapp" title="Direct link to heading">​</a></h4><p><a href="https://github.com/react-native-community/RNNewArchitectureApp" target="_blank" rel="noopener noreferrer">This repo</a> was created to demonstrate how to migrate an app, the native modules and the native components from the legacy architecture on the React Native version 0.67 to the New Architecture and the most recent version of React Native. Each commit corresponds to an isolated migration step.</p><figure><img loading="lazy" src="/blog/assets/new-arch-example-steps-to-migrate-an-app.png" alt="Example steps to migrate an app" class="img_SS3x"><figcaption>Commit list for a migration in the RNNewArchitectureApp repository</figcaption></figure><p>The repo is organized as follows:</p><ul><li>A <strong>main</strong> branch has no code but a README.md which advertises other branches.</li><li>Several migration branches which show a migration from a specific version of RN to another.</li></ul><p>Some of the migration branches also have a <strong>RUN.md</strong> file which describes in a more human-readable fashion the exact steps that have been applied in every commit.</p><p>We plan to keep this example up to date with the most recent stable releases, adding migrations to any minor release of React Native we are going to release. If you notice issue with any of the steps, please file an issue in the repository. This will hold until we have the reasonable feeling that most of the React Native users have migrated to the New Architecture.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="rnnewarchitecturelibraries">RNNewArchitectureLibraries<a class="hash-link" href="#rnnewarchitecturelibraries" title="Direct link to heading">​</a></h4><p>Similarly, <a href="https://github.com/react-native-community/RNNewArchitectureLibraries" target="_blank" rel="noopener noreferrer">this repo</a> provides a step-by-step guide on how to create a <strong>TurboModule</strong> and a <strong>Fabric Component</strong>. It has a focus on ensuring backward compatibility between the New Architecture and the legacy one.</p><p>The repository is organized in a similar way to the previous one:</p><ul><li>A <strong>main</strong> branch has no code but a README.md which advertises other branches.</li><li>Other branches to show how to develop <strong>TurboModules</strong> and <strong>Fabric Components</strong>.</li></ul><p>We plan to keep this example updated onto new releases of React Native, especially releases that affect library development, as well as add more examples on how to use advanced features (for example: implementing commands, event emitters, custom state). If you notice errors, please file an issue in the example repository.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="support">Support<a class="hash-link" href="#support" title="Direct link to heading">​</a></h3><p>We’ve created a dedicated <a href="https://github.com/reactwg/react-native-new-architecture" target="_blank" rel="noopener noreferrer">working group</a> to give the community space to ask questions and get updates on the New Architecture. If you are a library maintainer, this is a valuable resource to find answers to your questions, and for us to know about your requirements. To join, please follow <a href="https://github.com/reactwg/react-native-new-architecture#how-to-join-the-working-group" target="_blank" rel="noopener noreferrer">these instructions</a>. Everyone is welcome.</p><p>The working group is organized into several sections:</p><ul><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/announcements" target="_blank" rel="noopener noreferrer">Announcements</a>: A place to share milestones and significant updates on the RN New Architecture Rollout</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/deep-dive" target="_blank" rel="noopener noreferrer">Deep Dive</a>: A place to chat about deep dives and technical-specific topics</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/documentation" target="_blank" rel="noopener noreferrer">Documentation</a>: A place to chat about the New Architecture documentation and migration material</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/libraries" target="_blank" rel="noopener noreferrer">Libraries</a>: A place to chat about 3rd party libraries and their migration story to the New Architecture</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/q-a" target="_blank" rel="noopener noreferrer">Q&amp;A</a>: A place to ask the community for help on the New Architecture topics</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/releases" target="_blank" rel="noopener noreferrer">Releases</a>: A place to chat about release specific bugs &amp; build problems</li></ul><p>To use this group effectively:</p><ul><li><strong>Make sure your library is listed inside the <a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/libraries" target="_blank" rel="noopener noreferrer">Libraries</a> section</strong>. This will help us share a status update on the migration of your library and will help us understand which struggles library authors are facing to support you better.</li><li><strong>Leverage the Q&amp;A <a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/q-a" target="_blank" rel="noopener noreferrer">section</a> if you face a blocker and need support</strong>. Our team and community experts are monitoring and will support at our best effort.</li><li><strong>Keep an eye on the other sections for topics that may affect you</strong>. A new release may introduce exactly the API that you were looking for. You can subscribe to particular discussions via GitHub.</li></ul><p>We plan to support this group until the <strong>New Architecture</strong> is enabled by default and all the major libraries have been migrated to it.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="migration-status-of-popular-libraries">Migration Status of Popular Libraries<a class="hash-link" href="#migration-status-of-popular-libraries" title="Direct link to heading">​</a></h3><p>Libraries maintainers have been sharing with us <a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/libraries" target="_blank" rel="noopener noreferrer">in the working group</a> the status of their migration effort, and we wanted to provide you with a quick overview:</p><ul><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/15" target="_blank" rel="noopener noreferrer">react-native-gesture-handler</a>: ✅ Migrated</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/17" target="_blank" rel="noopener noreferrer">react-native-navigation</a>: 🏃‍♂️ Ongoing</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/16" target="_blank" rel="noopener noreferrer">react-native-pager-view</a>: 🏃‍♂️ Ongoing</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/14" target="_blank" rel="noopener noreferrer">react-native-reanimated</a>: ✅ Migrated. In the process of testing and profiling for performances</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/13" target="_blank" rel="noopener noreferrer">react-native-screens</a>: 🏃‍♂️ Ongoing</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/38" target="_blank" rel="noopener noreferrer">react-native-slider</a>: 🎬 Started</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/21" target="_blank" rel="noopener noreferrer">react-native-template-new-architecture</a>: ✅ Migrated. Gradually adopting/testing more companion Libraries</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/22" target="_blank" rel="noopener noreferrer">react-native-template-typescript</a>: ✅ Migrated</li><li><a href="https://github.com/reactwg/react-native-new-architecture/discussions/19" target="_blank" rel="noopener noreferrer">react-native-webview</a>: 🎬 Started</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-steps">Next Steps<a class="hash-link" href="#next-steps" title="Direct link to heading">​</a></h2><p>We are invested in supporting the React Native community’s adoption of the New Architecture. Concretely, we will continue to:</p><ul><li>Offer best-effort support in the <strong>Working Group.</strong></li><li>Provide more examples about how to achieve amazing results with the New Architecture in the <strong>RNNewArchitecture</strong> repositories.</li><li>Provide clear and up-to-date documentation on the <strong>New Architecture</strong>.</li><li>Track the migration status of essential React Native libraries in the <strong>Working Group</strong>.</li><li>Simplify the migration path for developers</li></ul><p>In addition, React Native 0.69 will ship with improved devX for app and library developers for New Architecture adoption. You can find more information about the 0.69.0 release <a href="https://github.com/reactwg/react-native-releases/discussions/21" target="_blank" rel="noopener noreferrer">here</a>.</p><p>We are excited about what we will build together with the <strong>New Architecture</strong>!</p>]]></content>
        <author>
            <name>Riccardo Cipolleschi</name>
            <uri>https://twitter.com/CipolleschiR</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Accessibility - GAAD 2022 Update]]></title>
        <id>/2022/05/19/GAAD-2022-update</id>
        <link href="https://reactnative.dev/blog/2022/05/19/GAAD-2022-update"/>
        <updated>2022-05-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[May 19th, 2022 marks the 11th annual celebration of Global Accessibility Awareness Day and we wanted to update everyone on the accessibility progress we’ve made on the React Native Framework. Meta (formerly Facebook) was the first organization to take the GAAD pledge in 2020, committing to making the React Native framework accessible.]]></summary>
        <content type="html"><![CDATA[<p>May 19th, 2022 marks the 11th annual celebration of Global Accessibility Awareness Day and we wanted to update everyone on the accessibility progress we’ve made on the React Native Framework. Meta (formerly Facebook) was the <a href="/blog/2021/03/08/GAAD-React-Native-Accessibility">first organization to take the GAAD pledge in 2020</a>, committing to making the React Native framework accessible.</p><blockquote><p><em>“We hope this pledge makes it easier for developers using React Native to create fully accessible mobile apps and inspires other organizations to make similar commitments to a more accessible future.”</em></p><p>— <a href="https://gaad.foundation/gaadpledge/" target="_blank" rel="noopener noreferrer">Mike Shebanek, head of accessibility Meta, 2020</a></p></blockquote><p>The process initially began with a thorough review and gap analysis of the framework focused on React Native utilized the iOS and Android APIs to support accessibility features. Dozens of issues have since been fixed or closed out, making good on the pledge to make React Native accessible and advancing the accessibility of the framework ever forward.</p><p>We didn’t stop there, and in early 2022, we reviewed and prioritized the remaining issues from this gap analysis on the <a href="https://github.com/facebook/react-native/projects/15" target="_blank" rel="noopener noreferrer">Improved React Native Accessibility Board</a> based on their impact on developers and end users.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="fixes-that-have-already-landed-in-2022">Fixes that have already landed in 2022<a class="hash-link" href="#fixes-that-have-already-landed-in-2022" title="Direct link to heading">​</a></h2><ul><li><a href="https://github.com/facebook/react-native/issues/30840" target="_blank" rel="noopener noreferrer">Android: Disabled state not announced/disabled functionality not applied for some components</a></li><li><a href="https://github.com/facebook/react-native/issues/30977" target="_blank" rel="noopener noreferrer">Android: Position in collection not supported by some components</a></li><li><a href="https://github.com/facebook/react-native/pull/31757" target="_blank" rel="noopener noreferrer">Android: Make links independently focusable by Talkback</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="fixes-currently-in-progress">Fixes currently in progress<a class="hash-link" href="#fixes-currently-in-progress" title="Direct link to heading">​</a></h2><ul><li><a href="https://github.com/facebook/react-native/issues/30848" target="_blank" rel="noopener noreferrer">iOS/Android: Text input error announcement</a></li><li><a href="https://github.com/facebook/react-native/issues/30859" target="_blank" rel="noopener noreferrer">Android: Form field error state announcement</a></li><li><a href="https://github.com/facebook/react-native/issues/31042" target="_blank" rel="noopener noreferrer">Android: Role description is announced before the components text, rather than after</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="contributor-highlight">Contributor highlight<a class="hash-link" href="#contributor-highlight" title="Direct link to heading">​</a></h2><p>We want to recognize and send a tremendous thank you to <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">Fabrizo Bertoglio</a> who has contributed several high-quality accessibility fixes to React Native in 2021 and 2022.</p><p>Fabrizio has made it a personal goal to enable users through high quality solutions. By learning how to use TalkBack and VoiceOver himself, he has discovered how difficult it can be for screen reader users to experience everyday applications. He wants to build software that removes friction from these experiences and please disabled users.</p><p>His pull requests have been very high quality, well documented, and include thorough test cases. Well done Fabrizio! The React Native Accessibility community thanks you for your many outstanding contributions.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="whats-next-in-2022">What’s next in 2022<a class="hash-link" href="#whats-next-in-2022" title="Direct link to heading">​</a></h2><p>Our goal is to fix as many of the remaining accessibility issues as possible in 2022. We will also be reviewing the backlog of <a href="https://github.com/facebook/react-native/issues" target="_blank" rel="noopener noreferrer">React Native community reported issues</a> to look for any new accessibility-related requests.</p>]]></content>
        <author>
            <name>Alex Tait</name>
            <uri>https://twitter.com/AT_Fresh_Dev</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.68]]></title>
        <id>/2022/03/30/version-068</id>
        <link href="https://reactnative.dev/blog/2022/03/30/version-068"/>
        <updated>2022-03-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hello everyone! Today we are announcing the 0.68.0 release of React Native, with opt-in to the New React Native Architecture, bug fixes and more.]]></summary>
        <content type="html"><![CDATA[<p>Hello everyone! Today we are announcing the 0.68.0 release of React Native, with opt-in to the New React Native Architecture, bug fixes and more.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="sections">Sections<a class="hash-link" href="#sections" title="Direct link to heading">​</a></h3><ul><li><a href="/blog/2022/03/30/version-068#highlights-of-068">Highlights of 0.68</a></li><li><a href="/blog/2022/03/30/version-068#opting-in-to-the-new-architecture">Opting in to the New Architecture</a></li><li><a href="/blog/2022/03/30/version-068#website-updates">Website updates</a></li><li><a href="/blog/2022/03/30/version-068#interested-in-helping-react-native-stabilize-new-releases">Interested in helping React Native stabilise new releases?</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="highlights-of-068">Highlights of 0.68<a class="hash-link" href="#highlights-of-068" title="Direct link to heading">​</a></h2><p><a href="https://twitter.com/Andrei_Calazans" target="_blank" rel="noopener noreferrer">Andrei Calazans</a> helped us selecting the most relevant changes that 0.68 brings along:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="breaking-changes-and-version-bumps">Breaking changes and version bumps<a class="hash-link" href="#breaking-changes-and-version-bumps" title="Direct link to heading">​</a></h3><p>This version brings along a few breaking changes:</p><ul><li>React Native has been updated to Node 16, the latest LTS. Since on CI we test for LTS and the previous LTS, this change means that users are now required to use a version of Node &gt;= 14.</li><li>Android Gradle Plugin was updated to 7.0.1, enforcing JDK 11 for Android builds, so make sure to upgrade your configurations (we recommend you use the <code>zulu11</code> JDK flavor for both Intel and M1 Macs)</li><li>Removed <code>fallbackResource</code> from <code>RCTBundleURLProvider</code> API on iOS. This parameter can be safely removed from the method call without replacement.</li></ul><p>Tooling has also been updated - here are the main bumps:</p><ul><li>@react-native-community/cli to 7.0.3</li><li>Metro to 0.67</li><li>react-devtools-core dependency to 4.23.0</li><li>Flipper to 0.125.0</li><li>react-native-codegen to 0.0.9</li><li>Kotlin to 1.6.10</li><li>Soloader to 0.10.3</li><li>Gradle to 7.3</li><li>Android compile and target SDK to 31</li></ul><p>Also, thanks to <a href="https://github.com/facebook/react-native/commit/bd7caa64f5d6ee5ea9484e92c3629c9ce711f73c" target="_blank" rel="noopener noreferrer">this commit</a> by <a href="https://github.com/cortinico" target="_blank" rel="noopener noreferrer">Nicola Corti</a> the Android Gradle Plugin will download the default version of NDK by itself, so you don’t have to specify and install it separately anymore.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="other-improvements">Other improvements<a class="hash-link" href="#other-improvements" title="Direct link to heading">​</a></h3><p>There are a lot of other changes and fixes landed in this release, but here’s a small selection that you might be interested in:</p><ul><li><a href="https://github.com/GijsWeterings" target="_blank" rel="noopener noreferrer">Gijs Weterings</a> <a href="https://github.com/facebook/react-native/commit/5050e7eaa17cb417baf7c20eb5c4406cce6790a5" target="_blank" rel="noopener noreferrer">fixed Forwarding testID to RCTModalHostView</a> for easier E2E targeting of Modals.</li><li><a href="https://github.com/liamjones" target="_blank" rel="noopener noreferrer">Liam Jones</a> <a href="https://github.com/facebook/react-native/commit/9d2df5b8ae9" target="_blank" rel="noopener noreferrer">fixed an issue</a> where calling <code>console.error</code> caused the RedBox to appear alongside the LogBox.</li><li><a href="https://github.com/samkline" target="_blank" rel="noopener noreferrer">Sam Kline</a> <a href="https://github.com/facebook/react-native/commit/c8d823b9bd9619dfa1f5851af003cc24ba2e8830" target="_blank" rel="noopener noreferrer">fixed the empty blank screen</a> after a BundleDownloader failure in dev mode on Android.</li><li><a href="https://github.com/JeffreyHyer" target="_blank" rel="noopener noreferrer">Jeffrey Hyer</a> <a href="https://github.com/facebook/react-native/commit/9c5e177a79c" target="_blank" rel="noopener noreferrer">fixed an issue</a> where the KeyboardAvoidingView didn't work as expected with the <code>onLayout</code> prop.</li></ul><p>If you are interested in the full list of changes, you can read it in the changelog <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#0680" target="_blank" rel="noopener noreferrer">at the link here</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="acknowledgements">Acknowledgements<a class="hash-link" href="#acknowledgements" title="Direct link to heading">​</a></h3><p>This release includes 614 commits by 68 contributors! Thank you all!</p><p>We wanted to also thank the release testers and supporters who helped us catch regressions before the stable 0.68.0 release: you are incredibly valuable to the success of this release!</p><p>If you, your app or your company is interested in joining the “Release Tester” program, you can <a href="https://forms.gle/fPuPE1MZRDGWNqpd6" target="_blank" rel="noopener noreferrer">sign up here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="opting-in-to-the-new-architecture">Opting in to the New Architecture<a class="hash-link" href="#opting-in-to-the-new-architecture" title="Direct link to heading">​</a></h2><p>As briefly mentioned above, React Native 0.68 is the first version with opt-in support for the Fabric Renderer and the TurboModule system. This marks a crucial milestone for the rollout of the New React Native Architecture. To help you get up to speed with the changes, we added <a href="/architecture/overview">the Architecture section</a> to the website, where you can find several in-depth guides about internals of the new systems.</p><p>At the same time, we added the <a href="/docs/next/new-architecture-intro">migration guide</a> to the documentation and launched <a href="https://github.com/reactwg/react-native-new-architecture" target="_blank" rel="noopener noreferrer">a working group</a> dedicated to the New Architecture. You can find more information, including how to opt in, in <a href="/blog/2022/03/15/an-update-on-the-new-architecture-rollout">the previous blog post</a>.</p><p>Please note that the New Architecture still needs some fine tuning. Some of the third-party libraries that you depend on might not be migrated yet, and you may encounter issues that we haven’t discovered yet. If you do so, please report them to our <a href="https://github.com/reactwg/react-native-new-architecture" target="_blank" rel="noopener noreferrer">New Architecture Working Group</a>.</p><p><strong>About React 18:</strong> React 18's new rendering engine is not supported by React Native 0.68, this will happen in a future version. This is because React 18 relies on the New Architecture to benefit from the new capabilities presented in <a href="https://reactjs.org/blog/2022/03/29/react-v18.html" target="_blank" rel="noopener noreferrer">the React 18 announcement blog post</a>. For more information, see the <a href="https://www.youtube.com/watch?v=FZ0cG47msEk&amp;t=1530s" target="_blank" rel="noopener noreferrer">React Conf keynote here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="website-updates">Website updates<a class="hash-link" href="#website-updates" title="Direct link to heading">​</a></h2><p>Along with improvements to the main codebase, with the help of <a href="https://github.com/Simek" target="_blank" rel="noopener noreferrer">Simek</a>, <a href="https://github.com/Megatron4537" target="_blank" rel="noopener noreferrer">Megatron4537</a> and <a href="https://github.com/slorber" target="_blank" rel="noopener noreferrer">slorber</a> there have been quite a few improvements landing on the website too! In particular, you will now be able to learn how to contribute to React Native via the new section in the top toolbar.
Moreover, the “Contributing” section and the new “Architecture” section are now unversioned — there is now only one copy of these sections, rather than one for each React Native version.</p>]]></content>
        <author>
            <name>Lorenzo Sciandra</name>
            <uri>https://twitter.com/kelset</uri>
        </author>
        <author>
            <name>Andrei Shikov</name>
            <uri>https://twitter.com/shikasd_</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[An update on the New Architecture Rollout]]></title>
        <id>/2022/03/15/an-update-on-the-new-architecture-rollout</id>
        <link href="https://reactnative.dev/blog/2022/03/15/an-update-on-the-new-architecture-rollout"/>
        <updated>2022-03-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hi everyone,]]></summary>
        <content type="html"><![CDATA[<p>Hi everyone,
<a href="/blog/2022/01/21/react-native-h2-2021-recap#the-new-architecture-rollout-and-releases">As previously announced</a>:</p><blockquote><p>2022 is going to be the year of the New Architecture in open source</p></blockquote><p>If you still haven’t had the time to look into the New React Native Architecture (the Fabric Renderer and the TurboModule system), there is no better time to do it <strong>than now</strong>!</p><p>We would like to share with the community some initiatives and material we prepared to make sure everyone is onboard on this endeavor.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="the-working-group">The Working Group<a class="hash-link" href="#the-working-group" title="Direct link to heading">​</a></h3><p>Recently, we launched the <a href="https://github.com/reactwg/react-native-new-architecture" target="_blank" rel="noopener noreferrer">React Native New Architecture Working Group</a> on GitHub, a <em>discussion only</em> repository to coordinate and support the rollout of the New Architecture across the ecosystem.</p><p>We envision this working group as a space where the community can <strong>meet</strong>, share <strong>ideas</strong>, and <strong>discuss</strong> challenges during the adoption of the New Architecture. Moreover, we're going to use this working group to <strong>share</strong> information and updates with the wider community for the sake of transparency.</p><p>To keep the discussion focused, we decided to have this working group <strong>open to read</strong> publicly and <strong>restricted to write</strong> only for approved users.</p><p>If you wish to join the conversation, you can <a href="https://forms.gle/8emgdwFZXuzEpyyn9" target="_blank" rel="noopener noreferrer">fill in this form</a> to either <strong>apply or nominate</strong> someone that you think would be a valuable addition to the discussion.</p><p><strong>Everyone is welcome</strong> to apply to join the conversation.</p><p>As every discussion forum, we would like to stress once more the importance of being <strong>respectful</strong> and welcoming towards others’ opinions. Please take the chance to read our <a href="https://github.com/reactwg/react-native-new-architecture/blob/main/CODE_OF_CONDUCT.md" target="_blank" rel="noopener noreferrer"><strong>code of conduct</strong></a> if you haven’t yet done it.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="the-migration-guide">The Migration Guide<a class="hash-link" href="#the-migration-guide" title="Direct link to heading">​</a></h3><p>After several rounds of review &amp; feedback, we finally merged <strong>the Migration Guide</strong> (f.k.a. <em>the Playbook</em>). You can find it <a href="/docs/next/new-architecture-intro">on the website in the Guides section.</a></p><p>This Migration Guide will show you <strong>how to create a custom Fabric component or a TurboModule</strong> with a step-by-step approach. The guide will also show you how to <strong>adapt your existing app or library</strong> to use the New Architecture.</p><p>Moreover, we would like to remind you the brand-new <a href="/architecture/overview">Architecture section</a> of our website. There you can find several in-depth articles and explanation of the React Native internals. Specifically, <a href="/architecture/fabric-renderer">the Fabric section</a> can help you understand the rendering pipeline in the New Architecture world.</p><p>Finally, please consider <strong>sharing your feedback</strong> to this documentation material <a href="https://github.com/reactwg/react-native-new-architecture/discussions/7" target="_blank" rel="noopener noreferrer">on the working group</a>. We’re constantly looking for developer’s opinion, and we want to make sure we’re delivering the content that you find most useful.</p><p>Over the next months, we will look into refining and adding more documentation to help you further.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="the-new-architecture-template">The New Architecture Template<a class="hash-link" href="#the-new-architecture-template" title="Direct link to heading">​</a></h3><p>React Native <strong>0.68.0</strong> is close to release. This version of React Native marks a crucial milestone in the New Architecture Rollout as it’s the first version to include an <strong>opt-in switch</strong> in the <strong>new app template.</strong></p><p>This means that you will be able to try the New Architecture <strong>by changing one line</strong> in the template. We also added extensive <strong>comments and documentation</strong> to the template to make sure you don’t need extra reading to use it out of the box. We hope this will help you adopt the New Architecture by <strong>reducing the amount of code</strong> your have to write.</p><p>In the next releases, we will keep on updating the template to make it even more streamlined and simple to use.</p><p>To enable the New Architecture on either platform, you can:</p><ul><li>On iOS, run <code>RCT_NEW_ARCH_ENABLED=1 bundle exec pod install</code> inside the <code>ios</code> folder.</li><li>On Android, set the <code>newArchEnabled</code> property to <code>true</code> by <strong>either</strong>:<ul><li>Changing the corresponding line inside the <code>android/gradle.properties</code> file.</li><li>Set an environment variable <code>ORG_GRADLE_PROJECT_newArchEnabled=true</code></li><li>Invoke Gradle with <code>-PnewArchEnabled=true</code></li></ul></li></ul><p>Then you can <strong>run your app</strong> with <code>yarn react-native run-android</code> or <code>run-ios</code> and you’ll be running using Fabric and TurboModules enabled.</p><p>Please consider trying this new template, and <a href="https://github.com/reactwg/react-native-new-architecture/discussions/5" target="_blank" rel="noopener noreferrer">report any bug or unexpected behavior</a> that you might face. Over the last months we worked hard to fix bugs and build failures that would have been <strong>hard to catch</strong> without the constant community feedback and testing.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="the-3rd-party-libraries-ecosystem">The 3rd-party Libraries Ecosystem<a class="hash-link" href="#the-3rd-party-libraries-ecosystem" title="Direct link to heading">​</a></h3><p>The community won't be able to migrate to the New Architecture without the full support of <strong>3rd-party libraries author &amp; maintainers</strong>.</p><p>We understand how this can be a tedious process, and we understand the importance of supporting users on <strong>both</strong> old and New Architecture. Over the next months, we will focus on supporting our library developers to help them migrate over.</p><p>If you’re a <strong>library developer</strong>, <a href="https://github.com/reactwg/react-native-new-architecture/discussions/categories/libraries" target="_blank" rel="noopener noreferrer">we invite you to post an update</a> in the New Architecture working group with the <strong>status of your libraries</strong>. This will help you attract early adopters and us to understand if any library is facing a blocker.</p><p>If instead you’re a <strong>library user</strong>, you can <a href="https://github.com/reactwg/react-native-new-architecture/discussions/6" target="_blank" rel="noopener noreferrer">post a message here</a> to request a migration of a library. If we identify a library that becomes a blocker for a number of users, we will try to reach out to the maintainer and understand why they haven’t migrated yet.</p><p>Finally, we would like to give a shout out to Software Mansion for releasing a new version of <a href="https://github.com/software-mansion/react-native-screens" target="_blank" rel="noopener noreferrer"><code>react-native-screens</code></a>, which has support for both architectures. Moreover, they published a blog-post (<a href="https://blog.swmansion.com/introducing-fabric-to-react-native-screens-fd17bf18858e" target="_blank" rel="noopener noreferrer">Introducing Fabric to react-native-screens</a>) where they <strong>tell their migration story</strong>. We hope you will find this story inspiring and useful to tackle your migration.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="releases">Releases<a class="hash-link" href="#releases" title="Direct link to heading">​</a></h3><p>Work on the 0.68 pre-release has realized much of <a href="/blog/2022/01/19/version-067#improvements-to-release-process">the improved release process we had defined last half</a>.</p><p>We’re happy to share that with 0.68 we were able to:</p><ul><li>Successfully onboard release work to an internal rotation. Much of this is supported by <a href="/contributing/overview">improved documentation</a> on the release process which will reduce the bus factor of the release process.</li><li>Initiated discussions with partners to support a <a href="/contributing/release-roles-responsibilities#release-role-2--release-copilot">Copilot rotation</a>. We hope this effort will improve transparency of the process and inform our partners where to invest to support React Native releases and eco-system.</li><li><a href="https://github.com/reactwg/react-native-releases/discussions/11" target="_blank" rel="noopener noreferrer">Onboarded several Release Supporters and Testers from the community</a>. We had put a call-out for help last half and so many folks stepped up! The feedback from our testers and supporters have <strong>helped us fix crucial bugs</strong> and regressions, especially around the new architecture, for the upcoming release. Thank you to everyone who signed up and tested out the release!</li></ul><p>With React Native 0.69 we will continue refining this process, ideally getting partners to provide earlier release signal and onboarding co-pilots. As always, <a href="https://github.com/reactwg/react-native-releases/discussions" target="_blank" rel="noopener noreferrer">any feedback is more than welcome</a>. If you’d like to join as a release tester or supporter, <a href="https://forms.gle/fPuPE1MZRDGWNqpd6" target="_blank" rel="noopener noreferrer">please sign up here</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="towards-hermes-as-default-engine">Towards Hermes as Default engine<a class="hash-link" href="#towards-hermes-as-default-engine" title="Direct link to heading">​</a></h3><p>One of the crucial point of the New Architecture Rollout is the adoption of the new JavaScript engine: <strong>Hermes.</strong></p><p>With the New React Native Architecture, we’re going to <strong>set Hermes as default engine</strong>. This means that all the new documentation and templates will have Hermes enabled.</p><p>Please note that we'll continue working with the community to make sure <strong>other engines</strong>, such as JSC (JavaScript Core), <strong>are supported</strong>. You can still use the engine you wish, but you’ll have to <strong>explicitly disable Hermes</strong>.</p><p>To improve the stability of Hermes, we’re working towards changing the <strong>distribution model</strong> of Hermes. Specifically, we envision the Hermes release process <strong>to be closer</strong> to the React Native release process.</p><p>This will allow us to ship a version of React Native, with a bundled JS engine that is <strong>fully compatible</strong>. You won’t have to deal with run-time crashes and Hermes incompatibilities that are really hard to debug and understand.</p><p>Moreover, this will <strong>shorten the cycle</strong> for picking up <strong>improvements</strong> and bug fixes in Hermes, which will allow us to be more <strong>responsive</strong> to the needs of React Native users.</p><p>We will be sharing more on this matter in the coming months. In the meanwhile, feel free to <a href="https://github.com/reactwg/react-native-new-architecture/discussions/4" target="_blank" rel="noopener noreferrer">join the discussion</a> about it on the Working Group.</p><p>If you haven’t tried Hermes yet, now is the time to give it a go. And please make sure to flag any issues or blockers you might face.</p><p>With this, that’s a wrap.</p><p>I’d like to thank Andrei, Aleksandar, Dmitry, Eli, Luna, Héctor &amp; Neil for reviewing this blog-post and providing valuable contributions to those efforts.</p><p>And looking forward to <strong>reading your migration stories</strong>.</p>]]></content>
        <author>
            <name>Nicola Corti</name>
            <uri>https://twitter.com/cortinico</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native - H2 2021 Recap]]></title>
        <id>/2022/01/21/react-native-h2-2021-recap</id>
        <link href="https://reactnative.dev/blog/2022/01/21/react-native-h2-2021-recap"/>
        <updated>2022-01-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[While we're all still excited for the release of React Native 0.67, we want to take a moment to celebrate what the community achieved in the last half and share what we have on the horizon for the future of React Native.]]></summary>
        <content type="html"><![CDATA[<p>While we're all still excited for the <a href="/blog/2022/01/19/version-067">release of React Native 0.67</a>, we want to take a moment to <strong>celebrate</strong> what the community achieved in the last half and share what we have on the <strong>horizon</strong> for the future of React Native.</p><p>Specifically, H2 2021 was an <a href="/blog/2021/08/19/h2-2021#pushing-the-technology-forward">exciting half for both us and the community</a> where we had the opportunity to invest more in our open-source ecosystem. We revamped some of our processes and created new ones from scratch that will help you, us, and the community to enjoy a <strong>better</strong> React Native experience.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="repository-health">Repository Health<a class="hash-link" href="#repository-health" title="Direct link to heading">​</a></h2><p>In H2 2021, we invested in tackling some of the <em>OSS debt</em> that our repository built up over the years. Specifically, most of our focus was around <strong>pull requests</strong>. We built an internal process to make sure all the new pull requests are addressed in a timely manner.</p><p>Although this is not a complete list, we would like to highlight some <strong>impactful</strong> PRs we received from our contributors:</p><ul><li><strong>Accessibility</strong><ul><li><a href="https://github.com/facebook/react-native/pull/31630" target="_blank" rel="noopener noreferrer">#31630</a> <code>Added Support for Entrance/exit from collection by Flatlist</code> by <a href="https://github.com/anaskhraza" target="_blank" rel="noopener noreferrer">@anaskhraza</a></li></ul></li><li><strong>Crash</strong><ul><li><a href="https://github.com/facebook/react-native/pull/29452" target="_blank" rel="noopener noreferrer">#29452</a> <code>Fix - TextInput Drawable to avoid Null Pointer Exception RuntimeError</code> by <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">@fabriziobertoglio1987</a></li></ul></li><li><strong>Display</strong><ul><li><a href="https://github.com/facebook/react-native/pull/31777" target="_blank" rel="noopener noreferrer">#31777</a> <code>fix: TouchableNativeFeedback ripple starts on previous touch location</code> by <a href="https://github.com/intergalacticspacehighway" target="_blank" rel="noopener noreferrer">@intergalacticspacehighway</a></li><li><a href="https://github.com/facebook/react-native/pull/31789" target="_blank" rel="noopener noreferrer">#31789</a> <code>Fix support for blobs larger than 64 KB on Android</code> by <a href="https://github.com/tomekzaw" target="_blank" rel="noopener noreferrer">@tomekzaw</a></li><li><a href="https://github.com/facebook/react-native/pull/31007" target="_blank" rel="noopener noreferrer">#31007</a> <code>Fix selectionColor doesn't style Android TextInput selection handles</code> by <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">@fabriziobertoglio1987</a></li><li><a href="https://github.com/facebook/react-native/pull/32398" target="_blank" rel="noopener noreferrer">#32398</a> <code>Fix Android border positioning regression</code> by <a href="https://github.com/oblador" target="_blank" rel="noopener noreferrer">@oblador</a></li><li><a href="https://github.com/facebook/react-native/pull/29099" target="_blank" rel="noopener noreferrer">#29099</a> <code>[Android] Allows to set individual (left,top,right,bottom) dotted/dashed</code> by <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">@fabriziobertoglio1987</a></li><li><a href="https://github.com/facebook/react-native/pull/29117" target="_blank" rel="noopener noreferrer">#29117</a> <code>[Android] Fix font weight numeric values</code> by <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">@fabriziobertoglio1987</a></li></ul></li><li><strong>Interaction</strong><ul><li><a href="https://github.com/facebook/react-native/pull/28995" target="_blank" rel="noopener noreferrer">#28995</a> <code>[Android] Fix TextInput Cursor jumping to the right when placeholder null</code> by <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">@fabriziobertoglio1987</a></li><li><a href="https://github.com/facebook/react-native/pull/28952" target="_blank" rel="noopener noreferrer">#28952</a> <code>[Android] Fix non selectable Text in FlatList</code> by <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">@fabriziobertoglio1987</a></li><li><a href="https://github.com/facebook/react-native/pull/29046" target="_blank" rel="noopener noreferrer">#29046</a> <code>[Android] onKeyPress event not fired with numeric keys</code> by <a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">@fabriziobertoglio1987</a></li><li><a href="https://github.com/facebook/react-native/pull/31500" target="_blank" rel="noopener noreferrer">#31500</a> <code>fix#29319 - ios dismiss modal</code> by <a href="https://github.com/intergalacticspacehighway" target="_blank" rel="noopener noreferrer">@intergalacticspacehighway</a></li><li><a href="https://github.com/facebook/react-native/pull/32179" target="_blank" rel="noopener noreferrer">#32179</a> <code>Fix: multiline textinput start "jerking" when trying to move cursor.</code> by <a href="https://github.com/xiankuncheng" target="_blank" rel="noopener noreferrer">@xiankuncheng</a></li><li><a href="https://github.com/facebook/react-native/pull/29039" target="_blank" rel="noopener noreferrer">#29039</a> <code>Fix to make taps on views outside parent bounds work on Android</code> by <a href="https://github.com/hsource" target="_blank" rel="noopener noreferrer">@hsource</a></li></ul></li><li><strong>Performance</strong><ul><li><a href="https://github.com/facebook/react-native/pull/31764" target="_blank" rel="noopener noreferrer">#31764</a> <code>Optimize font handling on iOS</code> by <a href="https://github.com/Adlai-Holler" target="_blank" rel="noopener noreferrer">@Adlai-Holler</a></li><li><a href="https://github.com/facebook/react-native/pull/32536" target="_blank" rel="noopener noreferrer">#32536</a> <code>Don't reconstruct app component on split-screen</code> by <a href="https://github.com/Somena1" target="_blank" rel="noopener noreferrer">@Somena1</a></li></ul></li><li><strong>Testing</strong><ul><li><a href="https://github.com/facebook/react-native/pull/31401" target="_blank" rel="noopener noreferrer">#31401</a> <code>Add unit tests for VirtualizedList render quirks</code> by <a href="https://github.com/NickGerleman" target="_blank" rel="noopener noreferrer">@NickGerleman</a></li></ul></li></ul><p>Some of those PRs addressed issues that were impacting both Meta and the overall OSS community, given the number of reactions on the corresponding issue they closed.</p><p>There are so many more PRs we would like to call out, and we want to <strong>thank</strong> again all the people that are spending their time to help us address bugs and improve React Native.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="community-engagement">Community Engagement<a class="hash-link" href="#community-engagement" title="Direct link to heading">​</a></h2><p>At the beginning of the half we set a goal to <strong>communicate</strong> with our community more and set process for the behavior to continue. Here were some of our engagements in H2 2021:</p><ul><li>We had the opportunity to participate in <a href="https://www.react-native.eu/" target="_blank" rel="noopener noreferrer">React Native EU</a> with a talk from <a href="https://twitter.com/joshuaisgross" target="_blank" rel="noopener noreferrer">Joshua Gross</a> - <a href="https://www.youtube.com/watch?v=xKOkILSLs0Q&amp;t=3987s" target="_blank" rel="noopener noreferrer">Bringing the Fabric renderer to the “Facebook” app</a></li><li>We hosted an <a href="https://www.reddit.com/r/reactnative/comments/pzdo1r/react_native_team_aua_thursday_oct_14_9am_pt/" target="_blank" rel="noopener noreferrer">“Ask Us Anything“ (AUA) on Reddit</a> and received over 100 questions! AUAs are a great opportunity for both us, to get a sense of the community engagement, and you all, to ask any kind of questions. If you haven’t yet, make sure you check the answers as some of them are extremely insightful</li><li>We shared our <a href="https://reactnative.dev/blog/2021/08/26/many-platform-vision" target="_blank" rel="noopener noreferrer">Many Platform Vision</a>, a guide for gotchas for <a href="https://reactnative.dev/blog/2021/09/01/preparing-your-app-for-iOS-15-and-android-12" target="_blank" rel="noopener noreferrer">Android 12 and iOS 15</a>, and the progress and <a href="https://reactnative.dev/blog/2021/10/26/toward-hermes-being-the-default" target="_blank" rel="noopener noreferrer">vision for Hermes to become the default JS engine</a> for React Native!</li><li>Our own <a href="https://twitter.com/fkgozali" target="_blank" rel="noopener noreferrer">Kevin Gozali</a> appeared on <a href="https://reactnativeradio.com/episodes/rnr-222-the-new-architecture-with-kevin-gozali-from-the-rn-core-team" target="_blank" rel="noopener noreferrer">an episode of React Native Radio podcast</a> to talk about the new architecture.</li><li>At <a href="https://conf.reactjs.org/" target="_blank" rel="noopener noreferrer">ReactConf 2021</a>, ReactConf <a href="https://twitter.com/rickhanlonii" target="_blank" rel="noopener noreferrer">Rick Hanlon</a> shared the unified many-platform vision for React and React Native. Moreover, <a href="https://twitter.com/EricRozell" target="_blank" rel="noopener noreferrer">Eric Rozell</a> and <a href="https://twitter.com/moyessa" target="_blank" rel="noopener noreferrer">Steven Moyes</a> got to share the amazing progress React Native Desktop has made in supporting both Meta and Microsoft apps and showcasing the Many Platform Vision in practice.</li></ul><p>Beyond sharing more updates in H2 2021, we also <strong>leaned</strong> on our community more than ever. We relied on critical feedback from contributors as they dogfooded early drafts of the New Architecture material. As well, we were heavily supported by the expertise of our community in debugging critical release issues and improvements.</p><p>There is a wealth of knowledge that our community brings into React Native, and we need to continue to nurture it.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="the-new-architecture-rollout-and-releases">The New Architecture Rollout and Releases<a class="hash-link" href="#the-new-architecture-rollout-and-releases" title="Direct link to heading">​</a></h2><p>2022 is going to be the year of the <strong>New Architecture in open source</strong>.</p><p>We’ve been working hard to deliver the infrastructure needed to rollout the New Architecture to apps and libraries. We involved some of our partners and core contributors/library maintainers to refine our support for the new architecture to get early stage feedback.</p><p>We are now preparing to release a new guide on our website: <a href="https://github.com/facebook/react-native-website/pull/2879" target="_blank" rel="noopener noreferrer">Getting Started with the New Architecture</a>. That will be the entry point to a collection of material that we’re going to release in 2022 and will help you migrate/start your project with the new architecture.</p><p>Moreover, we would like to stress the <a href="https://github.com/facebook/react-native-website/pull/2879" target="_blank" rel="noopener noreferrer">importance of <strong>giving feedback</strong></a> on the New Architecture material. We’re still in the process of finalizing the last details and your input will help everyone adopt the new architecture more seamlessly.</p><p><strong>Releases</strong> play a critical role in the New Architecture rollout. Our goal last half was to ensure any release blocking issues did not stagnate. We approached the problem by <a href="https://github.com/facebook/react-native/wiki/Releases" target="_blank" rel="noopener noreferrer">clarifying and improving process and responsibilities</a> for better accountability. Our release coordination now occurs in a <a href="https://github.com/reactwg/react-native-releases/discussions" target="_blank" rel="noopener noreferrer">dedicated discussions repository</a> with <a href="https://github.com/facebook/react-native/issues/new?assignees=&amp;labels=Needs%3A+Triage+%3Amag%3A%2CType%3A+Upgrade+Issue&amp;template=upgrade-regression-form.yml" target="_blank" rel="noopener noreferrer">clearer release issue reporting</a>.</p><p>In H1 2022, we will continue to iterate on release responsibilities to support new architecture rollout. If you’d like to help out testing release candidates or <a href="https://github.com/facebook/react-native/projects/18" target="_blank" rel="noopener noreferrer">working on improvements</a>, feel free to <a href="https://github.com/reactwg/react-native-releases/discussions/categories/improvements" target="_blank" rel="noopener noreferrer">join the discussion</a>!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="to-mobile-and-beyond">To Mobile and beyond<a class="hash-link" href="#to-mobile-and-beyond" title="Direct link to heading">​</a></h2><p>As you can see from <a href="https://conf.reactjs.org/" target="_blank" rel="noopener noreferrer">the ReactConf talk lineup</a>, React Native is not only Android &amp; iOS.</p><p>Earlier in 2021, we shared our <a href="https://reactnative.dev/blog/2021/08/26/many-platform-vision" target="_blank" rel="noopener noreferrer">Many Platform Vision</a>, and we had a successful time rolling out React Native on both Desktop and VR.</p><p>We’re looking forward to <strong>converging patterns</strong> that are platform-specific into the React Native experience.</p><p>Finally, we want to thank again the community for the enormous support in H2 2021. It’s always amazing to see how contributors come together and support each other on GitHub, fixing bugs, sharing their and helping us deliver React Native to millions of users.</p><p>Stay tuned and looking forward to an <strong>even more amazing 2022</strong> 🎉!</p>]]></content>
        <author>
            <name>Nicola Corti</name>
            <uri>https://twitter.com/cortinico</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.67]]></title>
        <id>/2022/01/19/version-067</id>
        <link href="https://reactnative.dev/blog/2022/01/19/version-067"/>
        <updated>2022-01-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Happy new year everyone! Today we are announcing the latest release of React Native, 0.67.0, along with some updates on the release process that we have been working on in the past few months.]]></summary>
        <content type="html"><![CDATA[<p>Happy new year everyone! Today we are announcing the latest release of React Native, 0.67.0, along with some updates on the release process that we have been working on in the past few months.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="sections">Sections<a class="hash-link" href="#sections" title="Direct link to heading">​</a></h3><ul><li><a href="/blog/2022/01/19/version-067#highlights-of-067">Highlights of 0.67</a></li><li><a href="/blog/2022/01/19/version-067#improvements-to-release-process">Improvements to Release Process</a></li><li><a href="/blog/2022/01/19/version-067#interested-in-helping-react-native-stabilise-new-releases">Interested in helping React Native stabilise new releases?</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="highlights-of-067">Highlights of 0.67<a class="hash-link" href="#highlights-of-067" title="Direct link to heading">​</a></h2><p>As mentioned in Meta's <a href="https://reactnative.dev/blog/2021/08/19/h2-2021" target="_blank" rel="noopener noreferrer">H2 2021 plans</a>, React Native is attempting more frequent releases for a shorter turnaround time for new features and fixes (like the new architecture) to land in the community. Naturally, many releases will focus on fixes and improvements.</p><p>Here are some notable changes coming in 0.67.0:</p><ul><li>Lean-core removals: <a href="https://github.com/facebook/react-native/commit/7a770526c626e6659a12939f8c61057a688aa623#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346" target="_blank" rel="noopener noreferrer">DatePickerAndroid</a></li><li>Bump Gradle version to 7.2, Bump Kotlin version to 1.5.31 <a href="https://github.com/facebook/react-native/commit/9ae3367431428748f5486c782199beb4f9c6b477" target="_blank" rel="noopener noreferrer">Bump Kotlin and Gradle versions (#32319)</a></li><li>A notable callout: 0.67 continues to depend on Hermes 0.9.0, unchanged from 0.66</li></ul><p>You can find the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0670" target="_blank" rel="noopener noreferrer">full changelog here</a>.</p><p>You can participate in the conversation on the status of this release at <a href="https://github.com/reactwg/react-native-releases/discussions/10" target="_blank" rel="noopener noreferrer">this discussion</a> - and, as always, to help you upgrade to this version, you can use the <a href="https://react-native-community.github.io/upgrade-helper/" target="_blank" rel="noopener noreferrer">upgrade helper</a> ⚛️</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="acknowledgements">Acknowledgements<a class="hash-link" href="#acknowledgements" title="Direct link to heading">​</a></h3><p>This release includes <a href="https://github.com/facebook/react-native/compare/0.66-stable...0.67-stable" target="_blank" rel="noopener noreferrer">379 commits with 74 contributors</a>! Thank you, to all our contributors (old and new)! You can find the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0670" target="_blank" rel="noopener noreferrer">full changelog here</a>.</p><p>We wanted to also thank the release testers who helped us make sure that 0.67.0 could reach your codebases without any massive regression. Specifically, we wanted to thank:</p><ul><li>Marc Rousavy (<a href="https://github.com/mrousavy" target="_blank" rel="noopener noreferrer">@mrousavy</a>) from <a href="https://margelo.io/" target="_blank" rel="noopener noreferrer">Margelo</a>, that surfaced a <a href="https://github.com/facebook/hermes/issues/649" target="_blank" rel="noopener noreferrer">regression for Hermes 0.10</a> (that would have never been caught on CI testing) which will be fixed in Hermes 0.11 in the 0.68 release of React Native.</li><li>The Reanimated team for quickly preparing a <a href="https://github.com/software-mansion/react-native-reanimated/releases/tag/2.2.4" target="_blank" rel="noopener noreferrer">0.67 compatible version</a> of their lib early in the 0.67 RC phase.</li><li>Elias Nahum (<a href="https://github.com/enahum" target="_blank" rel="noopener noreferrer">@enahum</a>) from <a href="https://mattermost.com/" target="_blank" rel="noopener noreferrer">Mattermost</a></li><li>Mike Hardy (<a href="https://github.com/mikeHardy" target="_blank" rel="noopener noreferrer">@mikeHardy</a>) working with <a href="https://invertase.io/" target="_blank" rel="noopener noreferrer">Invertase</a></li></ul><p>We appreciate also <a href="https://rainbow.me/" target="_blank" rel="noopener noreferrer">Rainbow</a>, <a href="https://comm.app/" target="_blank" rel="noopener noreferrer">Comm</a> and <a href="https://www.ledger.com/ledger-live" target="_blank" rel="noopener noreferrer">Ledger Live</a> for also being part of the pilot of the "Release Tester" program (more details below).</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="improvements-to-release-process">Improvements to Release Process<a class="hash-link" href="#improvements-to-release-process" title="Direct link to heading">​</a></h2><p>As mentioned, React Native has been restructuring the release pipeline to allow for more frequent releases such that new features and fixes can roll out faster to the community.</p><p>Over the last few months we tackled some issues that delay releases.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="coordination-and-knowledge-sharing">Coordination and Knowledge Sharing<a class="hash-link" href="#coordination-and-knowledge-sharing" title="Direct link to heading">​</a></h3><p>We invested in our documentation of releases to cover how to run a release, FAQs, coordination of release issues, etc – all of which can be found in this section of the <a href="https://github.com/facebook/react-native/wiki/Releases" target="_blank" rel="noopener noreferrer">react-native wiki</a>.
By documentation, releases are no longer blocked on any individual or tribal knowledge.</p><p>In addition to documentation, we have also revamped the coordination of releases and have moved discussion of pre-release status and patches to a dedicated discussion group: <a href="https://github.com/reactwg/react-native-releases/discussions" target="_blank" rel="noopener noreferrer">react-wg/react-native-releases</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="clarity-of-responsibility">Clarity of responsibility<a class="hash-link" href="#clarity-of-responsibility" title="Direct link to heading">​</a></h3><p>Following more documentation, release work can scale such that no one person is critical to running a release.</p><p>A React Native release is susceptible to a broad spectrum of potential points of failure and has a lot of dependencies and follow-up. Considering that usage of React Native varies across the community, it’s essential to have stakeholders involved in releases. We have defined a set of <a href="https://github.com/facebook/react-native/wiki/Release-Roles-and-Responsibilities" target="_blank" rel="noopener noreferrer">roles and responsibilities in supporting a release</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="release-candidate-signal">Release candidate signal<a class="hash-link" href="#release-candidate-signal" title="Direct link to heading">​</a></h3><p>Another issue with releases is getting a good signal that a release will not suffer from build regressions. This can be addressed with growing investment in testing build variants, etc. but signal from adoption will continue to be useful for some time.</p><p>In the 0.67 release we piloted a “Release Tester” program where React Native developers working on Open Source apps <a href="https://github.com/facebook/react-native/wiki/Release-Roles-and-Responsibilities#release-tester-responsibilities" target="_blank" rel="noopener noreferrer">commit to testing release candidates</a> on their apps. Prior, there was no formal expectation that the community will test out release candidates to raise any potential issues. This program helps us get faster signal to ensure a level of stability of the release.</p><p>Open source React Native apps are particularly useful due to availability of source code to help debug any regressions. With this program in place, a release tester surfaced a regression in 0.67 and we were able to resolve it without thrashing the larger community with a faulty release.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="interested-in-helping-react-native-stabilise-new-releases">Interested in helping React Native stabilise new releases?<a class="hash-link" href="#interested-in-helping-react-native-stabilise-new-releases" title="Direct link to heading">​</a></h2><p>A great way to help us catch regressions is to integrate the React Native pre-release version <a href="https://www.npmjs.com/package/react-native" target="_blank" rel="noopener noreferrer"><code>react-native@next</code></a> or <a href="https://www.npmjs.com/package/react-native" target="_blank" rel="noopener noreferrer"><code>react-native@nightly</code></a> to your CI. For any regressions, you can <a href="https://github.com/facebook/react-native/issues/new?assignees=&amp;labels=Needs%3A+Triage+%3Amag%3A%2CType%3A+Upgrade+Issue&amp;template=upgrade-regression-form.yml" target="_blank" rel="noopener noreferrer">file a release issue</a> and notify the appropriate discussion.</p><p>If your app or company is interested in joining the “Release Tester” program, head to the dedicated section at the bottom of the <a href="https://github.com/facebook/react-native/wiki/Release-Roles-and-Responsibilities#release-tester-responsibilities" target="_blank" rel="noopener noreferrer">Release Roles and Responsibilities wiki</a> to learn more.</p><p>Lastly any help on trying our release candidates or helping unblock release issues is much appreciated!</p>]]></content>
        <author>
            <name>Lorenzo Sciandra</name>
            <uri>https://twitter.com/kelset</uri>
        </author>
        <author>
            <name>Luna Wei</name>
            <uri>https://twitter.com/lunaleaps</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Toward Hermes being the Default]]></title>
        <id>/2021/10/26/toward-hermes-being-the-default</id>
        <link href="https://reactnative.dev/blog/2021/10/26/toward-hermes-being-the-default"/>
        <updated>2021-10-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Since we announced Hermes in 2019, it has been increasingly gaining adoption in the community. The team at Expo, who maintain a popular meta-framework for React Native apps, recently announced experimental support for Hermes after being one of the most requested features of Expo. The team at Realm, a popular mobile database, also recently shipped its alpha support for Hermes. In this post, we want to highlight some of the most exciting progress we've made over the past two years to push Hermes towards being the best JavaScript engine for React Native. Looking forward, we are confident that with these improvements and more to come, we can make Hermes the default JavaScript engine for React Native across all platforms.]]></summary>
        <content type="html"><![CDATA[<p>Since <a href="https://engineering.fb.com/2019/07/12/android/hermes/" target="_blank" rel="noopener noreferrer">we announced Hermes in 2019</a>, it has been increasingly gaining adoption in the community. The team at <a href="https://expo.dev/" target="_blank" rel="noopener noreferrer">Expo</a>, who maintain a popular meta-framework for React Native apps, recently <a href="https://blog.expo.dev/expo-sdk-42-579aee2348b6" target="_blank" rel="noopener noreferrer">announced experimental</a> <a href="https://blog.expo.dev/expo-sdk-43-beta-is-now-available-47dc54a8d29f" target="_blank" rel="noopener noreferrer">support</a> for Hermes after being <a href="https://expo.canny.io/feature-requests/p/enabling-hermes" target="_blank" rel="noopener noreferrer">one of the most requested features of Expo</a>. The team at <a href="https://realm.io/" target="_blank" rel="noopener noreferrer">Realm</a>, a popular mobile database, also recently shipped its <a href="https://github.com/realm/realm-js/issues/3940" target="_blank" rel="noopener noreferrer">alpha support</a> for Hermes. In this post, we want to highlight some of the most exciting progress we've made over the past two years to push Hermes towards being <em>the best</em> JavaScript engine for React Native. Looking forward, we are confident that with these improvements and more to come, we can make Hermes the default JavaScript engine for React Native across all platforms.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="optimizing-for-react-native">Optimizing for React Native<a class="hash-link" href="#optimizing-for-react-native" title="Direct link to heading">​</a></h2><p>Hermes’s defining feature is how it performs compilation work ahead-of-time, meaning that React Native apps with Hermes enabled ship with precompiled optimized bytecode instead of plain JavaScript source. This drastically reduces the amount of work needed to start up your product for users. Measurements from both Facebook and community apps have suggested that enabling Hermes often cut a product’s TTI (or <a href="https://web.dev/interactive/" target="_blank" rel="noopener noreferrer">Time-To-Interactive</a>) metric by nearly half.</p><p>That being said, we’ve been working on improving Hermes in many other aspects to make it even better as a JavaScript engine specialized for React Native.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="building-a-new-garbage-collector-for-fabric">Building a New Garbage Collector for Fabric<a class="hash-link" href="#building-a-new-garbage-collector-for-fabric" title="Direct link to heading">​</a></h3><p>With the upcoming <a href="https://github.com/react-native-community/discussions-and-proposals/issues/4" target="_blank" rel="noopener noreferrer">Fabric</a> renderer in the new React Native architecture, it will be possible to synchronously call JavaScript on the UI thread. However, this means if the JavaScript thread takes too long to execute, it can cause noticeable UI frame drops and block user inputs. The <a href="https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html" target="_blank" rel="noopener noreferrer">concurrent rendering</a> enabled by React <a href="https://reactjs.org/docs/faq-internals.html#what-is-react-fiber" target="_blank" rel="noopener noreferrer">Fiber</a> will avoid scheduling long JavaScript tasks by splitting rendering work into chunks. However, there is another common source of latency from the JavaScript thread — when the JavaScript engine has to “stop the world” to perform a garbage collection (GC).</p><p>The previous default garbage collector in Hermes, <a href="https://hermesengine.dev/docs/gengc/" target="_blank" rel="noopener noreferrer">GenGC</a>, was a single-threaded generational garbage collector. The new generations uses a typical semi-space copying strategy, and the old generations uses a mark-compact strategy to make it really good at aggressively returning memory to the operating system. Due to its single-thread, GenGC has the downside of causing long GC pauses. On apps that are as complicated as Facebook for Android, we observed an average pause of 200ms, or 1.4s at p99. We have even seen it be as long as 7 seconds, considering the large and diverse user base of Facebook for Android.</p><p>In order to mitigate this, we implemented a brand new <em>mostly concurrent</em> GC named <a href="https://hermesengine.dev/docs/hades" target="_blank" rel="noopener noreferrer">Hades</a>. Hades collects its young generation exactly the same as GenGC, but it manages its old generation with a snapshot-at-the-beginning style mark-sweep collector. which can significantly reduce GC pause time by performing most of its work in a background thread without blocking the engine’s main thread from executing JavaScript code. <strong>Our statistics show that Hades only pauses for 48ms at p99.9 on 64-bit devices (34x faster than GenGC!)</strong> and around 88ms at p99.9 on 32-bit devices (where it operates as a single-threaded <em>incremental</em> GC). These pause time improvements can come at the cost of overall throughput, due to the need for more expensive write barriers, slower freelist based allocation (as opposed to a bump pointer allocator), and increased heap fragmentation. We think those are the right trade-offs, and we were able to achieve overall lower memory consumption via coalescing and additional memory optimizations that we’ll talk about.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="striking-on-performance-pain-points">Striking on Performance Pain Points<a class="hash-link" href="#striking-on-performance-pain-points" title="Direct link to heading">​</a></h3><p>Startup time of applications is critical to the success of many apps, and we are continuously pushing the boundary for React Native. For any new JavaScript feature we implement in Hermes, we carefully monitor their impact on production performance and ensure that they don’t regress metrics. At Facebook, we are currently experimenting with a <a href="https://github.com/facebook/metro/blob/c9a6fd75937c56645ab9e4d88fa820e63e057cd6/packages/metro-react-native-babel-preset/src/configs/main.js#L42" target="_blank" rel="noopener noreferrer">dedicated Babel transform profile for Hermes in Metro</a> to replace a dozen Babel transforms with Hermes’s native ESNext implementations. We were able to observe <strong>18-25% TTI improvements</strong> on many surfaces and <strong>overall bytecode size decreases</strong> and we expect to see similar results for OSS.</p><p>In addition to startup performance, we identified memory footprint as an opportunity for improvement in React Native apps especially for <a href="https://reactnative.dev/blog/2021/08/26/many-platform-vision#expanding-to-new-platforms" target="_blank" rel="noopener noreferrer">virtual reality.</a> Thanks to the low-level control we have as a JavaScript engine, we were able to deliver rounds of memory optimizations by squeezing bits and bytes out:</p><ol><li>Previously, all JavaScript values were represented as 64-bit NaN-boxing encoded tagged values to represent floating point doubles and pointers on 64-bit architecture. However, this is wasteful in practice because most numbers are small integers (SMI) and JavaScript heap of client-side applications is not expected to be larger than 4GiB generally. To address this, we introduced a new 32-bit encoding in which SMI and pointers are encoded in 29 bits (because pointers are 8-byte aligned, we can assume the bottom 3 bits are always zero), and the rest of JS numbers are boxed onto the heap. <strong>This reduced the JavaScript heap size by ~30%.</strong></li><li>Different kinds of JavaScript objects are represented as different kinds of GC-managed cells in the JavaScript heap. By aggressively optimizing the memory layout of headers for those cells, <strong>we are able to reduce memory usage by another ~15%</strong>.</li></ol><p>One of our key decisions with Hermes was to not implement a <a href="https://en.wikipedia.org/wiki/Just-in-time_compilation" target="_blank" rel="noopener noreferrer">just-in-time (JIT) compiler</a> because we believe that for most React Native apps, the additional warm-up costs and extra footprints on binary and memory would not actually be worthwhile. For years, we invested a lot of effort in optimizing interpreter performance and compiler optimizations to make Hermes’s throughput competitive with other engines for React Native workloads. We are continuing to focus on improving throughput by identifying performance bottlenecks from everywhere (interpreter dispatch loop, stack layout, object model, GC, etc.). Expect some more numbers in upcoming releases!</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="pioneering-at-vertical-integrations">Pioneering at Vertical Integrations<a class="hash-link" href="#pioneering-at-vertical-integrations" title="Direct link to heading">​</a></h3><p>At Facebook, we prefer to colocate projects within a large <a href="https://en.wikipedia.org/wiki/Monorepo" target="_blank" rel="noopener noreferrer">monorepo</a>. By having the engine (Hermes) and the host (React Native) closely iterating together, we opened a lot of room for vertical integrations. To name a few:</p><ul><li>Hermes supports <a href="https://reactnative.dev/docs/hermes#debugging-js-on-hermes-using-google-chromes-devtools" target="_blank" rel="noopener noreferrer">on-device JavaScript debugging with the Chrome debugger</a> by speaking the <a href="https://chromedevtools.github.io/devtools-protocol/" target="_blank" rel="noopener noreferrer">Chrome DevTools Protocol</a>. It’s better than the legacy “<a href="https://reactnative.dev/docs/debugging#chrome-developer-tools" target="_blank" rel="noopener noreferrer">Remote JS Debugging</a>” (which uses an in-app proxy to run JS in desktop Chrome) because it supports debugging synchronous native calls and guaranteed a consistent runtime environment. Together with React DevTools, Metro, Inspector, and so on, Hermes debugger is now part of <a href="https://reactnative.dev/blog/2020/03/26/version-0.62" target="_blank" rel="noopener noreferrer">Flipper</a> to provide a one-stop developer experience.</li><li>Objects allocated during the initialization path of React Native apps are often long-lived and don’t follow the <em>generational</em> <em>hypothesis</em> leveraged by generational GCs. Therefore, we <a href="https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/hermes/reactexecutor/OnLoad.cpp#L37-L42" target="_blank" rel="noopener noreferrer">configured Hermes in React Native</a> to allocate the first 32MiB directly into old generations (known as <em>pre-tenuring</em>) to avoid triggering GC pauses and delaying TTI.</li><li>The new React Native architecture is heavily based on <a href="https://github.com/react-native-community/discussions-and-proposals/issues/91" target="_blank" rel="noopener noreferrer">JSI (or JavaScript Interface)</a>, a lightweight, general-purposed API for embedding a JavaScript engine into a C++ program. By having the team maintaining the JS engine also maintains the JSI API implementation, we are confident in providing the best possible integration that is reliable, performant and battle-tested at the Facebook’s scale.</li><li>Getting JavaScript concurrency primitives (e.g. <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises" target="_blank" rel="noopener noreferrer">promises</a>) and platform concurrency primitives (e.g. <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide" target="_blank" rel="noopener noreferrer">microtasks</a>) both semantically correct and performant are critical to React concurrent rendering and the future of React Native apps. Historically, promises in React Native were <a href="https://github.com/facebook/react-native/blob/main/Libraries/Core/polyfillPromise.js#L37" target="_blank" rel="noopener noreferrer">polyfilled</a> using non-standardized <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate" target="_blank" rel="noopener noreferrer"><code>setImmediate</code></a> APIs. We are working on making native promises and microtasks from JS engines available via JSI, and introducing <a href="https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask" target="_blank" rel="noopener noreferrer"><code>queueMicrotask</code></a>, a recent addition to the web standard, to the platform, to better support modern asynchronous JavaScript code.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="bringing-along-the-whole-community">Bringing Along the Whole Community<a class="hash-link" href="#bringing-along-the-whole-community" title="Direct link to heading">​</a></h2><p>Hermes has been really great for us at Facebook. But our work is not done until our community can use Hermes to power experiences throughout the ecosystem, so that everyone leverage all of its features and to embrace its full potential.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="expanding-to-new-platforms">Expanding to New Platforms<a class="hash-link" href="#expanding-to-new-platforms" title="Direct link to heading">​</a></h3><p>Hermes was initially open sourced only for React Native on Android. Since then, we have been thrilled to see our members of the community expanding Hermes support into <a href="https://reactnative.dev/blog/2021/08/26/many-platform-vision" target="_blank" rel="noopener noreferrer">many other platforms that React Native’s ecosystem has expanded</a>.</p><p><a href="https://callstack.com/" target="_blank" rel="noopener noreferrer">Callstack</a> led the effort of bringing <a href="https://reactnative.dev/blog/2021/03/12/version-0.64" target="_blank" rel="noopener noreferrer">Hermes to iOS in React Native 0.64</a>. They wrote a <a href="https://callstack.com/blog/bringing-hermes-to-ios-in-react-native/" target="_blank" rel="noopener noreferrer">series of articles</a> and hosted a <a href="https://callstack.com/podcasts/react-native-0-64-with-hermes-for-ios-ep-5" target="_blank" rel="noopener noreferrer">podcast</a> on how they achieved it. According to their benchmarks, Hermes was able to <strong>consistently deliver ~40% improvement to startup and ~18% reduced memory on iOS</strong> compared to JSC for the Mattermost app, with only 2.4 MiB of app size overhead. I encourage you to <a href="https://callstack.com/blog/hermes-performance-on-ios/" target="_blank" rel="noopener noreferrer">see it live with your own eyes</a>.</p><p>Microsoft has been bringing <a href="https://microsoft.github.io/react-native-windows/docs/hermes" target="_blank" rel="noopener noreferrer">Hermes to React Native for Windows and macOS</a>. <a href="https://youtu.be/QMFbrHZnvvw?t=389" target="_blank" rel="noopener noreferrer">At Microsoft Build 2020</a>, Microsoft shared that Hermes’s memory impact (<a href="https://en.wikipedia.org/wiki/Working_set" target="_blank" rel="noopener noreferrer">working set</a>) is 13% lower than the Chakra engine on React Native for Windows. Recently, on some synthetic benchmarks, they’ve found Hermes 0.8 (shipped with Hades and aforementioned SMI and pointer compression optimization) <strong>uses 30%-40% less memory than other engines</strong>. Not surprisingly, the <a href="https://www.messenger.com/desktop" target="_blank" rel="noopener noreferrer">desktop Messenger</a> video calling experience built on React Native, is also powered by Hermes.</p><p>Last but not least, Hermes has also been powering all virtual reality experiences built with the React family of technologies on Oculus, including Oculus Home.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="supporting-our-community">Supporting our Community<a class="hash-link" href="#supporting-our-community" title="Direct link to heading">​</a></h3><p>We acknowledge there are still blockers that prevent parts of the community from adopting Hermes and we are committed to building support for these missing features. Our goal is to be fully featured so that Hermes is the right choice for most React Native apps. Here is how the community has already shaped the Hermes roadmap:</p><ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Meta_programming" target="_blank" rel="noopener noreferrer"><code>Proxy</code> and <code>Reflect</code></a> were originally excluded from Hermes because Facebook does not use them. We were also concerned that adding Proxy would hurt property lookup performance even when Proxy is not used. But Proxy quickly become <a href="https://github.com/facebook/hermes/issues/33" target="_blank" rel="noopener noreferrer">the most requested feature</a> of Hermes due to popular libraries such as <a href="https://mobx.js.org/README.html" target="_blank" rel="noopener noreferrer">MobX</a> and <a href="https://immerjs.github.io/immer/" target="_blank" rel="noopener noreferrer">Immer</a>. We carefully evaluated and decided to build it just for the community, and we managed to implement it with very low cost. Since this is a feature we don’t use, we relied on our community to prove its stability. We started by testing Proxy behind a flag and created opt-in npm packages for <a href="https://github.com/facebook/hermes/issues/33#issuecomment-668374607" target="_blank" rel="noopener noreferrer">release v0.4</a> and <a href="https://github.com/facebook/hermes/issues/33#issuecomment-668374607" target="_blank" rel="noopener noreferrer">v0.5</a>, and it’s <a href="https://github.com/facebook/hermes/releases/tag/v0.7.0" target="_blank" rel="noopener noreferrer">enabled by default starting from v0.7</a>.</li><li><a href="https://hermesengine.dev/docs/intl" target="_blank" rel="noopener noreferrer">ECMAScript Internationalization API Specification (ECMA-402, or <code>Intl</code>)</a> was <a href="https://github.com/facebook/hermes/issues/23" target="_blank" rel="noopener noreferrer">the second most requested feature</a>. <code>Intl</code> is a huge set of APIs and often requires the implementation to include <strong>6MB worth</strong> of <a href="https://cldr.unicode.org/index" target="_blank" rel="noopener noreferrer">Unicode CLDR</a> data. This is why polyfills like <a href="https://github.com/formatjs/formatjs" target="_blank" rel="noopener noreferrer">FormatJS (a.k.a. <code>react-intl</code>)</a> and JS engines like the <a href="https://github.com/react-native-community/jsc-android-buildscripts#international-variant" target="_blank" rel="noopener noreferrer">international variant build of community JSC</a> are so huge. To avoid substantially increasing the binary size of Hermes, we decided to implement it with another strategy by consuming and mapping the ICU facilities provided by the libraries included in the operating systems, at the cost of some (often minor) variance in behaviors across platforms.<ul><li>Microsoft collaborated to build support on Android. It covers almost everything from ECMA-402 up to ES2020, <strong>with only a size impact as small as 3% (57-62K per ABI)</strong>. We ran <a href="https://twitter.com/tmikov/status/1336442786694893568" target="_blank" rel="noopener noreferrer">a poll on Twitter</a> and the results were strongly in favor of including <code>Intl</code> by default, so that’s what we did and it’s available starting from <a href="https://github.com/facebook/hermes/releases/tag/v0.8.0" target="_blank" rel="noopener noreferrer">release v0.8</a>.</li><li>Facebook has sponsored <a href="https://mlh.io/" target="_blank" rel="noopener noreferrer">Major League Hacking</a> to launch a <a href="https://news.mlh.io/welcoming-facebook-back-as-a-sponsor-of-the-2020-2021-mlh-fellowship-08-12-2020" target="_blank" rel="noopener noreferrer">remote open source fellowship program</a>. Last year, we launched the <a href="https://reactnative.dev/docs/profile-hermes" target="_blank" rel="noopener noreferrer">Hermes sampling profiler</a>. This year, our fellows will be working with members from Hermes, React Native, and Callstack, to add support for Hermes <code>Intl</code> on iOS. Stayed tuned!</li></ul></li><li>We appreciate that people have been working with us to discover issues affecting the community.<ul><li>People have helped us identify critical spec divergence such as <a href="https://github.com/facebook/hermes/issues/212" target="_blank" rel="noopener noreferrer">stability of <code>Array.prototype.sort</code></a> amended in <a href="https://github.com/tc39/ecma262/pull/1340" target="_blank" rel="noopener noreferrer">ES2019</a>. This has been fixed and will be available in the next release.</li><li>People found out that our default heap size limit was too small and caused <a href="https://github.com/facebook/hermes/issues/295" target="_blank" rel="noopener noreferrer">unnecessary GC pressure</a> and <a href="https://github.com/facebook/hermes/issues/511" target="_blank" rel="noopener noreferrer">OOM crashes</a> for many users who are not familiar with customizing Hermes’s GC configs. So we increased it from 512MiB to 3GiB to be more than sufficient for most users by default.</li><li>People also reported that our specialized <code>Function.prototype.toString</code> implementation <a href="https://github.com/facebook/hermes/issues/471#issuecomment-820123463" target="_blank" rel="noopener noreferrer">caused performance to drop in libraries doing improper feature detection</a> and <a href="https://github.com/facebook/hermes/issues/114#issuecomment-887106990" target="_blank" rel="noopener noreferrer">blocked users from doing source code injecting</a>. This helped us strengthen our stance that Hermes, whenever possible, should not get in the way of developers and to respect de-facto practices.</li></ul></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="summary">Summary<a class="hash-link" href="#summary" title="Direct link to heading">​</a></h2><p>In summary, our vision is to make Hermes ready to be the default JavaScript engine across all React Native platforms. We’ve already started working towards it, and we want to hear from all of you about this direction.</p><p>It’s extremely important for us to prepare the ecosystem for a smooth adoption. We encourage you to try out Hermes, and file issues on our <a href="https://github.com/facebook/hermes" target="_blank" rel="noopener noreferrer">GitHub repository</a> for any feedbacks, questions, feature requests and incompatibilities.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thanks">Thanks<a class="hash-link" href="#thanks" title="Direct link to heading">​</a></h2><p>We’d love to thank the Hermes team, the React Native team, and the many contributors from the React Native community for their work to improve Hermes.</p><p>I’d also love to personally thank (in alphabetic order) Eli White, Luna Wei, Neil Dhar, Tim Yung, Tzvetan Mikov, and many others for their help during the writing.</p>]]></content>
        <author>
            <name>Xuan Huang</name>
            <uri>https://twitter.com/huxpro</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.66]]></title>
        <id>/2021/10/01/version-066</id>
        <link href="https://reactnative.dev/blog/2021/10/01/version-066"/>
        <updated>2021-10-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we’re releasing React Native v0.66 for Android 12 and iOS 15 support alongside fixes and general updates.]]></summary>
        <content type="html"><![CDATA[<p>Today we’re releasing React Native v0.66 for Android 12 and iOS 15 support alongside fixes and general updates.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="highlights">Highlights<a class="hash-link" href="#highlights" title="Direct link to heading">​</a></h2><ul><li><a href="/blog/2021/10/01/version-066#handle-taps-on-child-views-outside-parent-boundaries-on-android">Handle taps on views outside parent bounds on Android</a></li><li><a href="/blog/2021/10/01/version-066#new-bluetooth-permissions-on-android">New Bluetooth Permissions on Android</a></li><li><a href="/blog/2021/10/01/version-066#better-support-for-apple-silicon-xcode-13-and-ios-15">Better Support for Apple Silicon, Xcode 13, and iOS 15</a></li><li><a href="/blog/2021/10/01/version-066#hermes-090">Hermes 0.9.0</a></li><li><a href="/blog/2021/10/01/version-066#nightly-and-commitly-releases">Nightly and “Commitly” Releases</a></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="handle-taps-on-child-views-outside-parent-boundaries-on-android">Handle taps on child views outside parent boundaries on Android<a class="hash-link" href="#handle-taps-on-child-views-outside-parent-boundaries-on-android" title="Direct link to heading">​</a></h3><p>Thanks to <a href="https://github.com/hsource" target="_blank" rel="noopener noreferrer">@hsource</a> for adding interaction support for children rendered outside of parent view boundaries via <code>overflow: visible</code>. This is a common use-case and aligns React Native on Android more closely with web standards.</p><p>Find more details on the <a href="https://github.com/facebook/react-native/pull/29039" target="_blank" rel="noopener noreferrer">pull request</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="new-bluetooth-permissions-on-android">New Bluetooth Permissions on Android<a class="hash-link" href="#new-bluetooth-permissions-on-android" title="Direct link to heading">​</a></h3><p>We’ve added support for <a href="https://developer.android.com/about/versions/12/features/bluetooth-permissions" target="_blank" rel="noopener noreferrer">new Bluetooth permissions</a> in preparation for Android 12 and we plan to update the <code>targetSDKVersion</code> to 31 in the next release.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="better-support-for-apple-silicon-xcode-13-and-ios-15">Better Support for Apple Silicon, Xcode 13, and iOS 15<a class="hash-link" href="#better-support-for-apple-silicon-xcode-13-and-ios-15" title="Direct link to heading">​</a></h3><p>This release provides a number of solutions to make Xcode builds for iOS on Apple Silicon (M1) Mac machines more reliable.</p><p>Notably, the new app template now includes a CocoaPods workaround (thanks to <a href="https://github.com/MikeHardy" target="_blank" rel="noopener noreferrer">@mikehardy</a>!).
To apply, make sure your app’s Podfile has <code>__apply_Xcode_12_5_M1_post_install_workaround(installer)</code> added in the <code>post_install</code> step.</p><p>In addition <code>RCT-Folly.podspec</code> has been <a href="https://github.com/facebook/react-native/commit/8b6d7fddd65a9b5caf599e8ff7b090a176a6f11f" target="_blank" rel="noopener noreferrer">updated to prevent arm64 linker failure</a>.</p><p>Check out this <a href="/blog/2021/09/01/preparing-your-app-for-iOS-15-and-android-12">post</a> we shared on preparing your app for iOS 15 and Android 12.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="hermes-090">Hermes 0.9.0<a class="hash-link" href="#hermes-090" title="Direct link to heading">​</a></h3><p>Hermes 0.9.0 is primarily about closing the gap between Hermes release cut point and this React Native release.</p><p>Among ~400 commits, there have been general bug fixes alongside memory and size wins.</p><p>See <a href="https://github.com/facebook/hermes/issues/586" target="_blank" rel="noopener noreferrer">Hermes 0.9.0 release issue</a> for more details</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="nightly-and-commitly-releases">Nightly and “Commitly” Releases<a class="hash-link" href="#nightly-and-commitly-releases" title="Direct link to heading">​</a></h3><p>In a <a href="/blog/2021/08/19/h2-2021">recent blog post</a> we shared that one of our goals in the second half of 2021 is to improve our release process to be faster and more stable. As part of this effort we are working to make React Native more stable on main and to reduce the bugs identified during our Release Candidate process.</p><p>While we have been publishing nightly releases of React Native for over a year, these releases haven’t been effectively used by most projects. They are now easier to access and we hope to use them as release candidates going forward. Nightly releases are published to npm under the “nightly” tag.</p><p>To improve the process of testing individual commits, React Native’s CI will now create a tarball artifact for each commit on the main and release branches as well as for each PR. We refer to them as commitlies. These commitlies will not be published to npm, but they can be downloaded directly from CircleCI. See instructions below.</p><p>Want to help get a PR merged? By trying out the related commitly and verifying the change, you will be providing valuable signal to help get the change landed!</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="using-nightly-releases-nightlies">Using Nightly Releases (Nightlies)<a class="hash-link" href="#using-nightly-releases-nightlies" title="Direct link to heading">​</a></h4><p>The process for migrating your project to a React Native nightly release is very similar to the one you would follow when upgrading to a regular version, with the exception that tools like the Upgrade Helper do not currently work with nightlies. With that in mind, we recommend that you first upgrade your project to the most recent stable release if you have not done so yet. Then, run <code>yarn upgrade react-native@nightly</code> to install the most recent nightly release. Note that there may be additional changes that are needed for your project to work properly on a nightly release.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="using-commitly-releases-commitlies">Using Commitly Releases (Commitlies)<a class="hash-link" href="#using-commitly-releases-commitlies" title="Direct link to heading">​</a></h4><figure><img loading="lazy" src="/blog/assets/0.66-artifact.png" alt="Screenshot of CircleCI artifact panel to find tarball" class="img_SS3x"><figcaption>Find the "build_npm_package-1" job related to a commit and head to the "Artifacts" panel to download the tarball for the commitly.</figcaption></figure><p>Just like with a nightly release, first make sure that your project has been upgraded to the most recent stable version. Then, go to the <a href="https://app.circleci.com/pipelines/github/facebook/react-native" target="_blank" rel="noopener noreferrer"><code>react-native</code> dashboard on Circle CI</a> and look up the workflow that was triggered by the commit in question. There, you should see a job named <code>build_npm_package</code>. That job will have an “Artifacts” panel which will provide a link that you may use to download a tarball file. You can then run the following:</p><div class="language-bash codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-bash codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1"># Update your react-native dependency to the tarball</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1"># using your preferred package manager</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ </span><span class="token function" style="color:#79b6f2">yarn</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">add</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">path to tarball</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ </span><span class="token function" style="color:#79b6f2">npm</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">add</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">path to tarball</span><span class="token operator" style="color:#fc929e">&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_JmGV" id="acknowledgements">Acknowledgements<a class="hash-link" href="#acknowledgements" title="Direct link to heading">​</a></h3><p>This release includes <strong>621 commits</strong> with <strong>92 contributors</strong>! Thank you to all our contributors new and old! You can find the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0660" target="_blank" rel="noopener noreferrer">full changelog here</a>.</p><p>As well, thank you to the following contributors for their support in preparing, testing and unblocking this release!</p><ul><li><a href="https://github.com/acoates-ms" target="_blank" rel="noopener noreferrer">@acoates-ms</a></li><li><a href="https://github.com/dulmandakh" target="_blank" rel="noopener noreferrer">@dulmandakh</a></li><li><a href="https://github.com/kelset" target="_blank" rel="noopener noreferrer">@kelset</a></li><li><a href="https://github.com/kraenhansen" target="_blank" rel="noopener noreferrer">@kraenhansen</a></li><li><a href="https://github.com/MikeHardy" target="_blank" rel="noopener noreferrer">@mikehardy</a></li><li><a href="https://github.com/NickGerleman" target="_blank" rel="noopener noreferrer">@NickGerleman</a></li><li><a href="https://github.com/pvinis" target="_blank" rel="noopener noreferrer">@pvinis</a></li><li><a href="https://github.com/satya164" target="_blank" rel="noopener noreferrer">@satya164</a></li><li><a href="https://github.com/Simek" target="_blank" rel="noopener noreferrer">@Simek</a></li><li><a href="https://github.com/swrobel" target="_blank" rel="noopener noreferrer">@swrobel</a></li><li><a href="https://github.com/thymikee" target="_blank" rel="noopener noreferrer">@thymikee</a></li><li><a href="https://github.com/tido64" target="_blank" rel="noopener noreferrer">@tido64</a></li><li><a href="https://github.com/titozzz" target="_blank" rel="noopener noreferrer">@titozzz</a></li></ul>]]></content>
        <author>
            <name>Luna Wei</name>
            <uri>https://twitter.com/lunaleaps</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Preparing Your App for iOS 15 and Android 12]]></title>
        <id>/2021/09/01/preparing-your-app-for-iOS-15-and-android-12</id>
        <link href="https://reactnative.dev/blog/2021/09/01/preparing-your-app-for-iOS-15-and-android-12"/>
        <updated>2021-09-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hello everyone!]]></summary>
        <content type="html"><![CDATA[<p>Hello everyone!</p><p>With new mobile OS versions releasing late this year, we recommend preparing your React Native apps beforehand to avoid regressions when the releases become generally available.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="ios-15">iOS 15<a class="hash-link" href="#ios-15" title="Direct link to heading">​</a></h2><p>The release date of iOS 15 hasn’t been announced yet, but based on previous iOS releases, it will likely be around September 16th. Please also account for App Store review time if any changes are required to prepare your app for iOS 15.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="what-to-watch-out-for">What to watch out for<a class="hash-link" href="#what-to-watch-out-for" title="Direct link to heading">​</a></h3><h4 class="anchor anchorWithStickyNavbar_JmGV" id="quicktype-bar">QuickType Bar<a class="hash-link" href="#quicktype-bar" title="Direct link to heading">​</a></h4><p>The way to disable <em>QuickType</em> bar in <em><a href="/docs/textinput">TextInput</a></em> has changed. <em>QuickType</em> bar is the bar above keyboard with three suggested words. In case your UI needs to have the bar hidden, setting <a href="/docs/textinput#autocorrect">autoCorrect</a> to <code>false</code> no longer disables <em>QuickType</em> bar in iOS 15 like earlier versions. In order to hide the <em>QuickType</em> bar, you need to also set <a href="/docs/textinput#spellcheck-ios">spellCheck</a> to <code>false</code>. This will disable spell check, the red underlines, in your <em>TextInput</em>. Disabling QuickType bar with spell check enabled is no longer an option.</p><figure><img loading="lazy" src="/blog/assets/ios-15-quicktype-bar.png" alt="Screenshot of QuickType bar" class="img_SS3x"><figcaption>QuickType bar with three suggested words</figcaption></figure><p>To disable QuickType bar in iOS 15, set prop <a href="/docs/textinput#spellcheck-ios">spellCheck</a> and <a href="/docs/textinput#autocorrect">autoCorrect</a> to <code>false</code>.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">TextInput</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#657b83">=</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag attr-value" style="color:#8dc891">something</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">autoCorrect</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript boolean" style="color:#ff8b50">false</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">spellCheck</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript boolean" style="color:#ff8b50">false</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e"></span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_JmGV" id="transparent-navigation-bar">Transparent Navigation Bar<a class="hash-link" href="#transparent-navigation-bar" title="Direct link to heading">​</a></h4><p>iOS 15 changes the default behaviour of the navigation bar. Unlike in iOS 14, the navigation bar becomes transparent when the content is scrolled all the way up. Make sure to watch out for this as it can make content difficult to read. For tips on how to work around this issue, check out <a href="https://developer.apple.com/forums/thread/682420" target="_blank" rel="noopener noreferrer">this thread</a>.</p><p><img loading="lazy" alt="Screenshot of navigation bar on iOS 14 and iOS 15" src="/assets/images/ios-15-navigation-bar-848434e416d217cea351622e47f107a7.jpg" width="2330" height="661" class="img_SS3x"></p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="how-to-install-ios-15">How to install iOS 15<a class="hash-link" href="#how-to-install-ios-15" title="Direct link to heading">​</a></h3><h4 class="anchor anchorWithStickyNavbar_JmGV" id="device">Device<a class="hash-link" href="#device" title="Direct link to heading">​</a></h4><p>If you have a spare device, you can join the <a href="https://beta.apple.com/sp/betaprogram/" target="_blank" rel="noopener noreferrer">beta program</a> and install iOS 15. At this point, beta releases are generally stable, but keep in mind that <strong>the upgrade to iOS 15 is irreversible</strong>.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="simulator">Simulator<a class="hash-link" href="#simulator" title="Direct link to heading">​</a></h4><p>To test your app on a simulator with iOS 15, you will need to download Xcode 13. You can find Xcode 13 <a href="https://developer.apple.com/xcode/" target="_blank" rel="noopener noreferrer">here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="android-12">Android 12<a class="hash-link" href="#android-12" title="Direct link to heading">​</a></h2><p>Android 12 will be released this autumn and it introduces some changes which can potentially affect your app experience. Traditionally, Google Play requires target SDK of your app to be upgraded before November of the following year. (see requirements for previous release <a href="https://developer.android.com/distribute/best-practices/develop/target-sdk" target="_blank" rel="noopener noreferrer">here</a>).</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="what-to-watch-out-for-1">What to watch out for<a class="hash-link" href="#what-to-watch-out-for-1" title="Direct link to heading">​</a></h3><h4 class="anchor anchorWithStickyNavbar_JmGV" id="overscroll-effect">Overscroll Effect<a class="hash-link" href="#overscroll-effect" title="Direct link to heading">​</a></h4><p>Android 12 introduces new <a href="https://developer.android.com/about/versions/12/overscroll" target="_blank" rel="noopener noreferrer">overscroll effect</a> which affects all scroll containers. As React Native scroll views are based on the native views, we recommend to check your scrollable containers to ensure the effect is applied correctly. You can opt-out from it by setting <a href="/docs/scrollview#overscrollmode-android"><code>overScrollMode</code></a> prop to <code>never</code>.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="permission-updates">Permission Updates<a class="hash-link" href="#permission-updates" title="Direct link to heading">​</a></h4><p>Android 12 allows users of your app to only provide access to the approximate location if you request it with <strong><code>ACCESS_FINE_LOCATION</code></strong> permission<strong>.</strong> Learn more about it <a href="https://developer.android.com/about/versions/12/approximate-location" target="_blank" rel="noopener noreferrer">here</a>.</p><p>Check out Google’s <a href="https://developer.android.com/about/versions/12/behavior-changes-all" target="_blank" rel="noopener noreferrer">detailed behavior changes</a> for all apps running on Android 12.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="how-to-install-android-12">How to install Android 12<a class="hash-link" href="#how-to-install-android-12" title="Direct link to heading">​</a></h3><h4 class="anchor anchorWithStickyNavbar_JmGV" id="device-1">Device<a class="hash-link" href="#device-1" title="Direct link to heading">​</a></h4><p>If you have a spare Android device, check if you’re able to install Android 12 Beta via <a href="https://developer.android.com/about/versions/12/get" target="_blank" rel="noopener noreferrer">instructions here.</a></p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="emulator">Emulator<a class="hash-link" href="#emulator" title="Direct link to heading">​</a></h4><p>If you don’t have a device available, you can set up an emulator following <a href="https://developer.android.com/about/versions/12/get#on_emulator" target="_blank" rel="noopener noreferrer">instructions here</a>.</p>]]></content>
        <author>
            <name>Samuel Susla</name>
            <uri>https://twitter.com/SamuelSusla</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Is Hiring Managers, To Expand Beyond Mobile]]></title>
        <id>/2021/08/30/react-native-is-hiring-managers</id>
        <link href="https://reactnative.dev/blog/2021/08/30/react-native-is-hiring-managers"/>
        <updated>2021-08-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We recently shared React Native’s Many Platform Vision for how expanding React to other platforms improves the framework for everyone else. We’ve been making significant progress on this vision over the last couple years by partnering with Microsoft on React Native for Windows and macOS, and Oculus on React Native in VR.]]></summary>
        <content type="html"><![CDATA[<p>We recently shared <a href="https://reactnative.dev/blog/2021/08/26/many-platform-vision" target="_blank" rel="noopener noreferrer">React Native’s Many Platform Vision</a> for how expanding React to other platforms improves the framework for everyone else. We’ve been making significant progress on this vision over the last couple years by partnering with Microsoft on React Native for Windows and macOS, and Oculus on React Native in VR.</p><p>As <a href="https://reactnative.dev/blog/2021/08/19/h2-2021" target="_blank" rel="noopener noreferrer">part of our plans beginning earlier this year</a>, we are growing our focus on these platforms and growing our teams to help us achieve our vision. In order to support our new teammates, and many more to come, <strong>we are hiring two Engineering Managers: one to help support React Native for Desktop, and one to support React Native for VR</strong>.</p><figure><img loading="lazy" src="/blog/assets/many-platform-vision-messenger-desktop.png" alt="Screenshot of the Messenger app on macOS" class="img_SS3x"><figcaption>React Native powers Video Calling in Messenger for Windows and macOS.</figcaption></figure><figure><img loading="lazy" src="/blog/assets/many-platform-vision-oculus-home.png" alt="Screenshot of Oculus Home in virtual reality" class="img_SS3x"><figcaption>React and Relay power the Oculus Home and many other virtual reality experiences.</figcaption></figure><p>We are looking for managers who will care deeply about the growth and success of our engineers, and are excited about our vision. Previous React or React Native experience is not required. This role is open to anyone in the United States. If this sounds like an interesting opportunity and you are interested in learning more, please apply on <a href="https://www.facebook.com/careers/v2/jobs/438516437547870" target="_blank" rel="noopener noreferrer">Facebook’s Career’s Page</a>. We look forward to hearing from you!</p>]]></content>
        <author>
            <name>Eli White</name>
            <uri>https://twitter.com/Eli_White</uri>
        </author>
        <category label="hiring" term="hiring"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native's Many Platform Vision]]></title>
        <id>/2021/08/26/many-platform-vision</id>
        <link href="https://reactnative.dev/blog/2021/08/26/many-platform-vision"/>
        <updated>2021-08-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[React Native has been very successful at raising the bar for mobile development, both at Facebook and elsewhere in the industry. As we interact with computers in new ways and as new devices are invented, we want React Native to be there for everyone. Although React Native was originally created to build mobile apps, we believe that focusing on many platforms and building to each platform’s strengths and constraints has a symbiotic effect. We have seen huge benefits when we extended this technology to desktop and virtual reality, and we're excited to share what this means for the future of React Native.]]></summary>
        <content type="html"><![CDATA[<p>React Native has been very successful at raising the bar for mobile development, both at Facebook and elsewhere in the industry. As we interact with computers in new ways and as new devices are invented, we want React Native to be there for everyone. Although React Native was originally created to build mobile apps, we believe that focusing on many platforms and building to each platform’s strengths and constraints has a symbiotic effect. We have seen huge benefits when we extended this technology to desktop and virtual reality, and we're excited to share what this means for the future of React Native.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="respecting-the-platform">Respecting the Platform<a class="hash-link" href="#respecting-the-platform" title="Direct link to heading">​</a></h2><p>Our first guiding principle is <a href="https://reactnative.dev/blog/2020/07/17/react-native-principles#native-experience" target="_blank" rel="noopener noreferrer">to match the expectations people have for each platform</a>. Android users expect accessible apps using TalkBack. Navigation should work the way it does in other Android apps. A button should look and feel the way buttons look and feel on Android. It should not look and feel like an iOS button. Although we seek to offer a consistent cross-platform developer experience, we resist the temptation to sacrifice users’ expectations.</p><p>We believe that React Native enables developers to meet users’ expectations while also gaining the benefits of a better developer experience. In this section, we share the following:</p><ol><li>By embracing platform constraints, we actually improve the experience on other platforms.</li><li>We can learn from institutional knowledge to build higher level cross-platform abstractions.</li><li>Other players on each platform inspire us to build better developer and user experiences.</li></ol><h3 class="anchor anchorWithStickyNavbar_JmGV" id="embracing-platform-constraints">Embracing Platform Constraints<a class="hash-link" href="#embracing-platform-constraints" title="Direct link to heading">​</a></h3><p>Specific device hardware or user expectations impose unique constraints and requirements. As an example, memory is typically more constrained on Android and VR headsets than on iOS, macOS, and Windows. As another example, users expect mobile apps to start up almost instantaneously, but they are less frustrated when desktop apps take longer to start up. <strong>We have found that by approaching these problems with React Native, we can more easily borrow lessons learned and code written for one platform, and apply them to other platforms.</strong></p><figure><img loading="lazy" src="/blog/assets/many-platform-vision-facebook-dating.png" alt="Screenshot of Facebook Dating on mobile" class="img_SS3x"><figcaption>React Native and Relay power over 1000 Facebook surfaces on Android and iOS.</figcaption></figure><p>For example, React Native relies on an optimization known as “view flattening” which is critical for reducing memory usage on Android. We never built this optimization for iOS because it does not bear the same memory constraints. Over the past few years as we built our new cross-platform renderer, we had to reimplement “view flattening”. But this time, it was written in C++ instead of platform-specific Java. Trying out this same optimization on iOS was now only a matter of flipping a switch. In the production Facebook app, we observed that this improved performance on iOS! We likely never would have built this for iOS, but our investment on Android was able to benefit our investment on iOS.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="learning-from-institutional-knowledge">Learning from Institutional Knowledge<a class="hash-link" href="#learning-from-institutional-knowledge" title="Direct link to heading">​</a></h3><p>One of the reasons that React Native was originally created was to reduce engineering silos. There is a tendency for Android engineers to be siloed from iOS engineers working on the same product. Android engineers review code for Android engineers and attend Android meetups and conferences. iOS engineers review code for iOS engineers and attend iOS meetups and conferences. Engineers working on different platforms bring unique domain and institutional knowledge about how to build great product experiences.</p><p>One of the best outcomes of cross-platform frameworks like React Native is how they bring together engineers with vastly different domain expertise. <strong>We believe that by targeting more platforms, we can accelerate cross-pollination of institutional knowledge between platform experts.</strong></p><p>As an example, the accessibility abstractions in React Native are influenced by how Android, iOS, and web each approach accessibility in different ways. This enabled us to build a common interface that improves how accessibility hints are handled on both mobile platforms.</p><p>As another example, our research into user perception of speed on the web led to concurrent features like Suspense. Over the past year, these features were vetted by the new <a href="http://facebook.com/" target="_blank" rel="noopener noreferrer">Facebook.com</a> website. Now with our new renderer, these features are making their way to React Native and influencing how we design event scheduling and priorities. The React team’s investment into improving the web experience is benefiting React Native for native platforms.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="competition-drives-innovation">Competition Drives Innovation<a class="hash-link" href="#competition-drives-innovation" title="Direct link to heading">​</a></h3><p>In addition to domain-specific engineers and meetups and conferences, each platform also brings other unique players solving similar problems. On the web, React (which directly powers React Native) frequently draws inspiration from other open source web frameworks like <a href="https://vuejs.org/" target="_blank" rel="noopener noreferrer">Vue</a>, <a href="https://preactjs.com/" target="_blank" rel="noopener noreferrer">Preact</a>, and <a href="https://svelte.dev/" target="_blank" rel="noopener noreferrer">Svelte</a>. On mobile, React Native has been inspired by other open source mobile frameworks, and we have been learning from other mobile frameworks built inside Facebook.</p><p><strong>We believe that competition leads to better outcomes for everyone in the long run.</strong> By studying what makes other players on each platform great, we can learn lessons that may apply to other platforms. For example, the race to simplify complex websites influenced the development of React and gave React Native a head start to offer a declarative framework for mobile apps. The demand for faster iteration cycles and build times for the web also led to the development of Fast Refresh which significantly benefited React Native. Similarly, performance optimizations in our internal mobile frameworks — especially around data fetching and parallelization — challenged us to improve React Native in a way that has also influenced React when we built the new <a href="http://facebook.com/" target="_blank" rel="noopener noreferrer">Facebook.com</a> website.</p><figure><img loading="lazy" src="/blog/assets/many-platform-vision-facebook-website.png" alt="Screenshot of the Facebook.com website" class="img_SS3x"><figcaption>React and Relay powers the <a href="http://facebook.com/" target="_blank" rel="noopener noreferrer">Facebook.com</a> website.</figcaption></figure><h2 class="anchor anchorWithStickyNavbar_JmGV" id="expanding-to-new-platforms">Expanding to New Platforms<a class="hash-link" href="#expanding-to-new-platforms" title="Direct link to heading">​</a></h2><p>React and React Native are at a turning point. React has <a href="https://reactjs.org/blog/2021/06/08/the-plan-for-react-18.html" target="_blank" rel="noopener noreferrer">started the road to a React 18 release</a>, and <a href="https://twitter.com/reactnative/status/1415099806507167745" target="_blank" rel="noopener noreferrer">the new React Native renderer is now fully powering the Facebook mobile apps</a>. Our team has grown substantially this year in order to support the growing adoption at Facebook. Teams developing on other platforms have noticed the adoption and see the opportunity for them to also reap the benefits of React Native.</p><p><strong>For the past year, we have been partnering with Microsoft and the Messenger team to create a truly native video calling experience on Windows and macOS.</strong> Due to the high scrutiny that we place on startup time for mobile apps, our initial implementation of desktop video calling using React Native completely blew away the performance of the Electron implementation that it replaced. For the first couple weeks of building this experience, we recorded videos of us resizing a window with multiple live video calls and marveled at the smooth frame rates.</p><p>Building for desktop has been very exciting for us. We have taken what we know about building mobile experiences and applied them to desktop with eyes wide open. We’ve expanded our horizons with multiple child windows, menu bars, system trays, and more. As we continue collaborating on new desktop Messenger features, we expect to find opportunities that influence how we build on web and mobile. If you want to stay up to date, our desktop collaboration work is taking place <a href="https://github.com/microsoft/react-native-windows" target="_blank" rel="noopener noreferrer">on GitHub</a>.</p><figure><img loading="lazy" src="/blog/assets/many-platform-vision-messenger-desktop.png" alt="Screenshot of the Messenger app on macOS" class="img_SS3x"><figcaption>React Native powers Video Calling in Messenger for Windows and macOS.</figcaption></figure><p><strong>We are also partnering more closely with <a href="https://tech.fb.com/ar-vr/" target="_blank" rel="noopener noreferrer">Facebook Reality Labs</a> to understand how React is uniquely positioned to deliver virtual reality experiences on Oculus.</strong> Building experiences in VR with React Native will be particularly interesting because of tighter memory constraints and user sensitivity to interaction latency.</p><p>Similar to how we approach React Native for mobile, we will be validating our technology at Facebook scale before we share anything publicly. A lot is still changing and we still have many questions. We want to have confidence that the technology is production-ready and reliable before sharing with the community.</p><p>Although most of the development for VR will still be internal, we hope to share more as soon as we can. We also anticipate that improvements to React Native for VR will surface in open source. For example, we anticipate that projects to reduce memory usage for VR use cases will also reduce memory usage for React Native on mobile and desktop experiences.</p><figure><img loading="lazy" src="/blog/assets/many-platform-vision-oculus-home.png" alt="Screenshot of Oculus Home in virtual reality" class="img_SS3x"><figcaption>React and Relay power the Oculus Home and many other virtual reality experiences.</figcaption></figure><p>When we reflect back on how the industry has adopted React, there has always been an appetite in the community for React on more platforms. Even before we announced React Native to the community, Netflix had already been crafting Gibbon, their custom renderer for building TV experiences with React. And before Facebook started building Messenger for desktop, <a href="https://www.youtube.com/watch?v=IUMWFExtDSg&amp;t=382s" target="_blank" rel="noopener noreferrer">Microsoft was already using React to build native desktop experiences in Office and Windows 10</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="summary">Summary<a class="hash-link" href="#summary" title="Direct link to heading">​</a></h2><p>In summary, our vision is to expand React Native's reach beyond mobile and we've already started by partnering with desktop and VR teams at Facebook. We know that when we embrace the platform constraints of each platform, learn from institutional knowledge, and gather inspiration from other players, it benefits every platform in the ecosystem. And most importantly, in doing so, we stay true to <a href="https://reactnative.dev/blog/2020/07/17/react-native-principles" target="_blank" rel="noopener noreferrer">our guiding principles</a>.</p><p>We are excited about what's to come as we continue to explore what many platforms unlocks for React Native. Connect with us (<a href="https://twitter.com/reactnative" target="_blank" rel="noopener noreferrer">@reactnative</a>) for more updates and share your thoughts!</p>]]></content>
        <author>
            <name>Christine Abernathy</name>
            <uri>https://twitter.com/abernathyca</uri>
        </author>
        <author>
            <name>Eli White</name>
            <uri>https://twitter.com/Eli_White</uri>
        </author>
        <author>
            <name>Luna Wei</name>
            <uri>https://twitter.com/lunaleaps</uri>
        </author>
        <author>
            <name>Timothy Yung</name>
            <uri>https://twitter.com/yungsters</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native in H2 2021]]></title>
        <id>/2021/08/19/h2-2021</id>
        <link href="https://reactnative.dev/blog/2021/08/19/h2-2021"/>
        <updated>2021-08-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Over the past year so much has changed in our world, React Native being no exception. We've welcomed new members to our team (whom we are excited to eventually meet in person!), our projects have matured and new opportunities have arisen. We're excited to share all this with you in this post and others to come!]]></summary>
        <content type="html"><![CDATA[<p>Over the past year so much has changed in our world, React Native being no exception. We've welcomed new members to our team (whom we are excited to eventually meet in person!), our projects have matured and new opportunities have arisen. We're excited to share all this with you in this post and others to come!</p><p>At Facebook, our team works in half-year cycles. Each half we review our strategy, set plans, and share them internally. Today, we want to share our H2 plans with you, our community.</p><p>H2 2021 is an exciting half for React Native. Our areas of focus include nurturing the community, beginning to roll out the new architecture to open source, and pushing the technology forward.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="setting-up-the-community-for-success">Setting up the Community for Success<a class="hash-link" href="#setting-up-the-community-for-success" title="Direct link to heading">​</a></h2><p>React Native’s open source ecosystem is one of its greatest strengths. We’ve identified the following areas as the best ways to grow our partnership with the community.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="community-engagement">Community Engagement<a class="hash-link" href="#community-engagement" title="Direct link to heading">​</a></h3><p>In order for everyone to move in the same direction, we want to continually communicate our vision and status to the community. Sharing our incremental progress publicly isn’t second-nature for us (yet). This half, we are committing to a more consistent content schedule that exercises the muscle and sets up processes to reduce friction. Beyond sharing our updates, we also want to use this opportunity to showcase the accomplishments of the community.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="new-architecture-rollout-and-releases">New Architecture Rollout and Releases<a class="hash-link" href="#new-architecture-rollout-and-releases" title="Direct link to heading">​</a></h3><p>In H1, <a href="https://twitter.com/reactnative/status/1415099806507167745" target="_blank" rel="noopener noreferrer">we finished rolling out the new React Native architecture</a> to all React Native mobile products in the Facebook app. Facebook is made up of surfaces like Marketplace Tab and Dating Profile, and we have migrated over 1000 surfaces!</p><p>In H2, we are beginning to bring this new architecture to the community. We have put together a playbook that shows how to migrate libraries and applications. We have already shared drafts with early partners that maintain popular React Native libraries. We expect to get their feedback, support them in upgrading their libraries, and learn how to improve our playbook and implementations. We plan on sharing the playbook more broadly as soon as the work stabilizes.</p><p>We are also focused on improving React Native’s release process. We will need frequent reliable releases to progressively ship the new React Native architecture. Our aim is to catch release-blockers earlier and to reduce the turn-around time. This will enable more predictable release timelines with less burden on contributors and developers.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="repository-health">Repository Health<a class="hash-link" href="#repository-health" title="Direct link to heading">​</a></h3><p>When developers evaluate a technology, an essential signal is the health of its repository. This impression is informed by signals such as pull request throughput, stars, age of last commit, and others. The React Native repository has historically lacked a process to ensure that issues and pull requests are reviewed in a timely manner. Our work this half is two-fold: we need to resolve a large backlog of contributions, and we need to build sustainable practices for handling incoming contributions. We hope this work will also set us up for success for more engagement from the community via issues and PRs as the community starts using the new architecture. You can follow our progress on the backlog using this <a href="https://github.com/facebook/react-native/projects/17" target="_blank" rel="noopener noreferrer">project board.</a></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="pushing-the-technology-forward">Pushing the Technology Forward<a class="hash-link" href="#pushing-the-technology-forward" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_JmGV" id="new-architectural-capabilities">New Architectural Capabilities<a class="hash-link" href="#new-architectural-capabilities" title="Direct link to heading">​</a></h3><p>As mentioned, our new architecture recently finished rolling out to the Facebook mobile apps! We are already building new capabilities that will change the performance curve for React Native. This includes supporting Concurrent Rendering in React Native. Concurrent Rendering enables React to pause and resume work and quickly respond to high priority events like a touch gesture. Something we are also really excited about is using Concurrent Rendering to make use of idle CPU cycles for rendering offscreen product features without slowing down onscreen user interactions.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="mobile-and-beyond">Mobile and Beyond<a class="hash-link" href="#mobile-and-beyond" title="Direct link to heading">​</a></h3><p>We have had overwhelming success with powering mobile experiences using React at Facebook, and we have seen amazing mobile products from our partners. Now we want to bring that success to more platforms! We believe that targeting many platforms lets us learn new lessons and further improve our offering on mobile platforms. (We will share more about this in a later post.) The exciting news is that we’ve already started taking steps towards making this a reality!</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="messenger-desktop">Messenger Desktop<a class="hash-link" href="#messenger-desktop" title="Direct link to heading">​</a></h4><p>Last summer, we <a href="https://twitter.com/reactnative/status/1286061933293010944" target="_blank" rel="noopener noreferrer">expanded our focus beyond mobile</a> by partnering with Microsoft to accelerate React Native development on Windows and macOS. We partnered with the Messenger team at Facebook to enable user experiences that are only possible on desktop, and to deliver huge performance wins over their previous Electron implementation. Our vision is to combine high quality, delightful, <em>native</em> desktop user experiences with the great developer experience of React Native.</p><p>The Messenger team has ambitious plans for the Messenger desktop apps, including finding new ways to further unleash the unique capabilities of desktop platforms and large screens. We are excited to continue enabling these experiences by investing more into React Native on desktop.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="react-native-in-virtual-reality">React Native in Virtual Reality<a class="hash-link" href="#react-native-in-virtual-reality" title="Direct link to heading">​</a></h4><p>Oculus has long used React Native to power core experiences like Store, where people buy applications and games in VR. In H2, React Native and Oculus are partnering to bring new exciting experiences to VR. We are also bringing optimizations and improvements from VR to mobile, and from mobile to VR. This will include expanding React Native to support unique requirements of VR — from new input types like controllers to new memory usage optimizations. This is the start of an exciting journey to explore and influence how immersive experiences can built for VR using React Native.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="summary">Summary<a class="hash-link" href="#summary" title="Direct link to heading">​</a></h3><p>We hope our H2 plans excite you as much as it does us, and we look forward to sharing more with you in the upcoming months! We will also be attending React Native EU on September 1, 2021 where teammate Joshua Gross (<a href="https://twitter.com/joshuaisgross" target="_blank" rel="noopener noreferrer">@joshuaisgross</a>) will share how we replaced the architecture for the world’s largest React Native app. <a href="https://www.react-native.eu/" target="_blank" rel="noopener noreferrer">Register for React Native EU</a> if you haven’t already! In the meantime, connect with us on Twitter (<a href="https://twitter.com/reactnative" target="_blank" rel="noopener noreferrer">@reactnative</a>) for updates on events, our roadmap, and much more.</p>]]></content>
        <author>
            <name>Luna Wei</name>
            <uri>https://twitter.com/lunaleaps</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.65]]></title>
        <id>/2021/08/17/version-065</id>
        <link href="https://reactnative.dev/blog/2021/08/17/version-065"/>
        <updated>2021-08-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we’re releasing React Native version 0.65 with a new version of Hermes, improvements to accessibility, package upgrades, and more.]]></summary>
        <content type="html"><![CDATA[<p>Today we’re releasing React Native version 0.65 with a new version of Hermes, improvements to accessibility, package upgrades, and more.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="whats-new-in-hermes-08">What's new in Hermes 0.8?<a class="hash-link" href="#whats-new-in-hermes-08" title="Direct link to heading">​</a></h2><p><a href="https://hermesengine.dev" target="_blank" rel="noopener noreferrer">Hermes</a>, Facebook’s open source JavaScript VM optimized for React Native, has been upgraded to version 0.8.1. Some of the stand-out features in this release are:</p><ul><li>A new concurrent garbage collector titled “Hades” which delivers up to 30 times shorter pause times on 64 bit devices. At Facebook, we saw this improve some CPU-intensive workloads by 20%-50%. You can <a href="https://hermesengine.dev/docs/hades/" target="_blank" rel="noopener noreferrer">learn more about Hades here</a>.</li><li><a href="https://hermesengine.dev/docs/intl" target="_blank" rel="noopener noreferrer">ECMAScript Internationalization API (ECMA-402, or <code>Intl</code>)</a> is now built into Hermes on Android and enabled by default, with only 57-62K per API size overhead (compared to <a href="https://github.com/react-native-community/jsc-android-buildscripts" target="_blank" rel="noopener noreferrer">JSC's 6MiB</a>). With this change, Hermes users no longer require locale polyfills. A big thank you to <a href="https://github.com/mganandraj" target="_blank" rel="noopener noreferrer">@mganandraj</a> and other partners at Microsoft for driving the implementation to make this happen!</li><li><a href="/blog/2021/03/12/version-0.64">Hermes on iOS</a> now <a href="https://github.com/facebook/hermes/pull/546" target="_blank" rel="noopener noreferrer">supports Apple M1 Macs and Mac Catalyst</a>!</li><li>Memory improvements including SMI (Small Integers) and pointer compression that <a href="https://twitter.com/tmikov/status/1385629737121243140" target="_blank" rel="noopener noreferrer">shrank JS heap by 30%</a>.</li><li>Changes to <code>Function.prototype.toString</code> that <a href="https://github.com/facebook/hermes/issues/471#issuecomment-820123463" target="_blank" rel="noopener noreferrer">fixed a performance drop due to improper feature detection</a> and <a href="https://github.com/facebook/hermes/issues/114" target="_blank" rel="noopener noreferrer">supports the source code injecting use case</a>.</li></ul><p>You can find the full <a href="https://github.com/facebook/hermes/releases" target="_blank" rel="noopener noreferrer">Hermes changelog here</a>.</p><p><a href="/docs/hermes#enabling-hermes">Follow steps here</a> to opt-in your app to Hermes if you haven’t already to leverage these new features and gains!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="accessibility-fixes-and-additions">Accessibility Fixes and Additions<a class="hash-link" href="#accessibility-fixes-and-additions" title="Direct link to heading">​</a></h2><p>Last year <a href="https://reactnative.dev/blog/2021/05/20/GAAD-One-Year-Later" target="_blank" rel="noopener noreferrer">Facebook took the GAAD pledge</a> to improve accessibility within React Native. 0.65 shares the results of this pledge and other accessibility wins! Some notable changes include:</p><ul><li>Allow specification of high contrast light and dark values for iOS. See <a href="/docs/dynamiccolorios">documentation</a> for more details.</li><li>Added <a href="/docs/accessibilityinfo#getrecommendedtimeoutmillis-android"><code>getRecommendedTimeoutMillis</code></a> API on Android. This exposes a user’s preferred default timeout value as set in Android’s accessibility options and is for users who may need extra time to review or reach controls, etc.</li><li>General fixes to ensure TalkBack/VoiceOver properly announce UI states such as <code>disabled</code> and <code>unselected</code> on components.</li></ul><p>You can follow along or contribute to our <a href="https://github.com/facebook/react-native/projects/15" target="_blank" rel="noopener noreferrer">outstanding accessibility issues</a> here!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="notable-dependency-version-updates-and-gotchas">Notable Dependency Version Updates and Gotchas<a class="hash-link" href="#notable-dependency-version-updates-and-gotchas" title="Direct link to heading">​</a></h2><ul><li><code>react-native-codegen</code> version <code>0.0.7</code> is now needed as a <code>devDependency</code> in the <code>package.json</code>.</li><li>JCenter has been sunsetted and read-only now. We have removed JCenter as a maven repository and updated dependencies to use MavenCentral and Jitpack.</li><li>Upgraded OkHttp from v3 to v4.9.1. See <a href="https://square.github.io/okhttp/upgrading_to_okhttp_4/" target="_blank" rel="noopener noreferrer">Upgrading to OkHttp 4</a> for more details on changes.</li><li>Upgraded to Flipper 0.93 to support Xcode 12.5. See <a href="https://github.com/facebook/flipper/blob/master/desktop/static/CHANGELOG.md" target="_blank" rel="noopener noreferrer">Flipper changelog here</a>.</li><li>Android Gradle Plugin 7 support</li><li>Apple Silicon requires a linker workaround. See <a href="https://github.com/react-native-community/releases/issues/238#issuecomment-890367992" target="_blank" rel="noopener noreferrer">@mikehardy’s note</a> about this.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thank-you">Thank You!<a class="hash-link" href="#thank-you" title="Direct link to heading">​</a></h2><p>This release includes over <strong>1100 commits</strong> from <strong>61 contributors</strong>. Thank you to everyone who has contributed and supported this release! You can find the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0650" target="_blank" rel="noopener noreferrer">full changelog here</a>.</p>]]></content>
        <author>
            <name>Luna Wei</name>
            <uri>https://twitter.com/lunaleaps</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The GAAD Pledge - One Year Later]]></title>
        <id>/2021/05/20/GAAD-One-Year-Later</id>
        <link href="https://reactnative.dev/blog/2021/05/20/GAAD-One-Year-Later"/>
        <updated>2021-05-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[It has been one year since Facebook took the GAAD Pledge to make React Native accessible and the project has exceeded our expectations. We are excited to announce that this project will continue throughout 2021 and want to update everyone on our progress so far. Following a thorough analysis of the accessibility gaps in React Native last year, work began on filling these gaps.]]></summary>
        <content type="html"><![CDATA[<p>It has been one year since Facebook took the <a href="https://diamond.la/GAADPledge/" target="_blank" rel="noopener noreferrer">GAAD Pledge</a> to make React Native accessible and the project has exceeded our expectations. We are excited to announce that this project will continue throughout 2021 and want to update everyone on our progress so far. Following a thorough analysis of the accessibility gaps in React Native last year, work began on filling these gaps.</p><p>We started with 90 outstanding gap analysis issues and from March 2021, when the project launched on GitHub, until now:</p><ul><li><p>11 issues have been closed by the community.</p></li><li><p>19 issues were evaluated and closed by the React Native team.</p></li><li><p>9 pull requests were merged.</p></li><li><p>1 pull request was merged into the React Native docs.</p></li></ul><p>We want to recognize and thank the React Native community for the significant progress towards a more accessible React Native over the past year. Every contributor's effort has counted in making progress on improving React Native Accessibility.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="fixes">Fixes<a class="hash-link" href="#fixes" title="Direct link to heading">​</a></h2><p>Two types of issues have been fixed in multiple components and one new functionality has been added to the API by the 9 pull requests.</p><ul><li><p>An issue with Disabled state has been addressed in seven components</p></li><li><p>An issue with Selected state was addressed in two components</p></li><li><p>A new addition to the React Native API added the ability to query AccessibilityManager.getRecommendedTimeoutMillis().</p></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="disabled-state-announcement-and-disable-function">Disabled State Announcement and Disable function<a class="hash-link" href="#disabled-state-announcement-and-disable-function" title="Direct link to heading">​</a></h3><p>One of the most prevalent issues found during the gap analysis was that some components do not announce or disable functionality. Now seven components announce their disabled state or disable click functionality.</p><p>Announces when Disabled</p><ul><li><p><code>Button</code> - <a href="https://github.com/facebook/react-native/pull/31001" target="_blank" rel="noopener noreferrer">#31001</a></p></li><li><p><code>Images</code> - <a href="https://github.com/facebook/react-native/pull/31252" target="_blank" rel="noopener noreferrer">#31252</a></p></li><li><p><code>ImageBackground</code> - <a href="https://github.com/facebook/react-native/pull/31252" target="_blank" rel="noopener noreferrer">#31252</a></p></li></ul><p>Disables click functionality when the component has a disabled prop</p><ul><li><p><code>Button</code> - <a href="https://github.com/facebook/react-native/pull/31001" target="_blank" rel="noopener noreferrer">#31001</a></p></li><li><p><code>Text</code> - <a href="https://github.com/facebook/react-native/commit/33ff4445dcf858cd5e6ba899163fd2a76774b641" target="_blank" rel="noopener noreferrer">React Native Team commit</a></p></li><li><p><code>Pressable</code> - <a href="https://github.com/facebook/react-native/commit/1c7d9c8046099eab8db4a460bedc0b2c07ed06df" target="_blank" rel="noopener noreferrer">React Native Team commit</a></p></li><li><p><code>TouchableHighlight</code> - <a href="https://github.com/facebook/react-native/pull/31135" target="_blank" rel="noopener noreferrer">#31135</a></p></li><li><p><code>TouchableOpacity</code> - <a href="https://github.com/facebook/react-native/pull/31108" target="_blank" rel="noopener noreferrer">#31108</a></p></li><li><p><code>TouchableNativeFeedback</code> - <a href="https://github.com/facebook/react-native/pull/31224" target="_blank" rel="noopener noreferrer">#31224</a></p></li><li><p><code>TouchableWithoutFeedback</code> - <a href="https://github.com/facebook/react-native/pull/31297" target="_blank" rel="noopener noreferrer">#31297</a></p></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="selected-state-announcement">Selected State Announcement<a class="hash-link" href="#selected-state-announcement" title="Direct link to heading">​</a></h3><p>There were some components that did not announce their selection when in focus. This behavior has now been fixed when the component is in focus and the AccessibilityState is set to selected or the component is changed to selected.</p><p>Announces when Selected</p><ul><li><p><code>Button</code> - <a href="https://github.com/facebook/react-native/pull/31001" target="_blank" rel="noopener noreferrer">#31001</a></p></li><li><p><code>TextInput</code> - <a href="https://github.com/facebook/react-native/pull/31144" target="_blank" rel="noopener noreferrer">#31144</a></p></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="accessibility-timeout-setting">Accessibility Timeout Setting<a class="hash-link" href="#accessibility-timeout-setting" title="Direct link to heading">​</a></h3><p>There was previously no way to query the accessibility timeout setting on Android. The fix added the ability to query <code>AccessibilityManager.getRecommendedTimeoutMillis()</code>. This queries the "Time to take action" before the UI elements auto-dismisses or auto-progresses.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="documentation-additions">Documentation Additions<a class="hash-link" href="#documentation-additions" title="Direct link to heading">​</a></h2><p>The React Native documentation must be updated to reflect each addition or change to the available APIs. The <a href="https://reactnative.dev/docs/next/accessibilityinfo#getrecommendedtimeoutmillis-android" target="_blank" rel="noopener noreferrer">new addition to the React Native documentation</a> covered the addition of <code>getRecommendedTimeoutMillis()</code> to AccessibilityInfo.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="community-involvement">Community Involvement<a class="hash-link" href="#community-involvement" title="Direct link to heading">​</a></h2><p>We want to thank all the contributors mentioned below who have submitted and merged pull requests as well as those who have reviewed and commented on issues.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="merged-pull-requests">Merged Pull Requests<a class="hash-link" href="#merged-pull-requests" title="Direct link to heading">​</a></h3><ul><li><a href="https://twitter.com/huzaifaaak" target="_blank" rel="noopener noreferrer">@huzaifaaak</a> closed 3 issues with:<ul><li><a href="https://github.com/facebook/react-native/pull/31001" target="_blank" rel="noopener noreferrer">Added talkback support for button accessibility: disabled prop #31001</a></li><li><a href="https://github.com/facebook/react-native/pull/31189" target="_blank" rel="noopener noreferrer">Accessibility/button test #31189</a></li></ul></li><li><a href="https://twitter.com/natural_clar" target="_blank" rel="noopener noreferrer">@natural_clar</a> closed 1 issue with:<ul><li><a href="https://github.com/facebook/react-native/pull/31135" target="_blank" rel="noopener noreferrer">feat: set disabled accessibilityState when <code>TouchableHighlight</code> is disabled #31135</a></li></ul></li><li><a href="https://github.com/fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">fabriziobertoglio1987</a> closed 2 issues with:<ul><li><a href="https://github.com/facebook/react-native/pull/31144" target="_blank" rel="noopener noreferrer">[Android] Selected State does not annonce when <code>TextInput</code> Component selected #31144</a></li><li><a href="https://github.com/facebook/react-native/pull/31252" target="_blank" rel="noopener noreferrer">Accessibility Fix Image does not announce "disabled" #31252</a></li></ul></li><li><a href="https://twitter.com/kyamashiro73" target="_blank" rel="noopener noreferrer">@kyamashiro73</a> closed 1 issue with:<ul><li><a href="https://github.com/facebook/react-native/pull/31224" target="_blank" rel="noopener noreferrer">Added talkback support for <code>TouchableNativeFeedback</code> accessibility: disabled prop #31224</a></li></ul></li><li><a href="https://twitter.com/dkrk0901" target="_blank" rel="noopener noreferrer">@grgr-dkrk</a> closed 1 issue and added to the React Native documentation with:<ul><li><a href="https://github.com/facebook/react-native/pull/31063" target="_blank" rel="noopener noreferrer">add <code>getRecommendedTimeoutMillis</code> to AccessibilityInfo #31063</a></li><li><a href="https://github.com/facebook/react-native-website/pull/2581" target="_blank" rel="noopener noreferrer">feat: add <code>getRecommendedTimeoutMillis</code> section on accessibilityInfo #2581</a></li></ul></li><li><a href="https://twitter.com/crloscuesta" target="_blank" rel="noopener noreferrer">@crloscuesta</a> closed 1 issue with:<ul><li><a href="https://github.com/facebook/react-native/pull/31297" target="_blank" rel="noopener noreferrer">Disable accessibilityState when <code>TouchableWithoutFeedback</code> is disabled #31297</a></li></ul></li><li><a href="https://twitter.com/chakrihacker" target="_blank" rel="noopener noreferrer">@chakrihacker</a> closed 1 issue with:<ul><li><a href="https://github.com/facebook/react-native/pull/31108" target="_blank" rel="noopener noreferrer">Disable <code>TouchableOpacity</code> when accessibility disabled is set #31108</a></li></ul></li></ul><p>Thank you to the community members who gave their time in other ways!</p><p><a href="https://github.com/Simek" target="_blank" rel="noopener noreferrer">Simek</a>, <a href="https://github.com/saurabhkacholiya" target="_blank" rel="noopener noreferrer">saurabhkacholiya</a>, <a href="https://github.com/meehawk" target="_blank" rel="noopener noreferrer">meehawk</a>, <a href="https://github.com/intergalacticspacehighway" target="_blank" rel="noopener noreferrer">intergalacticspacehighway</a>, <a href="https://github.com/chrisglein" target="_blank" rel="noopener noreferrer">chrisglein</a>, <a href="https://github.com/jychiao" target="_blank" rel="noopener noreferrer">jychiao</a> and <a href="https://github.com/Waltari10" target="_blank" rel="noopener noreferrer">Waltari10</a></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="get-involved">Get Involved!<a class="hash-link" href="#get-involved" title="Direct link to heading">​</a></h2><p>We've come a long way but we're not done yet. We need your support to reach the finish line. Facebook's React Native team has committed to supporting contributors working on gap analysis issues. They will continue to respond to comments on Accessibility issues and triage pull requests. The React Native team is also tackling some of the toughest gap analysis issues. This work includes the correct translation of accessibilityRoles to other languages and specifying error text for specific components.</p><p>Join us in tackling the rest. There are still open accessibility issues on the <a href="https://github.com/facebook/react-native/projects/15" target="_blank" rel="noopener noreferrer">Improved React Native Accessibility project board</a>. Issues with <a href="https://github.com/facebook/react-native/issues/30843" target="_blank" rel="noopener noreferrer">Checked/Unchecked State</a>, <a href="https://github.com/facebook/react-native/issues/30861" target="_blank" rel="noopener noreferrer">Entrance/exit from Collection</a>, and <a href="https://github.com/facebook/react-native/issues/30977" target="_blank" rel="noopener noreferrer">Position in Collection</a> are great opportunities for current and new contributors to contribute to a more accessible React Native.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="learn-more">Learn More<a class="hash-link" href="#learn-more" title="Direct link to heading">​</a></h3><p>Read about how the gap analysis was conducted on the <a href="https://tech.fb.com/react-native-accessibility/" target="_blank" rel="noopener noreferrer">Facebook Tech blog</a> or about the launch of the GitHub issues on the <a href="https://reactnative.dev/blog/2021/03/08/GAAD-React-Native-Accessibility" target="_blank" rel="noopener noreferrer">React Native Blog</a>.</p>]]></content>
        <author>
            <name>Alexandra Marlette</name>
            <uri>https://twitter.com/alexmarlette</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The GAAD Pledge - March Accessibility Issues Update]]></title>
        <id>/2021/04/08/GAAD-March-Accessibility-Issue-Update</id>
        <link href="https://reactnative.dev/blog/2021/04/08/GAAD-March-Accessibility-Issue-Update"/>
        <updated>2021-04-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[It has been four weeks since we reached out to the GitHub community with a thoroughly reviewed gap analysis and list of issues to improve React Native's accessibility. With the help of the React Native community, we are already making great progress on improving accessibility. Community members have been helping contributors, reviewing tests, and bringing attention to prior accessibility issues. Since March 8th the community has closed six issues with four pull requests and seven other pull requests are in the pipeline for review.]]></summary>
        <content type="html"><![CDATA[<p>It has been four weeks since we reached out to the GitHub community with a thoroughly reviewed gap analysis and list of issues to improve React Native's accessibility. With the help of the React Native community, we are already making great progress on improving accessibility. Community members have been helping contributors, reviewing tests, and bringing attention to prior accessibility issues. Since March 8th the community has closed six issues with four pull requests and seven other pull requests are in the pipeline for review.</p><p>While this work continues, the React Native and Accessibility teams at Facebook are evaluating accessibility bugs and issues that were submitted prior to this initiative, to determine if they are already covered by our current gap analysis or if there are additional issues that need to be brought into the project. One new issue has already been discovered and moved into the project, four others directly mapped to existing issues and two others are expected to be closed by addressing existing issues that address the root cause of their issue.</p><p>Thank you to all the community members who have participated. You are truly moving the needle in making React Native more accessible for everyone!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="closed-pull-requests-">Closed Pull Requests 🎉<a class="hash-link" href="#closed-pull-requests-" title="Direct link to heading">​</a></h2><ul><li><p><a href="https://github.com/facebook/react-native/pull/31001" target="_blank" rel="noopener noreferrer">Added talkback support for button accessibility: disabled prop #31001</a> - closed by <a href="https://twitter.com/huzaifaaak" target="_blank" rel="noopener noreferrer">@huzaifaaak </a></p></li><li><p><a href="https://github.com/facebook/react-native/pull/31135" target="_blank" rel="noopener noreferrer">feat: set disabled accessibilityState when TouchableHighlight is disabled #31135</a> closed by <a href="https://twitter.com/natural_clar" target="_blank" rel="noopener noreferrer">@natural_clar</a></p></li><li><p><a href="https://github.com/facebook/react-native/pull/31144" target="_blank" rel="noopener noreferrer">[Android] Selected State does not annonce when TextInput Component selected #31144</a> closed by <a href="http://fabriziobertoglio1987" target="_blank" rel="noopener noreferrer">fabriziobertoglio1987</a></p></li><li><p><a href="https://github.com/facebook/react-native/pull/31224" target="_blank" rel="noopener noreferrer">Added talkback support for TouchableNativeFeedback accessibility: disabled prop #31224</a> closed by <a href="https://twitter.com/kyamashiro73" target="_blank" rel="noopener noreferrer">@kyamashiro73</a></p></li><li><p><a href="https://github.com/facebook/react-native/pull/31189" target="_blank" rel="noopener noreferrer">Accessibility/button test #31189</a> closed by <a href="https://twitter.com/huzaifaaak" target="_blank" rel="noopener noreferrer">@huzaifaaak </a></p><ul><li>Adds a test for accessibilityState for button</li></ul></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="fixes">Fixes<a class="hash-link" href="#fixes" title="Direct link to heading">​</a></h2><ul><li><p><code>Button</code> component (fixed by <a href="https://github.com/facebook/react-native/pull/31001" target="_blank" rel="noopener noreferrer">#31001</a>):</p><ul><li><p>Now announces when it is disabled</p></li><li><p>Disables click functionality for screen readers when the button is disabled</p></li><li><p>Announces the selected state of the button</p></li></ul></li><li><p><code>TextInput</code> component (fixed by <a href="https://github.com/facebook/react-native/pull/31144" target="_blank" rel="noopener noreferrer">#31144</a>):</p><ul><li>Announces "selected" when the "selected" accessibilityState is set to true and the element is focused</li></ul></li><li><p><code>TouchableHighlight</code> component (fixed by <a href="https://github.com/facebook/react-native/pull/31135" target="_blank" rel="noopener noreferrer">#31135</a>):</p><ul><li>Disables click functionality for screen readers when the component is disabled</li></ul></li><li><p><code>TouchableNativeFeedback</code> component (fixed by <a href="https://github.com/facebook/react-native/pull/31224" target="_blank" rel="noopener noreferrer">#31224</a>):</p><ul><li>Disables click functionality for screen readers when the component is disabled</li></ul></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="other-progress">Other Progress<a class="hash-link" href="#other-progress" title="Direct link to heading">​</a></h2><table><thead><tr><th>Status</th><th align="center">Number of Issues</th></tr></thead><tbody><tr><td>Issues To Do</td><td align="center">53</td></tr><tr><td>In Progress Issues by the Community</td><td align="center">8</td></tr><tr><td>In Progress Issues by React Native Team</td><td align="center">5</td></tr><tr><td>Pull Request in Progress</td><td align="center">3</td></tr><tr><td>Pull Request in Reviews</td><td align="center">4</td></tr></tbody></table><h2 class="anchor anchorWithStickyNavbar_JmGV" id="get-involved">Get involved!<a class="hash-link" href="#get-involved" title="Direct link to heading">​</a></h2><ul><li><p>New contributors should read the <a href="https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a> and browse the list of 37 <a href="https://github.com/facebook/react-native/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+first+issue%22+label%3AAccessibility" target="_blank" rel="noopener noreferrer">good first issues</a> in the React Native GitHub.</p></li><li><p>Contributors interested in issues requiring a bit more effort should visit <a href="https://github.com/facebook/react-native/projects/15" target="_blank" rel="noopener noreferrer">the project page for Improved React Native Accessibility</a> to see the GitHub issues that need their knowledge of React Native.</p></li><li><p>Technical writers interested in updating React Native's documentation to reflect the accessibility gaps being closed should visit the <a href="https://github.com/facebook/react-native-website#-overview" target="_blank" rel="noopener noreferrer">React Native Docs</a>.</p></li><li><p>Share this initiative with anyone who may be able to help!</p></li><li><p>Follow the GAAD Pledge Open Source Accessibility Community Manager for React Native on <a href="https://twitter.com/alexmarlette" target="_blank" rel="noopener noreferrer">Twitter</a> or <a href="https://www.facebook.com/React-Native-Open-Source-Accessibility-Community-Manager-102732258549941" target="_blank" rel="noopener noreferrer">Facebook</a> to keep up to date on progress.</p></li></ul>]]></content>
        <author>
            <name>Alexandra Marlette</name>
            <uri>https://twitter.com/alexmarlette</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.64 with Hermes on iOS]]></title>
        <id>/2021/03/12/version-0.64</id>
        <link href="https://reactnative.dev/blog/2021/03/12/version-0.64"/>
        <updated>2021-03-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we’re releasing React Native 0.64 that ships with support for Hermes on iOS.]]></summary>
        <content type="html"><![CDATA[<p>Today we’re releasing React Native 0.64 that ships with support for Hermes on iOS.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="hermes-opt-in-on-ios">Hermes opt-in on iOS<a class="hash-link" href="#hermes-opt-in-on-ios" title="Direct link to heading">​</a></h2><p><a href="https://hermesengine.dev" target="_blank" rel="noopener noreferrer">Hermes</a> is an open source JavaScript engine optimized for running React Native. It improves performance by decreasing memory utilization, reducing download size and decreasing the time it takes for the app to become usable or “time to interactive” (TTI).</p><p>With this release, we are happy to announce that you can now use Hermes to build on iOS as well. To enable Hermes on iOS, set <code>hermes_enabled</code> to <code>true</code> in your <code>Podfile</code> and run <code>pod install</code>.</p><div class="language-ruby codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-ruby codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">use_react_native</span><span class="token operator" style="color:#fc929e">!</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">   </span><span class="token symbol" style="color:#5a9bcf">:path</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"> config</span><span class="token punctuation" style="color:#657b83">[</span><span class="token symbol" style="color:#5a9bcf">:reactNativePath</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">   </span><span class="token comment" style="color:#93a1a1"># to enable hermes on iOS, change `false` to `true` and then install pods</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">   </span><span class="token symbol" style="color:#5a9bcf">:hermes_enabled</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Please keep in mind that Hermes support on iOS is still early stage. We are keeping it as an opt-in as we are running further benchmarking. We encourage you to try it on your own applications and let us know how it is working out for you!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="inline-requires-enabled-by-default">Inline Requires enabled by default<a class="hash-link" href="#inline-requires-enabled-by-default" title="Direct link to heading">​</a></h2><p>Inline Requires is a Metro configuration option that improves startup time by delaying execution of JavaScript modules until they are used, instead of at startup.</p><p>This feature has existed and been recommended for a few years as an opt-in configuration option, listed in the <a href="/docs/performance">Performance section of our documentation</a>. We are now enabling this option by default for new applications to help people have fast React Native applications without extra configuration.</p><p>Inline Requires is a Babel transform that takes module imports and converts them to be inline. As an example, Inline Requires transforms this module import call from being at the top of the file to where it is used.</p><p><strong>Before:</strong></p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">MyFunction</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'my-module'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token function-variable function maybe-class-name" style="color:#79b6f2">MyComponent</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token parameter">props</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> result </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#79b6f2">MyFunction</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">result</span><span class="token punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>After:</strong></p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token function-variable function maybe-class-name" style="color:#79b6f2">MyComponent</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token parameter">props</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> result </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'my-module'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access maybe-class-name" style="color:#79b6f2">MyFunction</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">result</span><span class="token punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>More information about Inline Requires is available in the <a href="/docs/ram-bundles-inline-requires#inline-requires">Performance documentation</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="view-hermes-traces-with-chrome">View Hermes traces with Chrome<a class="hash-link" href="#view-hermes-traces-with-chrome" title="Direct link to heading">​</a></h2><p>Over the last year Facebook has sponsored the <a href="https://fellowship.mlh.io/" target="_blank" rel="noopener noreferrer">Major League Hacking fellowship</a>, supporting contributions to React Native. <a href="https://twitter.com/jessie_anh_ng" target="_blank" rel="noopener noreferrer">Jessie Nguyen</a> and <a href="https://twitter.com/saphalinsaan" target="_blank" rel="noopener noreferrer">Saphal Patro</a> added the ability to use the Performance tab on Chrome DevTools to visualize the execution of your application when it is using Hermes.</p><p>For more information, check out the <a href="/docs/profile-hermes#record-a-hermes-sampling-profile">new documentation page</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="hermes-with-proxy-support">Hermes with Proxy Support<a class="hash-link" href="#hermes-with-proxy-support" title="Direct link to heading">​</a></h2><p>We have added Proxy support to Hermes, enabling compatibility with popular community projects like react-native-firebase and mobx. If you have been using these packages you can now migrate to Hermes for your project.</p><p>We plan to make Hermes the default JavaScript engine for Android in a coming release so we are working to resolve the remaining issues people have when using Hermes. Please open an issue on the <a href="https://github.com/facebook/hermes" target="_blank" rel="noopener noreferrer">Hermes GitHub repo</a> if there are remaining issues holding back your app from adopting Hermes.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="react-17">React 17<a class="hash-link" href="#react-17" title="Direct link to heading">​</a></h2><p>React 17 does not include new developer-facing features or major breaking changes. For React Native applications, the main change is a <a href="https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html" target="_blank" rel="noopener noreferrer">new JSX transform</a> enabling files to no longer need to import React to be able to use JSX.</p><p>More information about React 17 is available <a href="https://reactjs.org/blog/2020/10/20/react-v17.html" target="_blank" rel="noopener noreferrer">on the React blog</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="major-dependency-version-changes">Major Dependency Version Changes<a class="hash-link" href="#major-dependency-version-changes" title="Direct link to heading">​</a></h2><ul><li>Dropped Android API levels 16-20. The Facebook app consistently drops support for Android versions with sufficiently low usage. As the Facebook app no longer supports these versions and is React Native’s main testing surface, React Native is dropping support as well.</li><li>Xcode 12 and CocoaPods 1.10 are required</li><li>Minimum Node support bumped from 10 to Node 12</li><li>Flipper bumped to 0.75.1</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thanks">Thanks<a class="hash-link" href="#thanks" title="Direct link to heading">​</a></h2><p>Thank you to the hundreds of contributors that helped make 0.64 possible! The <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0640" target="_blank" rel="noopener noreferrer">0.64 changelog</a> includes all of the changes included in this release.</p>]]></content>
        <author>
            <name>Mike Grabowski</name>
            <uri>https://twitter.com/grabbou</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The GAAD Pledge - Improving React Native Accessibility]]></title>
        <id>/2021/03/08/GAAD-React-Native-Accessibility</id>
        <link href="https://reactnative.dev/blog/2021/03/08/GAAD-React-Native-Accessibility"/>
        <updated>2021-03-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Hello React Native Community,]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_JmGV" id="hello-react-native-community">Hello React Native Community,<a class="hash-link" href="#hello-react-native-community" title="Direct link to heading">​</a></h2><p>In May 2020 Facebook was the first company to take the <a href="https://diamond.la/GAADPledge/" target="_blank" rel="noopener noreferrer">GAAD pledge</a>, by doing so they committed to making accessibility a core part of the React Native open source project. Since May, Facebook has spent that time thoughtfully reviewing and documenting accessibility gaps within React Native. So far the gap analysis has surfaced 90 issues, all of which have been translated to <a href="https://github.com/facebook/react-native/projects/15" target="_blank" rel="noopener noreferrer">GitHub issues</a>.</p><p>Overall, we found that React Native APIs provide strong support for accessibility. However, we also found many core components do not yet fully utilize platform accessibility APIs and support is missing for some platform specific features.</p><p>The enthusiasm and diversity of contributors have always played a critical role in the development of React Native and these gaps in accessibility are great opportunities for current and new contributors. If you have been interested in contributing to React Native, we encourage you to join us in making React Native more accessible.</p><p>To recognize contributors for their effort, when an accessibility issue is closed and attached to a pull request, contributors will get a shout out on Twitter from our community manager. Contributors whose pull requests are accepted into the codebase will be highlighted in our monthly issues update on the React Native blog.</p><p>Please join us in making React Native more accessible for everyone.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="how-you-can-help">How you can help:<a class="hash-link" href="#how-you-can-help" title="Direct link to heading">​</a></h3><ul><li><p>New contributors should read the <a href="https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">contribution guide</a> and browse the list of 46 <a href="https://github.com/facebook/react-native/issues?q=is%3Aopen+is%3Aissue+label%3A%22Good+first+issue%22+label%3AAccessibility" target="_blank" rel="noopener noreferrer">good first issues</a> in the React Native GitHub.</p></li><li><p>Contributors interested in issues requiring a bit more effort should visit <a href="https://github.com/facebook/react-native/projects/15" target="_blank" rel="noopener noreferrer">the project page for Improved React Native Accessibility</a> to see the GitHub issues that need their knowledge of React Native.</p></li><li><p>Technical writers interested in updating React Native's documentation to reflect the accessibility gaps being closed should visit the <a href="https://github.com/facebook/react-native-website#-overview" target="_blank" rel="noopener noreferrer">React Native Docs</a>.</p></li><li><p>Share this initiative with anyone who may be able to help!</p></li><li><p>Follow the GAAD Pledge Open Source Accessibility Community Manager for React Native on <a href="https://twitter.com/alexmarlette" target="_blank" rel="noopener noreferrer">Twitter</a> or <a href="https://www.facebook.com/React-Native-Open-Source-Accessibility-Community-Manager-102732258549941" target="_blank" rel="noopener noreferrer">Facebook</a> to keep up to date on progress.</p></li></ul>]]></content>
        <author>
            <name>Alexandra Marlette</name>
            <uri>https://twitter.com/alexmarlette</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Documentation Update]]></title>
        <id>/2020/07/23/docs-update</id>
        <link href="https://reactnative.dev/blog/2020/07/23/docs-update"/>
        <updated>2020-07-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Last year we conducted user interviews and sent out a survey to learn more about how and when people use the React Native docs. With the data and guidance gleaned from 24 interviews and over 3000 survey responses, we've been able to work to improve React Native's documentation, and we're excited to share that progress today:]]></summary>
        <content type="html"><![CDATA[<p>Last year we conducted user interviews and sent out <a href="https://www.surveymonkey.co.uk/r/DDZWQDJ" target="_blank" rel="noopener noreferrer">a survey</a> to learn more about how and when people use the React Native docs. With the data and guidance gleaned from 24 interviews and over 3000 survey responses, we've been able to work to improve React Native's documentation, and we're excited to share that progress today:</p><ul><li><strong><a href="https://reactnative.dev/docs/getting-started" target="_blank" rel="noopener noreferrer">New Getting Started guides</a></strong> We launched new Getting Started with docs to <a href="https://reactnative.dev/docs/intro-react-native-components" target="_blank" rel="noopener noreferrer">explain what Native Components</a> are to people with no mobile development background. We also included a <a href="https://reactnative.dev/docs/intro-react" target="_blank" rel="noopener noreferrer">refresher/introduction to React</a> to help folks getting started with React for the first time!</li><li><strong><a href="https://reactnative.dev/docs/testing-overview" target="_blank" rel="noopener noreferrer">New Testing guide</a></strong> We worked with Vojtech Novak to create a new illustrated testing guide that introduces app developers to different kinds of testing strategies and how they work in a React Native workflow.</li><li><strong><a href="https://reactnative.dev/docs/security" target="_blank" rel="noopener noreferrer">New Security guide</a></strong> We worked with Kadi Kraman to create a new illustrated security guide that explains the basics of security in a React Native world and puts forth best in class solutions.</li><li><strong>More illustrations</strong> We've added fancy new illustrations, including the new <a href="https://reactnative.dev/docs/pressable" target="_blank" rel="noopener noreferrer"><code>Pressable</code></a> and <a href="https://reactnative.dev/docs/intro-react-native-components" target="_blank" rel="noopener noreferrer">introduction to React Native components</a> docs</li><li><strong><a href="https://reactnative.dev" target="_blank" rel="noopener noreferrer">https://reactnative.dev</a></strong> After 5 years we finally moved to our own domain! <strong>reactnative.dev</strong> is easier to autocomplete from your browser bar and is easier to type out than our previous <strong>github.io</strong> address!</li><li><strong>Site design and architecture improvements</strong> We've updated the design and site architecture to surface and categorize more of our guides and make content in the API reference more readable. Kudos especially to <a href="https://github.com/Simek" target="_blank" rel="noopener noreferrer">Bartosz Kaszubowski</a> whose attention to detail and collaboration has made many of these changes possible quickly!</li><li><strong>Updated Core Component and API docs</strong> We held a <a href="https://github.com/facebook/react-native-website/issues/1579" target="_blank" rel="noopener noreferrer">documentation drive</a> to update reference docs! Thanks to these and other participants we were able to fully update the docs and add Snack examples to all of them in time for 0.62: <a href="https://twitter.com/martadabrowka" target="_blank" rel="noopener noreferrer">Marta Dabrowka</a>, <a href="https://twitter.com/nnajiabraham" target="_blank" rel="noopener noreferrer">Abraham Nnaji</a>, <a href="https://twitter.com/ahmdtalat" target="_blank" rel="noopener noreferrer">Ahmed Talaat El-Hager</a>, <a href="https://twitter.com/mohamedsgap" target="_blank" rel="noopener noreferrer">Mohamed Abdel Nasser Abdou</a>, <a href="https://twitter.com/danilobrinu" target="_blank" rel="noopener noreferrer">Danilo Britto</a>, <a href="https://twitter.com/mitulsavani" target="_blank" rel="noopener noreferrer">Mitul Savani</a>, <a href="https://twitter.com/kaiodduarte" target="_blank" rel="noopener noreferrer">Kaio Duarte</a>, <a href="https://twitter.com/espipj" target="_blank" rel="noopener noreferrer">Pablo Espinosa</a>, <a href="https://twitter.com/natural_clar" target="_blank" rel="noopener noreferrer">Jesse Katsumata</a>, <a href="https://twitter.com/gedeagas" target="_blank" rel="noopener noreferrer">I Gede Agastya Darma Laksana</a>, <a href="https://twitter.com/bruno_kiafuka" target="_blank" rel="noopener noreferrer">Sebastião Bruno Kiafuka Fernando</a>, <a href="https://twitter.com/Darking360" target="_blank" rel="noopener noreferrer">Miguel Bolivar</a>, <a href="https://twitter.com/dani_akash_" target="_blank" rel="noopener noreferrer">Dani Akash</a>, <a href="https://twitter.com/_eucelso" target="_blank" rel="noopener noreferrer">Luiz Celso de Faria Alves</a>, and <a href="https://twitter.com/simek" target="_blank" rel="noopener noreferrer">Bartosz Kaszubowski</a>. With their contributions, these are the best and most up to date React Native docs yet!</li><li><strong>Keep those PRs coming!</strong> We are able to consistently keep our open PRs under 10 per week! Thank you for sending them!</li></ul><p>Thank you so much to everyone who participated in the interviews, the survey, and our documentation efforts! Your collaboration makes this possible.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="whats-next">What’s next?<a class="hash-link" href="#whats-next" title="Direct link to heading">​</a></h2><p>The global COVID-19 pandemic has impacted many community members’ jobs.</p><p>We are responding with additional content including:</p><ul><li>New and improved Native Modules guides</li><li>Introductory content for people coming in to React Native for the first time</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="you-can-help">You can help!<a class="hash-link" href="#you-can-help" title="Direct link to heading">​</a></h3><p>There are many ways you can help us write even better docs!</p><ol><li>If you see a typo, run into an issue with a guide, or something otherwise isn’t quite right, click that “Edit” button and submit a PR.</li><li><a href="https://www.surveymonkey.co.uk/r/DDZWQDJ" target="_blank" rel="noopener noreferrer">Participate in our survey</a>—this helps us understand how you use React Native and its documentation</li><li>Write for us! We’re working on a tutorial section as well as guides for topics like offline apps, navigation, accessibility, debugging, animations, internationalization, and performance. If you or someone you admire or know is a perfect fit for any of these, please <a href="https://twitter.com/rachelnabors" target="_blank" rel="noopener noreferrer">reach out to me</a>!</li></ol>]]></content>
        <author>
            <name>Rachel Nabors</name>
            <uri>https://twitter.com/rachelnabors</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Team Principles]]></title>
        <id>/2020/07/17/react-native-principles</id>
        <link href="https://reactnative.dev/blog/2020/07/17/react-native-principles"/>
        <updated>2020-07-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The React Native team at Facebook is guided by principles that help determine how we prioritize our work on React Native. These principles represent our team specifically and do not necessarily represent every stakeholder in the React Native community. We are sharing these principles here to be more transparent about what drives us, how we make decisions, and how we focus our efforts.]]></summary>
        <content type="html"><![CDATA[<p>The React Native team at Facebook is guided by principles that help determine how we prioritize our work on React Native. These principles represent our team specifically and do not necessarily represent every stakeholder in the React Native community. We are sharing these principles here to be more transparent about what drives us, how we make decisions, and how we focus our efforts.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="native-experience"><strong>Native Experience</strong><a class="hash-link" href="#native-experience" title="Direct link to heading">​</a></h2><p>Our top priority for React Native is to <strong>match the expectations people have for each platform</strong>. This is why React Native renders to platform primitives. We value native look-and-feel over cross-platform consistency.</p><p>For example, the TextInput in React Native renders to a UITextField on iOS. This ensures that integration with password managers and keyboard controls work out of the box. By using platform primitives, React Native apps are also able to stay up-to-date with design and behavior changes from new releases of Android and iOS.</p><p>In order to match the look-and-feel of native apps, we must also match their performance. This is where we focus our most ambitious efforts. For example, Facebook created Hermes, <a href="https://facebook.github.io/react-native/blog/2019/07/17/hermes" target="_blank" rel="noopener noreferrer">a new JavaScript Engine built from scratch for React Native on Android</a>. Hermes significantly improves the start time of React Native apps. We are also working on major architectural changes that optimize the threading model and make React Native easier to interoperate with native code.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="massive-scale">Massive Scale<a class="hash-link" href="#massive-scale" title="Direct link to heading">​</a></h2><p>Hundreds of screens in the Facebook app are implemented with React Native. The Facebook app is used by billions of people on a huge range of devices. <strong>This is why</strong> <strong>we invest in the most challenging problems at scale.</strong></p><p>Deploying React Native in our apps lets us identify problems that we wouldn’t see at a smaller scale. For example, Facebook focuses on improving performance across a broad spectrum of devices from the newest iPhone to many older generations of Android devices. This focus informs our architecture projects such as Hermes, Fabric, and TurboModules.</p><p>We have proven that React Native can scale to massive organizations too. When hundreds of developers are working on the same app, gradual adoption is a must. This is why we made sure that React Native can be adopted one screen at a time. Soon, we will be taking this one step further and enable migrating individual native views of an existing native screen to React Native.</p><p>A focus on massive scale means there are many things our team isn’t currently working on. For example, our team doesn’t drive the adoption of React Native in the industry. We also do not actively build solutions for problems that we don’t see at scale. We are proud that we have <a href="https://github.com/facebook/react-native/blob/master/ECOSYSTEM.md" target="_blank" rel="noopener noreferrer">many partners and core contributors</a> that are able to focus on those important areas for the community.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="developer-velocity">Developer Velocity<a class="hash-link" href="#developer-velocity" title="Direct link to heading">​</a></h2><p>Great user experiences are created iteratively. <strong>It should only take a few seconds to seeing the result of code changes</strong> in a running app. React Native's architecture enables it to provide near-instant feedback during development.</p><p>We often hear from teams that adopting React Native significantly improved their development velocity. These teams find that the instant feedback during development makes it much easier to try different ideas and add extra polish when they don’t have to interrupt their coding session for every little change. When we make changes to React Native, we make sure to preserve this quality of the developer experience.</p><p>Instant feedback is not the only way that React Native improves developer velocity. Teams can leverage the fast-growing ecosystem of high quality open source packages. Teams can also share business logic between Android, iOS, and the web. This helps them ship updates faster and reduce organizational silos between platform teams.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="every-platform">Every Platform<a class="hash-link" href="#every-platform" title="Direct link to heading">​</a></h2><p>When we introduced React Native in 2014, we presented it with our motto “Learn once, write anywhere” — and we mean <em>anywhere</em>. <strong>Developers should be able to reach as many people as possible without being limited by device model or operating system.</strong></p><p>React Native targets very different platforms including mobile, desktop, web, TV, VR, game consoles, and more. We want to enable rich experiences on each platform instead of requiring developers to build for the lowest common denominator. To accomplish this, we focus on supporting the unique features of each platform. This ranges from varying input mechanisms (e.g. touch, pen, mouse) to fundamentally different consumption experiences like 3D environments in VR.</p><p>This principle informed our decision to implement React Native’s new core architecture in cross-platform C++ to promote parity across platforms. We are also refining the public interface targeted at other platform maintainers like Microsoft with Windows and macOS. We strive to enable any platforms to support React Native.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="declarative-ui">Declarative UI<a class="hash-link" href="#declarative-ui" title="Direct link to heading">​</a></h2><p>We don’t believe in deploying the exact same user interface on every platform, we believe in <strong>exposing each platform’s unique capabilities with the same declarative programming model</strong>. Our declarative programming model is React.</p><p>In our experience, the unidirectional data flow popularized by React makes applications easier to understand. We prefer to express a screen as a composition of declarative components rather than imperatively managed views. React’s success on the web and the direction of the new native Android and iOS frameworks show that the industry has also embraced declarative UI.</p><p>React popularized declarative user interfaces. However, there remain many unsolved problems that React is uniquely positioned to solve. React Native will continue to build on top of the innovations of React and remain at the forefront of the declarative user interface movement.</p>]]></content>
        <author>
            <name>Eli White</name>
            <uri>https://twitter.com/Eli_White</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.63 with LogBox]]></title>
        <id>/2020/07/06/version-0.63</id>
        <link href="https://reactnative.dev/blog/2020/07/06/version-0.63"/>
        <updated>2020-07-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we’re releasing React Native 0.63 that ships with LogBox turned on by default.]]></summary>
        <content type="html"><![CDATA[<p>Today we’re releasing React Native 0.63 that ships with LogBox turned on by default.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="logbox">LogBox<a class="hash-link" href="#logbox" title="Direct link to heading">​</a></h2><p>We’ve heard frequent feedback from the community that errors and warnings are difficult to debug in React Native. To address these issues we took a look at the entire error, warning, and log system in React Native and redesigned it <a href="https://www.youtube.com/watch?v=Y8brBH5O-bQ&amp;feature=youtu.be" target="_blank" rel="noopener noreferrer">from the ground up</a>.</p><p><img loading="lazy" alt="Screenshot of LogBox" src="/assets/images/0.63-logbox-a209851328e548bf0810bdee050fb960.png" width="1600" height="894" class="img_SS3x"></p><p>LogBox is a completely redesigned redbox, yellowbox, and logging experience in React Native. In 0.62 we introduced LogBox as an opt-in. In this release, we’re launching LogBox as the default experience in all of React Native.</p><p>LogBox addresses complaints that errors and warnings were too verbose, poorly formatted, or unactionable by focusing on three primary goals:</p><ul><li><strong>Concise</strong>: Logs should provide the minimum amount of information necessary to debug an issue.</li><li><strong>Formatted</strong>: Logs should be formatted so that you can quickly find the information you need.</li><li><strong>Actionable</strong>: Logs should be actionable, so you can fix the issue and move on.</li></ul><p>To achieve these goals, LogBox includes:</p><ul><li><strong>Log notifications</strong>: We’ve redesigned the warning notifications and added support for errors so that all console.warn and console.log messages show up as notifications instead of covering your app.</li><li><strong>Code Frames</strong>: Every error and warning now includes a code frame that shows the source code of the log right inside the app, allowing you to quickly identify the source of your issue.</li><li><strong>Component Stacks</strong>: All component stacks are now stripped from error messages and put into their own section with the top three frames visible. This gives you a single, consistent space to expect stack frame information that doesn’t clutter the log message.</li><li><strong>Stack Frame Collapsing</strong>: By default we now collapse call stack frames not related to your application’s code so you can quickly see the issue in your app and not sift through React Native internals.</li><li><strong>Syntax Error Formatting</strong>: We’ve improved the formatting for syntax errors and added codeframes with syntax highlighting so you can see the source of the error, fix it, and continue coding without React Native getting in your way.</li></ul><p>We’ve wrapped all of these features into an improved visual design that’s consistent between errors and warnings and allows paginating through all logs in one enjoyable UI.</p><p>With this change we’re also deprecating YellowBox in favor of LogBox APIs:</p><ul><li><code>LogBox.ignoreLogs()</code>: This function replaces <code>YellowBox.ignoreLogs([])</code> as a way to silence any logs that match the given strings or regexes.</li><li><code>LogBox.ignoreAllLogs()</code>: This function replaces <code>console.disableYellowBox</code> as a way to turn off error or warning notifications. Note: this only disables notifications, uncaught errors will still open a full screen LogBox.</li></ul><p>In 0.63, we will warn when using these deprecated modules or methods. Please update your call sites off of these APIs before they are removed in 0.64.</p><p>For more information on LogBox and debugging react native, see the docs <a href="https://reactnative.dev/docs/debugging#in-app-errors-and-warnings" target="_blank" rel="noopener noreferrer">here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="pressable">Pressable<a class="hash-link" href="#pressable" title="Direct link to heading">​</a></h2><p>React Native is built to enable applications to meet user’s expectations of the platform. This includes avoiding “tells”—little things that give away that the experience was built with React Native. One major source of these tells has been the Touchable components: <code>Button</code>, <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code>, <code>TouchableOpacity</code>, <code>TouchableNativeFeedback</code>, and <code>TouchableBounce</code>. These components make your application interactive by allowing you to provide visual feedback to user interactions. However, because they include built-in styles and effects that don’t match the platform interaction, users can tell when experiences are written with React Native.</p><p>Further, as React Native has grown and our bar for high-quality applications has gone up, these components haven't grown with it. React Native now supports platforms like Web, Desktop, and TV, but support for additional input modalities has been lacking. React Native needs to support high-quality interaction experiences on all platforms.</p><p>To address these problems, we are shipping a new core component called <code>Pressable</code>. This component can be used to detect various types of interactions. The API was designed to provide direct access to the current state of interaction without having to maintain state manually in a parent component. It was also designed to enable platforms to extend it's capabilities to include hover, blur, focus, and more. We expect that most people will build and share components utilizing <code>Pressable</code> under the hood instead of relying on the default experience of something like <code>TouchableOpacity</code>.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">Pressable</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Text</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Pressable</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">onPress</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript console class-name" style="color:#fac863">console</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript method function property-access" style="color:#79b6f2">log</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript string" style="color:#8dc891">'pressed'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript punctuation" style="color:#657b83">;</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">  </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript parameter" style="color:#fc929e">pressed</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">backgroundColor</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> pressed </span><span class="token tag script language-javascript operator" style="color:#fc929e">?</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript string" style="color:#8dc891">'lightskyblue'</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript string" style="color:#8dc891">'white'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">  </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">text</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text">Press Me!</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Pressable</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p class="snippet-caption">A simple example of a Pressable component in action</p><p>You can learn more about it from <a href="https://reactnative.dev/docs/pressable" target="_blank" rel="noopener noreferrer">the documentation</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="native-colors-platformcolor-dynamiccolorios">Native Colors (PlatformColor, DynamicColorIOS)<a class="hash-link" href="#native-colors-platformcolor-dynamiccolorios" title="Direct link to heading">​</a></h2><p>Every native platform has the concept of system-defined colors. Colors that automatically respond to system theme settings such as Light or Dark mode, accessibility settings such as a High Contrast mode, and even its context within the app such as the traits of a containing view or window.</p><p>While it is possible to detect some of these settings via the <a href="https://reactnative.dev/docs/appearance#getcolorscheme" target="_blank" rel="noopener noreferrer"><code>Appearance</code></a> API and/or <a href="https://reactnative.dev/docs/accessibilityinfo#isgrayscaleenabled" target="_blank" rel="noopener noreferrer"><code>AccessibilityInfo</code></a> and set your styles accordingly, such abstractions are not only costly to develop but are approximating the appearance of native colors. These inconsistencies are particularly noticeable when working on a hybrid application, where React Native elements co-exist next to the native ones.</p><p>React Native now provides an out-of-the-box solution to use these system colors. <code>PlatformColor()</code> is a new API that can be used like any other color in React Native.</p><p>For example, on iOS, the <a href="https://developer.apple.com/documentation/uikit/uicolor/ui_element_colors?language=objc" target="_blank" rel="noopener noreferrer">system provides a color called <code>labelColor</code></a>. That can be used in React Native with <code>PlatformColor</code> like this:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">Text</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">PlatformColor</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">color</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript function maybe-class-name" style="color:#79b6f2">PlatformColor</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript string" style="color:#8dc891">'labelColor'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  This is a label</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p class="snippet-caption">Sets the color of the Text component to labelColor as defined by iOS.</p><p>Android, on the other hand, <a href="https://developer.android.com/reference/android/R.attr#colorButtonNormal" target="_blank" rel="noopener noreferrer">provides colors like colorButtonNormal</a>. You can use this color in React Native with:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">View</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Text</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">PlatformColor</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">backgroundColor</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript function maybe-class-name" style="color:#79b6f2">PlatformColor</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript string" style="color:#8dc891">'?attr/colorButtonNormal'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">  </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text">This is colored like a button!</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p class="snippet-caption">Sets the background color of the View component to colorButtonNormal as defined by Android.</p><p>You can learn more about <code>PlatformColor</code> from <a href="https://reactnative.dev/docs/platformcolor" target="_blank" rel="noopener noreferrer">the documentation</a>. You can also check the actual <a href="https://github.com/facebook/react-native/blob/master/packages/rn-tester/js/examples/PlatformColor/PlatformColorExample.js" target="_blank" rel="noopener noreferrer">code examples present in the RNTester</a>.</p><p><code>DynamicColorIOS</code> is an iOS only API that lets you define which color to use in light and dark mode. Similar to <code>PlatformColor</code>, this can be used anywhere you can use colors. <code>DynamicColorIOS</code> uses iOS’s <code>colorWithDynamicProvider</code> under the hood.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">Text</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">DynamicColorIOS</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> customDynamicTextColor </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#79b6f2">DynamicColorIOS</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">dark</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'lightskyblue'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">light</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'midnightblue'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">color</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> customDynamicTextColor</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  This color changes automatically based on the system theme!</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p class="snippet-caption">Changes the text color based on the system theme</p><p>You can learn more about <code>DynamicColorIOS</code> from <a href="https://reactnative.dev/docs/dynamiccolorios" target="_blank" rel="noopener noreferrer">the documentation</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="dropping-ios-9-and-nodejs-8-support">Dropping iOS 9 and Node.js 8 support<a class="hash-link" href="#dropping-ios-9-and-nodejs-8-support" title="Direct link to heading">​</a></h2><p>After over four years from its release, we are dropping support for iOS 9. This change will allow us to move faster by being able to reduce the number of compatibility checks that need to be placed in the native code to detect whether a given feature was supported on a certain iOS version. With its <a href="https://david-smith.org/iosversionstats/" target="_blank" rel="noopener noreferrer">market share of 1%</a>, it shouldn’t have much negative impact on your customers.</p><p>At the same time, we are dropping support for Node 8. <a href="https://nodejs.org/fr/blog/release/v8.9.0/" target="_blank" rel="noopener noreferrer">Its LTS maintenance cycle expired in December 2019</a>. The current LTS is Node 10 and it is now the version that we are targeting. If you are still using Node 8 for the development of React Native applications, we encourage you to upgrade in order to receive all the latest security fixes and updates.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="other-notable-improvements">Other notable improvements<a class="hash-link" href="#other-notable-improvements" title="Direct link to heading">​</a></h2><ul><li><strong>Support rendering <code>&lt;View /&gt;</code> in <code>&lt;Text /&gt;</code> without explicit size</strong>: You can now render any <code>&lt;View /&gt;</code> inside any <code>&lt;Text /&gt;</code> component without setting its width and height explicitly, which wasn’t always possible. On previous releases of React Native, this would result in a RedBox.</li><li><strong>Changed iOS LaunchScreen from <code>xib</code> to <code>storyboard</code></strong>: Starting April 30, 2020, all apps submitted to the App Store must use an Xcode storyboard to provide the app’s launch screen and all iPhone apps must support all iPhone screens. This commit adjusts the default React Native template to be compatible with this requirement.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thanks">Thanks<a class="hash-link" href="#thanks" title="Direct link to heading">​</a></h2><p>Thank you to the hundreds of contributors that helped make 0.63 possible!</p><blockquote><p>Special thanks to <a href="https://twitter.com/rickhanlonii" target="_blank" rel="noopener noreferrer">Rick Hanlon</a> for authoring the section on <code>LogBox</code> and <a href="https://twitter.com/Eli_White" target="_blank" rel="noopener noreferrer">Eli White</a> for authoring the <code>Pressable</code> part of this article.</p></blockquote><p>To see all the updates, take a look at the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0630" target="_blank" rel="noopener noreferrer">0.63 changelog</a>.</p>]]></content>
        <author>
            <name>Mike Grabowski</name>
            <uri>https://twitter.com/grabbou</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.62 with Flipper]]></title>
        <id>/2020/03/26/version-0.62</id>
        <link href="https://reactnative.dev/blog/2020/03/26/version-0.62"/>
        <updated>2020-03-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we’re releasing React Native version 0.62 which includes support for Flipper by default.]]></summary>
        <content type="html"><![CDATA[<p>Today we’re releasing React Native version 0.62 which includes support for Flipper by default.</p><p>This release comes in the midst of a global pandemic. We’re releasing this version today to respect the work of hundreds of contributors who made this release possible and to prevent the release from falling too far behind master. Please be mindful of the reduced capacity of contributors to help with issues and prepare to delay upgrading if necessary.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="flipper-by-default">Flipper by default<a class="hash-link" href="#flipper-by-default" title="Direct link to heading">​</a></h2><p><a href="https://fbflipper.com/" target="_blank" rel="noopener noreferrer">Flipper</a> is a developer tool for debugging mobile apps. It’s popular in the Android and iOS communities, and in this release we’ve enabled support by default for new and existing React Native apps.</p><p><img loading="lazy" alt="Screenshot of Flipper for React Native" src="/assets/images/0.62-flipper-dc5a5cb54cc6033750c56f3c147c6ce3.png" width="1666" height="967" class="img_SS3x"></p><p>Flipper provides the following features out of the box:</p><ul><li><strong>Metro Actions</strong>: Reload the app and trigger the Dev Menu right from the toolbar.</li><li><strong>Crash Reporter</strong>: View crash reports from Android and iOS devices.</li><li><strong>React DevTools</strong>: Use the newest version of React DevTools right alongside all your other tools.</li><li><strong>Network Inspector</strong>: View all of the network requests made by device applications.</li><li><strong>Metro and Device Logs</strong>: View, search, and filter all logs from both Metro and the Device.</li><li><strong>Native Layout Inspector</strong>: View and edit the native layout output by the React Native renderer.</li><li><strong>Database and Preference Inspectors</strong>: View and edit the device databases and preferences.</li></ul><p>Additionally, since Flipper is an extensible platform, it provides a marketplace that pulls plugins from NPM so you can publish and install custom plugins specific to your workflows. See the available plugins <a href="https://www.npmjs.com/search?q=flipper-plugin" target="_blank" rel="noopener noreferrer">here</a>.</p><p>For more information, check out the <a href="https://fbflipper.com/docs/features/react-native" target="_blank" rel="noopener noreferrer">Flipper documentation</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="new-dark-mode-features">New dark mode features<a class="hash-link" href="#new-dark-mode-features" title="Direct link to heading">​</a></h2><p>We’ve added a new <code>Appearance</code> module to provide access to the user's appearance preferences, such as their preferred color scheme (light or dark).</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> colorScheme </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token maybe-class-name">Appearance</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">getColorScheme</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword control-flow" style="color:#c5a5c5">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">colorScheme </span><span class="token operator" style="color:#fc929e">===</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'dark'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token comment" style="color:#93a1a1">// Use dark color scheme</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We’ve also added a hook to subscribe to state updates to the users preferences:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">Text</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> useColorScheme</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token function-variable function maybe-class-name" style="color:#79b6f2">MyComponent</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> colorScheme </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">useColorScheme</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text">useColorScheme(): </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">colorScheme</span><span class="token punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Text</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>See the docs for <a href="/docs/appearance">Appearance</a> and <a href="/docs/usecolorscheme">useColorScheme</a> for more information.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="moving-apple-tv-to-react-native-tvos">Moving Apple TV to react-native-tvos<a class="hash-link" href="#moving-apple-tv-to-react-native-tvos" title="Direct link to heading">​</a></h2><p>As part of our <a href="/blog#lean-core">Lean Core effort</a> and to bring Apple TV in line with other platforms like React Native Windows and React Native macOS, we’ve started to remove Apple TV specific code from core.</p><p>Going forward, Apple TV support for React Native will be maintained in <a href="https://github.com/react-native-community/react-native-tvos" target="_blank" rel="noopener noreferrer">react-native-community/react-native-tvos</a> along with the corresponding <code>react-native-tvos</code> NPM package. This is a full fork of the main repository, with only the changes needed to support Apple TV.</p><p>Releases of <code>react-native-tvos</code> will be based on the public release of React Native. For this 0.62 release of <code>react-native</code> please upgrade Apple TV projects to use <code>react-native-tvos</code> 0.62.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="more-upgrade-support">More upgrade support<a class="hash-link" href="#more-upgrade-support" title="Direct link to heading">​</a></h2><p>When 0.61 was released, the community introduced a new <a href="https://react-native-community.github.io/upgrade-helper/" target="_blank" rel="noopener noreferrer">upgrade helper</a> tool to support developers upgrading to new versions of React Native. The upgrade helper provides a diff of changes from the version you're on to the version you're targeting, allowing you to see the changes that need to be made for your specific upgrade.</p><p>Even with this tool, issues come up when upgrading. Today we're introducing more dedicated upgrading support by announcing <a href="https://github.com/react-native-community/upgrade-support" target="_blank" rel="noopener noreferrer">Upgrade-Support</a>. Upgrade Support is a GitHub issue tracker where users can submit issues specific to upgrading their projects to receive help from the community.</p><p>We're always working to improve the upgrade experience, and we hope that these tools give users the support they need in the edge cases we haven't covered yet.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="other-improvements">Other improvements<a class="hash-link" href="#other-improvements" title="Direct link to heading">​</a></h2><ul><li><strong>LogBox</strong>: We’re adding the new LogBox error and warning experience as an opt-in; to enable it, add <code>require('react-native').unstable_enableLogBox()</code> to your <code>index.js</code> file.</li><li><strong>React DevTools v4</strong>: This change includes an upgrade to the <a href="https://reactjs.org/blog/2019/08/15/new-react-devtools.html" target="_blank" rel="noopener noreferrer">latest React DevTools</a> which offers significant performance gains, an improved navigation experience, and full support for React Hooks.</li><li><strong>Accessibility improvements</strong>: We’ve made improvements to accessibility including adding <a href="https://reactnative.dev/docs/accessibility#accessibilityvalue-ios-android" target="_blank" rel="noopener noreferrer">accessibilityValue</a>, missing props on <a href="https://github.com/facebook/react-native/commit/8c0c860e38f57e18296f689e47dfb4a54088c260" target="_blank" rel="noopener noreferrer">Touchables</a>, <code>onSlidingComplete</code> <a href="https://github.com/facebook/react-native/commit/c7aa6dc8270c0eabc913fe6c617c8131e3f4b3c5" target="_blank" rel="noopener noreferrer">accessibility events</a>, and changing the default role of Switch component from <code>"button"</code> to <code>"switch"</code>.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="breaking-changes">Breaking changes<a class="hash-link" href="#breaking-changes" title="Direct link to heading">​</a></h2><ul><li><strong>Remove PropTypes</strong>: We're removing <code>propTypes</code> from core components in order to reduce the app size impact of React Native core and to favor static type systems which check at compile time instead of runtime.</li><li><strong>Remove accessibilityStates</strong>: We’ve <a href="https://github.com/facebook/react-native/commit/7b35f427fd66cb0f36921b992095fe5b3c14d8b9" target="_blank" rel="noopener noreferrer">removed</a> the deprecated <code>accessibilityStates</code> property in favor of the new <code>accessibilityState</code> prop which is a more semantically rich way for components to describe information about their state to accessibility services.</li><li><strong>TextInput changes</strong>: We removed <code>onTextInput</code> <a href="https://github.com/facebook/react-native/commit/3f7e0a2c9601fc186f25bfd794cd0008ac3983ab" target="_blank" rel="noopener noreferrer">from TextInput</a> as it’s uncommon, not W3C compliant, and difficult to implement in <a href="https://github.com/react-native-community/discussions-and-proposals/issues/4" target="_blank" rel="noopener noreferrer">Fabric</a>. We also removed the undocumented <code>inputView</code> prop, and <code>selectionState</code>.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="deprecations">Deprecations<a class="hash-link" href="#deprecations" title="Direct link to heading">​</a></h2><ul><li><code>AccessibilityInfo.fetch</code> was already deprecated, but in this release we <a href="https://github.com/facebook/react-native/commit/523ab8333800afbfb169c6fd70ab6611fe07cc2a" target="_blank" rel="noopener noreferrer">added a warning</a>.</li><li>Setting <code>useNativeDriver</code> is <a href="https://github.com/facebook/react-native/commit/5876052615f4858ed5fc32fa3da9b64695974238" target="_blank" rel="noopener noreferrer">now required</a> to support switching the default in the future.</li><li>The <code>ref</code> of an <code>Animated</code> component is now the internal component and <a href="https://github.com/facebook/react-native/commit/66e72bb4e00aafbcb9f450ed5db261d98f99f82a" target="_blank" rel="noopener noreferrer">deprecated</a> <code>getNode</code>.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thanks">Thanks<a class="hash-link" href="#thanks" title="Direct link to heading">​</a></h2><p>Thank you to the hundreds of contributors that helped make 0.62 possible!</p><p>To see all the updates, take a look at the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0620" target="_blank" rel="noopener noreferrer">0.62 changelog</a>.</p>]]></content>
        <author>
            <name>Rick Hanlon</name>
            <uri>https://twitter.com/rickhanlonii</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Meet Doctor, a new React Native command]]></title>
        <id>/2019/11/18/react-native-doctor</id>
        <link href="https://reactnative.dev/blog/2019/11/18/react-native-doctor"/>
        <updated>2019-11-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[After over 20 pull requests from 6 contributors in the React Native Community, we're excited to launch react-native doctor, a new command to help you out with getting started, troubleshooting and automatically fixing errors with your development environment. The doctor command is heavily inspired by Expo and Homebrew's own doctor command with a pinch of UI inspired by Jest.]]></summary>
        <content type="html"><![CDATA[<p>After over 20 pull requests from 6 contributors in the React Native Community, we're excited to launch <code>react-native doctor</code>, a new command to help you out with getting started, troubleshooting and automatically fixing errors with your development environment. The <code>doctor</code> command is heavily inspired by <a href="https://expo.io/" target="_blank" rel="noopener noreferrer">Expo</a> and <a href="https://brew.sh/" target="_blank" rel="noopener noreferrer">Homebrew</a>'s own doctor command with a pinch of UI inspired by <a href="https://jestjs.io/" target="_blank" rel="noopener noreferrer">Jest</a>.</p><p>Here it is in action:</p><p style="text-align:center"><video width="700" controls="" autoplay="" style="border-radius:5px"><source type="video/mp4" src="/img/homepage/DoctorCommand.mp4"></video></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="how-it-works">How it works<a class="hash-link" href="#how-it-works" title="Direct link to heading">​</a></h2><p>The <code>doctor</code> command currently supports most of the software and libraries that React Native relies on, such as CocoaPods, Xcode and Android SDK. With <code>doctor</code> we'll find issues with your development environment and give you the option to automatically fix them. If <code>doctor</code> is not able to fix an issue, it will display a message and a helpful link explaining how to fix it manually as the following:</p><p style="text-align:center"><img loading="lazy" width="700" src="/img/DoctorManualInstallationMessage.png" alt="Doctor command with a link to help on Android SDK's installation" title="Doctor command with a link to help on Android SDK's installation" class="img_SS3x"></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="try-it-now">Try it now<a class="hash-link" href="#try-it-now" title="Direct link to heading">​</a></h2><p>The <code>doctor</code> command is available as a part of React Native 0.62. However, you can try it without upgrading yet:</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">npx @react-native-community/cli doctor</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="what-checks-are-currently-supported">What checks are currently supported<a class="hash-link" href="#what-checks-are-currently-supported" title="Direct link to heading">​</a></h2><p><code>doctor</code> currently supports the following checks:</p><ul><li>Node.js (&gt;= 8.3)</li><li>yarn (&gt;= 1.10)</li><li>npm (&gt;= 4)</li><li>Watchman (&gt;= 4), used for watching changes in the filesystem when in development mode.</li></ul><p>Specific to the Android environment:</p><ul><li>Android SDK (&gt;= 26), the software runtime for Android.</li><li>Android NDK (&gt;= 19), the native development toolkit for Android.</li><li><code>ANDROID_HOME</code>, environment variable required by the Android SDK setup.</li></ul><p>And to the iOS environment:</p><ul><li>Xcode (&gt;= 10), IDE for developing, building and shipping iOS applications.</li><li>CocoaPods, library dependency management tool for iOS applications.</li><li>ios-deploy (optional), library used internally by the CLI to install applications on a physical iOS device.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thanks">Thanks<a class="hash-link" href="#thanks" title="Direct link to heading">​</a></h2><p>Huge thanks for the React Native Community for working on this, in particular <a href="https://github.com/thymikee" target="_blank" rel="noopener noreferrer">@thymikee</a>, <a href="https://github.com/thib92" target="_blank" rel="noopener noreferrer">@thib92</a>, <a href="https://github.com/jmeistrich" target="_blank" rel="noopener noreferrer">@jmeistrich</a>, <a href="https://github.com/tido64" target="_blank" rel="noopener noreferrer">@tido64</a> and <a href="https://github.com/rickhanlonii" target="_blank" rel="noopener noreferrer">@rickhanlonii</a>.</p>]]></content>
        <author>
            <name>Lucas Bento</name>
            <uri>https://twitter.com/lbentosilva</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.61 with Fast Refresh]]></title>
        <id>/2019/09/18/version-0.61</id>
        <link href="https://reactnative.dev/blog/2019/09/18/version-0.61"/>
        <updated>2019-09-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We’re excited to announce React Native 0.61, which includes a new reloading experience we’re calling Fast Refresh.]]></summary>
        <content type="html"><![CDATA[<p>We’re excited to announce React Native 0.61, which includes a new reloading experience we’re calling Fast Refresh.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="fast-refresh">Fast Refresh<a class="hash-link" href="#fast-refresh" title="Direct link to heading">​</a></h2><p>When we asked the React Native community about <a href="https://github.com/react-native-community/discussions-and-proposals/issues/64" target="_blank" rel="noopener noreferrer">common pain points</a>, one of the top answers was that the “hot reloading” feature was broken. It didn’t work reliably for function components, often failed to update the screen, and wasn’t resilient to typos and mistakes. We heard that most people turned it off because it was too unreliable.</p><p>In React Native 0.61, <strong>we’re unifying the existing “live reloading” (reload on save) and “hot reloading” features into a single new feature called “Fast Refresh”</strong>. Fast Refresh was implemented from scratch with the following principles:</p><ul><li>Fast Refresh <strong>fully supports modern React</strong>, including function components and Hooks.</li><li>Fast Refresh <strong>gracefully recovers after typos</strong> and other mistakes, and falls back to a full reload when needed.</li><li>Fast Refresh <strong>doesn’t perform invasive code transformations</strong> so it’s reliable enough to be on by default.</li></ul><p>To see Fast Refresh in action, check out this video:</p><p style="text-align:center"><video width="700" controls="" autoplay=""><source type="video/mp4" src="https://reactnative.dev/img/homepage/ReactRefresh.mp4"></video></p><p>Give it a try, and let us know what you think! If you prefer, you can turn it off in the Dev Menu (Cmd+D on iOS, Cmd+M or Ctrl+M on Android). Turning it on and off is instant so you can do it any time.</p><p>Here are a few Fast Refresh tips:</p><ul><li>Fast Refresh preserves React local state in function components (and Hooks!) by default.</li><li>If you need to reset the React state on every edit, you can add a special <code>// @refresh reset</code> comment to the file with that component.</li><li>Fast Refresh always remounts class components without preserving state. This ensures it works reliably.</li><li>We all make mistakes in the code! Fast Refresh automatically retries rendering after you save a file. You don't need to reload the app manually after fixing a syntax or a runtime error.</li><li>Adding a <code>console.log</code> or a <code>debugger</code> statement during edits is a neat debugging technique.</li></ul><p>Please report any issues with Fast Refresh on GitHub, and we’ll look into them.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="other-improvements">Other Improvements<a class="hash-link" href="#other-improvements" title="Direct link to heading">​</a></h2><ul><li><strong>Fixed use_frameworks! CocoaPods support.</strong> In 0.60 we made some updates to integrate CocoaPods by default. Unfortunately, this broke builds using <a href="https://guides.cocoapods.org/syntax/podfile.html#use_frameworks_bang" target="_blank" rel="noopener noreferrer">use_frameworks!</a>. This is <a href="https://github.com/facebook/react-native/pull/25619" target="_blank" rel="noopener noreferrer">fixed in 0.61</a>, making it easier to integrate React Native into your iOS projects that require building with dynamic frameworks.</li><li><strong>Add useWindowDimensions Hook.</strong> This new Hook automatically provides and subscribes to dimension updates, and can be used instead of the Dimensions API in most cases.</li><li><strong>React was upgraded to 16.9.</strong> This version deprecates old names for the UNSAFE<!-- -->_<!-- --> lifecycle methods, contains improvements to <code>act</code>, and more. See the <a href="https://reactjs.org/blog/2019/08/08/react-v16.9.0.html" target="_blank" rel="noopener noreferrer">React 16.9 blog post</a> for an automated migration script and more information.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="breaking-changes">Breaking Changes<a class="hash-link" href="#breaking-changes" title="Direct link to heading">​</a></h2><ul><li><strong>Remove React .xcodeproj.</strong> In 0.60, we introduced auto-linking support via CocoaPods. We have also integrated CocoaPods into the e2e tests runs, so that from now on, we have a unified standard way of integrating RN into iOS apps. This effectively deprecates the React .xcodeproj support, and the file has been removed starting 0.61. Note: if you use 0.60 auto-linking already, you shouldn't be affected.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thanks">Thanks<a class="hash-link" href="#thanks" title="Direct link to heading">​</a></h2><p>Thanks to all of the contributors that helped make 0.61 possible!</p><p>To see all the updates, take a look at the <a href="https://github.com/facebook/react-native/blob/main/CHANGELOG.md#v0610" target="_blank" rel="noopener noreferrer">0.61 changelog</a>.</p>]]></content>
        <author>
            <name>Dan Abramov</name>
            <uri>https://twitter.com/dan_abramov</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Meet Hermes, a new JavaScript Engine optimized for React Native]]></title>
        <id>/2019/07/17/hermes</id>
        <link href="https://reactnative.dev/blog/2019/07/17/hermes"/>
        <updated>2019-07-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Last week at Chain React we announced Hermes, an open source JavaScript engine we’ve been working on at Facebook. It’s a small and lightweight JavaScript engine optimized for running React Native on Android. Check it out!]]></summary>
        <content type="html"><![CDATA[<p>Last week at Chain React we announced Hermes, an open source JavaScript engine we’ve been working on at Facebook. It’s a small and lightweight JavaScript engine optimized for running React Native on Android. <a href="https://code.fb.com/android/hermes/" target="_blank" rel="noopener noreferrer">Check it out!</a></p><p>Hermes improves React Native performance by decreasing memory utilization, reducing download size, and decreasing the time it takes for the app to become usable or “time to interactive” (TTI).</p><blockquote><p>“As we analyzed performance data, we noticed that the JavaScript engine itself was a significant factor in startup performance and download size. With this data in hand, we knew we had to optimize JavaScript performance in the more constrained environments of a mobile phone compared with a desktop or laptop. After exploring other options, we built a new JavaScript engine we call Hermes. It is designed to improve app performance, focusing on our React Native apps, even on mass-market devices with limited memory, slow storage, and reduced computing power.” —<a href="https://code.fb.com/android/hermes/" target="_blank" rel="noopener noreferrer">Hermes: An open source JavaScript engine optimized for mobile apps, starting with React Native</a></p></blockquote><p>Want to get started right away? Be sure to <a href="/docs/hermes">check out our new guide to enabling Hermes in your existing React Native app</a> in the docs!</p><p><a href="https://code.fb.com/android/hermes/" target="_blank" rel="noopener noreferrer"><img loading="lazy" alt="Illustration of the Hermes and React Native logos joined into a winged fury, rising in a crashing electrical storm from a lone, glowing, presumably Android phone." src="/assets/images/2019_hermes-launch-illo-rachel-nabors-05aac3b583be3cc5b84b78b88d60fa09.jpg" width="1000" height="707" class="img_SS3x"></a> <em>Illustration by Rachel Nabors</em></p>]]></content>
        <author>
            <name>Rachel Nabors</name>
            <uri>https://twitter.com/rachelnabors</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing React Native 0.60]]></title>
        <id>/2019/07/03/version-60</id>
        <link href="https://reactnative.dev/blog/2019/07/03/version-60"/>
        <updated>2019-07-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[After months of hard work from hundreds of contributors, the React Native Core team is proud to announce the release of version 0.60. This release handles significant migrations for both Android and iOS platforms, and many issues are resolved too. This blog post covers the highlights of the release. As always though, refer to the changelog for more detailed information. Finally, thank you contributors for helping us to make this milestone!]]></summary>
        <content type="html"><![CDATA[<p>After months of hard work from hundreds of contributors, the React Native Core team is proud to announce the release of version 0.60. This release handles significant migrations for both Android and iOS platforms, and many issues are resolved too. This blog post covers the highlights of the release. As always though, refer to the changelog for more detailed information. Finally, thank you contributors for helping us to make this milestone!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="focus-on-accessibility">Focus on Accessibility<a class="hash-link" href="#focus-on-accessibility" title="Direct link to heading">​</a></h2><p>There have been many improvements to the accessibility APIs, like <a href="https://github.com/facebook/react-native/commit/cfe0032" target="_blank" rel="noopener noreferrer">announceForAccessibility</a>, plus improvements to <a href="https://github.com/facebook/react-native/commit/1aeac1c" target="_blank" rel="noopener noreferrer">roles</a>, <a href="https://github.com/facebook/react-native/commit/14b4668" target="_blank" rel="noopener noreferrer">action support</a>, <a href="https://github.com/facebook/react-native/commit/0090ab3" target="_blank" rel="noopener noreferrer">flags</a>, and more. Accessibility is a complex science, but we hope these improvements make it a bit easier to be an A11Y. Be sure to check <a href="/blog/2019/06/12/react-native-open-source-update#meaningful-community-contributions">React Native Open Source Update June 2019</a> for more details of these changes.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="a-fresh-start">A Fresh Start<a class="hash-link" href="#a-fresh-start" title="Direct link to heading">​</a></h2><p>React Native's start screen has been updated! Thank you to the many contributors who helped create the new UI. This new "Hello World" will welcome users to the ecosystem in a more friendly, engaging way.</p><p><img loading="lazy" alt="The new init screen helps developers get started from the get-go with resources and a good example" src="/assets/images/0.60-new-init-screen-5b31714cd0630d7df25c66cab80c210b.png" width="233" height="466" class="img_SS3x"></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="androidx-support">AndroidX Support<a class="hash-link" href="#androidx-support" title="Direct link to heading">​</a></h2><p><a href="https://developer.android.com/jetpack/androidx" target="_blank" rel="noopener noreferrer">AndroidX</a> is a major step forward in the Android ecosystem, and the old support library artifacts are being deprecated. For 0.60, React Native has been migrated over to AndroidX. This is a breaking change, and <strong>your native code and dependencies will need to be migrated</strong> as well.</p><blockquote><p>With this change, React Native apps will need to begin using AndroidX themselves. They cannot be used side-by-side in one app, so all of the app code and dependency code needs to be using one or the other.</p><p><a href="https://github.com/matt-oakes" target="_blank" rel="noopener noreferrer">matt-oakes</a> on <a href="https://github.com/react-native-community/discussions-and-proposals/issues/129" target="_blank" rel="noopener noreferrer">discussions-and-proposals</a></p></blockquote><p>While your own native code will need to be migrated by you, <a href="https://github.com/mikehardy" target="_blank" rel="noopener noreferrer">@mikehardy</a>, <a href="https://github.com/cawfree" target="_blank" rel="noopener noreferrer">@cawfree</a>, and <a href="https://github.com/m4tt72" target="_blank" rel="noopener noreferrer">@m4tt72</a> built a <a href="https://github.com/mikehardy/jetifier" target="_blank" rel="noopener noreferrer">clever tool named "jetifier"</a> to patch your <code>node_modules</code>. Library maintainers will need to upgrade, but this tool provide you with a temporary solution while giving them time to release an AndroidX version. So if you find errors related to AndroidX migration, give this a shot.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="cocoapods-by-default">CocoaPods by Default<a class="hash-link" href="#cocoapods-by-default" title="Direct link to heading">​</a></h2><p><a href="https://github.com/react-native-community/discussions-and-proposals/blob/master/proposals/0004-cocoapods-support-improvements.md" target="_blank" rel="noopener noreferrer">CocoaPods are now part of React Native's iOS project</a>. If you weren't already, be sure to open iOS platform code using the <code>xcworkspace</code> file from now on (protip: try <code>xed ios</code> from the root project directory). Also, the <code>podspec</code>s for the internal packages have changed to make them compatible with the Xcode projects, which will help with troubleshooting and debugging. Expect to make <a href="https://github.com/facebook/react-native/commit/2321b3f" target="_blank" rel="noopener noreferrer">some straightforward changes</a> to your <code>Podfile</code> as part of the upgrade to 0.60 to bring this exciting support. Note that we are aware of a compatibility issue with <code>use_frameworks!</code>, and we're tracking an <a href="https://github.com/facebook/react-native/issues/25349" target="_blank" rel="noopener noreferrer">issue</a> with workarounds and a future patch.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="lean-core-removals">Lean Core Removals<a class="hash-link" href="#lean-core-removals" title="Direct link to heading">​</a></h2><p><strong>WebView</strong> and <strong>NetInfo</strong> were previously extracted into separate repositories, and in 0.60 we’ve finished migrating them out of the React Native repository. Additionally, in response to community feedback about new App Store policy, <strong>Geolocation</strong> has been extracted. If you haven’t already, complete your migration by adding dependencies to <a href="https://github.com/react-native-community/react-native-webview" target="_blank" rel="noopener noreferrer">react-native-webview</a>, <a href="https://github.com/react-native-community/react-native-netinfo" target="_blank" rel="noopener noreferrer">@react-native-community/netinfo</a>, and <a href="https://github.com/react-native-community/react-native-geolocation" target="_blank" rel="noopener noreferrer">@react-native-community/geolocation</a>. If you'd like an automated solution, consider using <a href="https://github.com/lucasbento/rn-update-deprecated-modules" target="_blank" rel="noopener noreferrer">rn-upgrade-deprecated-modules</a>. Maintainers have made more than 100 commits to these repositories since extraction and we’re excited to see the community’s support!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="native-modules-are-now-autolinked">Native Modules are now Autolinked<a class="hash-link" href="#native-modules-are-now-autolinked" title="Direct link to heading">​</a></h2><p>The team working on the <a href="https://github.com/react-native-community/cli" target="_blank" rel="noopener noreferrer">React Native CLI</a> has introduced major improvements to native module linking called <a href="https://github.com/react-native-community/cli/blob/master/docs/autolinking.md" target="_blank" rel="noopener noreferrer">autolinking</a>! Most scenarios will not require the use of <code>react-native link</code> anymore. At the same time, the team overhauled the linking process in general. Be sure to <code>react-native unlink</code> any preexisting dependencies as mentioned in the docs above.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="upgrade-helper">Upgrade Helper<a class="hash-link" href="#upgrade-helper" title="Direct link to heading">​</a></h2><p><a href="https://github.com/lucasbento" target="_blank" rel="noopener noreferrer">@lucasbento</a>, <a href="https://github.com/pvinis" target="_blank" rel="noopener noreferrer">@pvinis</a>, <a href="https://github.com/kelset" target="_blank" rel="noopener noreferrer">@kelset</a>, and <a href="https://github.com/watadarkstar" target="_blank" rel="noopener noreferrer">@watadarkstar</a> have built a great tool called <a href="https://react-native-community.github.io/upgrade-helper/" target="_blank" rel="noopener noreferrer">Upgrade Helper</a> to make the upgrade process simpler. It helps React Native users with brownfield apps or complex customizations to see what's changed between versions. Take a look at the <a href="/docs/upgrading">updated upgrading docs</a> and try it out today for your upgrade path!</p><p><img loading="lazy" alt="Upgrade Helper cleanly and easily shows the changes needed to migrate to a different version of React Native" src="/assets/images/0.60-upgrade-helper-220ec6d7cb848ee06ae952c142c1cf2a.png" width="2172" height="1502" class="img_SS3x"></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="a-note-to-library-maintainers">A Note to Library Maintainers<a class="hash-link" href="#a-note-to-library-maintainers" title="Direct link to heading">​</a></h2><p>Changes for AndroidX will almost certainly require updates to your library, so be sure to include support soon. If you're not able to upgrade yet, consider checking your library against the jetifier to confirm that users are able to patch your library at build time.</p><p>Review the <a href="https://github.com/react-native-community/cli/blob/master/docs/autolinking.md" target="_blank" rel="noopener noreferrer">autolinking</a> docs to update your configs and readme. Depending on how your library was previously integrated, you may also need to make some additional changes. Check the <a href="https://github.com/react-native-community/cli/blob/master/docs/dependencies.md" target="_blank" rel="noopener noreferrer">dependencies</a> guide from the CLI for information on how to define your dependency interface.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thanks">Thanks<a class="hash-link" href="#thanks" title="Direct link to heading">​</a></h2><p>While these are the highlights that we noted, there are many others to be excited about. To see all the updates, take a look at the <a href="https://github.com/react-native-community/react-native-releases/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer">changelog</a>. As always, stay tuned for more news. Enjoy 0.60 in the meantime!</p>]]></content>
        <author>
            <name>Ryan Turner</name>
            <uri>https://twitter.com/turnrye</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Open Source Update June 2019]]></title>
        <id>/2019/06/12/react-native-open-source-update</id>
        <link href="https://reactnative.dev/blog/2019/06/12/react-native-open-source-update"/>
        <updated>2019-06-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Code & Community Health]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_JmGV" id="code--community-health">Code &amp; Community Health<a class="hash-link" href="#code--community-health" title="Direct link to heading">​</a></h2><p>In the past six months, a total of 2800 commits were made to React Native by more than 550 contributors. 400 contributors from the community created more than <a href="https://github.com/facebook/react-native/pulls?page=24&amp;q=is%3Apr+closed%3A%3E2018-12-01&amp;utf8=%E2%9C%93" target="_blank" rel="noopener noreferrer">1,150 Pull Requests</a>, of which <a href="https://github.com/facebook/react-native/pulls?utf8=%E2%9C%93&amp;q=is%3Apr+closed%3A%3E2018-12-01+label%3A%22Merged%22+" target="_blank" rel="noopener noreferrer">820 Pull Requests</a> were merged.</p><p>The average number of Pull Requests per day throughout the past six months has increased from three to about six, even though we split the website, CLI and many modules out of React Native via the Lean Core effort. The average amount of open pull requests is now below 25 and we usually reply with suggestions and reviews within hours or days.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="meaningful-community-contributions">Meaningful Community Contributions<a class="hash-link" href="#meaningful-community-contributions" title="Direct link to heading">​</a></h3><p>We’d like to highlight a number of recent contributions which we thought were awesome:</p><ul><li><strong>Accessibility:</strong> React Native 0.60 will ship with many improvements to accessibility APIs both on Android and iOS. All of the new features are directly using APIs provided by the underlying platform so they’ll integrate with native assistance technologies both on Android and iOS. We’d like to thank <a href="https://github.com/marcmulcahy" target="_blank" rel="noopener noreferrer">Marc Mulcahy</a>, <a href="https://github.com/facebook/react-native/pull/24746" target="_blank" rel="noopener noreferrer">Alan Kenyon</a>, <a href="https://github.com/elucaswork" target="_blank" rel="noopener noreferrer">Estevão Lucas</a>, <a href="https://github.com/sweggersen" target="_blank" rel="noopener noreferrer">Sam Mathias Weggersen</a> and <a href="https://twitter.com/janicduplessis" target="_blank" rel="noopener noreferrer">Janic Duplessis</a> for their contributions:<ul><li><a href="https://github.com/facebook/react-native/pull/24095" target="_blank" rel="noopener noreferrer">Additional Accessibility Roles + States</a> and a <a href="https://github.com/facebook/react-native/pull/24608" target="_blank" rel="noopener noreferrer">new Accessibility States API</a>. Added a number of missing accessibility roles for various components and a new API for better web support in the future.</li><li><a href="https://github.com/facebook/react-native/pull/24746" target="_blank" rel="noopener noreferrer">AccessibilityInfo.announceForAccessibility</a>. Added support for Android, previously iOS-only.</li><li><a href="https://github.com/facebook/react-native/pull/24695" target="_blank" rel="noopener noreferrer">Extended Accessibility Actions Support</a>. Added callbacks to deal with accessibility around user-defined actions.</li><li><a href="https://github.com/facebook/react-native/pull/23913" target="_blank" rel="noopener noreferrer">Support for iOS Accessibility flags</a> and <a href="https://github.com/facebook/react-native/pull/23839" target="_blank" rel="noopener noreferrer">support for "reduce motion"</a>.</li><li><a href="https://github.com/facebook/react-native/pull/24359" target="_blank" rel="noopener noreferrer">Android keyboard accessibility improvements</a>. Added a <code>clickable</code> prop and an <code>onClick</code> callback for invoking actions via keyboard navigation <em>(note: this will soon be renamed to <code>focusable</code>).</em></li><li><a href="https://github.com/facebook/react-native/pull/24387" target="_blank" rel="noopener noreferrer">Use CALayers to draw text</a>. Fixed an issue that made scaled-up text disappear on iOS.</li></ul></li><li><strong>New App Screen:</strong> The community came up with a <a href="https://github.com/react-native-community/discussions-and-proposals/issues/122" target="_blank" rel="noopener noreferrer">design for the new app screen</a> that is implemented in 0.60. This screen is what most people see when they are first using React Native. It now links first time users to the documentation and the look fits with our upcoming website redesign 🌟. Huge thanks to <a href="http://twitter.com/orta" target="_blank" rel="noopener noreferrer">Orta</a>, <a href="https://www.linkedin.com/in/ashurson/" target="_blank" rel="noopener noreferrer">Adam Shurson</a>, <a href="https://github.com/glauberfc" target="_blank" rel="noopener noreferrer">Glauber Castro</a>, <a href="https://github.com/karanpratapsingh" target="_blank" rel="noopener noreferrer">Karan Singh</a>, <a href="https://twitter.com/_eliperkins" target="_blank" rel="noopener noreferrer">Eli Perkins</a>, <a href="https://twitter.com/lbentosilva" target="_blank" rel="noopener noreferrer">Lucas Bento</a> and <a href="https://twitter.com/ericlewis" target="_blank" rel="noopener noreferrer">Eric Lewis</a> for all their work and collaboration!<ul><li>Check out the new app screen on the “<em><a href="https://www.youtube.com/watch?v=ImlAqMZxveg" target="_blank" rel="noopener noreferrer">React Native Show</a>“ </em>video series.</li></ul></li><li><strong>TurboModule Types:</strong> The new <a href="https://github.com/react-native-community/discussions-and-proposals/issues/40" target="_blank" rel="noopener noreferrer">TurboModules system</a> requires <a href="https://github.com/facebook/react-native/issues/24875" target="_blank" rel="noopener noreferrer">types for all native modules</a> to guarantee type safe operations in native. In just over two weeks, the community sent ~40 Pull Requests to complete this work for flow typed native modules. Aside from the people already mentioned above, we’d like to thank <a href="https://twitter.com/michalchudziak" target="_blank" rel="noopener noreferrer">Michał Chudziak</a>, <a href="https://twitter.com/thymikee" target="_blank" rel="noopener noreferrer">Michał Pierzchała</a>, <a href="https://github.com/wojteg1337" target="_blank" rel="noopener noreferrer">Wojtek Szafraniec</a>, and <a href="https://github.com/jeanregisser" target="_blank" rel="noopener noreferrer">Jean Regisser</a> and everyone else who sent one or more Pull Requests.</li><li><strong>Haste:</strong> Since 2015 React Native used the <a href="https://github.com/reactjs/reactjs.org/commit/0629e3e2289ed54fac854472aec9a5f6c8318c98#diff-c42b758729cb89976b3a8fd51d1227fa" target="_blank" rel="noopener noreferrer">“haste” module system</a> that allows importing modules just via a global id instead of a relative path which is convenient but not well supported by many tools. <a href="https://twitter.com/JI" target="_blank" rel="noopener noreferrer">James Ide</a> proposed removing haste, similar to how React removed haste many years ago. He planned all the work through an <a href="https://github.com/facebook/react-native/issues/24316" target="_blank" rel="noopener noreferrer">umbrella task</a> and he sent 18 Pull Requests to make it happen! Check out <a href="https://twitter.com/JI/status/1136369775083319296" target="_blank" rel="noopener noreferrer">his Twitter thread</a> to learn more.</li><li><strong>Android Fragments:</strong> <a href="https://github.com/jpshelley" target="_blank" rel="noopener noreferrer">John Shelley</a>‘s proposal to make React Native work via <a href="https://github.com/facebook/react-native/pull/12199" target="_blank" rel="noopener noreferrer">Android Fragments</a> was merged and will be available in 0.61. <a href="https://developer.android.com/guide/components/fragments" target="_blank" rel="noopener noreferrer">Read more about Android Fragments here</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="lean-core">Lean Core<a class="hash-link" href="#lean-core" title="Direct link to heading">​</a></h3><p>The primary motivation of <a href="https://github.com/react-native-community/discussions-and-proposals/issues/6" target="_blank" rel="noopener noreferrer">Lean Core</a> has been to split modules out of React Native into separate repositories so they can receive better maintenance. In just a six months repositories like <a href="https://github.com/react-native-community/react-native-webview" target="_blank" rel="noopener noreferrer">WebView</a>, <a href="https://github.com/react-native-community/react-native-netinfo" target="_blank" rel="noopener noreferrer">NetInfo</a>, <a href="https://github.com/react-native-community/react-native-async-storage" target="_blank" rel="noopener noreferrer">AsyncStorage</a>, the <a href="https://github.com/facebook/react-native-website" target="_blank" rel="noopener noreferrer">website</a> and the <a href="https://github.com/react-native-community/cli" target="_blank" rel="noopener noreferrer">CLI</a> received more than 800 Pull Requests combined. Besides better maintenance, these projects can also be independently released more often than React Native itself.</p><p>We have also taken the opportunity to remove obsolete polyfills and legacy components from React Native itself. Polyfills were necessary in the past to support language features like <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map" target="_blank" rel="noopener noreferrer"><code>Map</code></a> and <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set" target="_blank" rel="noopener noreferrer"><code>Set</code></a> in older versions of JavaScriptCore (JSC). Now that React Native ships with a new version, these polyfills were removed.</p><p>This work is still in progress and many more things still need to be split out or removed both on the native and JavaScript side but there are early signs that we managed to reverse the trend of increasing the surface area and app size: When looking at the JavaScript bundle for example, about a year ago in version 0.54 the React Native JavaScript bundle size was 530kb and grew to 607kb (+77kb) by version 0.57 in just 6 months. Now we are seeing a bundle size reduction of 28kb down to 579kb on master, a delta of more than 100kb!</p><p>As we conclude the first iteration of the Lean Core effort, we will make an effort to be more intentional about new APIs added to React Native and we will continuously evaluate ways to make React Native smaller and faster, as well as finding ways to empower the community to take ownership of various components.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="user-feedback">User Feedback<a class="hash-link" href="#user-feedback" title="Direct link to heading">​</a></h2><p>Six months ago we asked the community “<a href="https://github.com/react-native-community/discussions-and-proposals/issues/64" target="_blank" rel="noopener noreferrer">What do you dislike about React Native?</a>” which gave a good overview of problems people are facing. We <a href="https://github.com/react-native-community/discussions-and-proposals/issues/104" target="_blank" rel="noopener noreferrer">replied to the post a few months ago</a> and it's time to summarize the progress that was made on top issues:</p><ul><li><strong>Upgrading:</strong> The React Native community rallied around with multiple improvements to the upgrading experience: <a href="https://github.com/react-native-community/cli/blob/master/docs/autolinking.md" target="_blank" rel="noopener noreferrer">autolinking</a>, a better upgrading command via <a href="https://github.com/react-native-community/rn-diff-purge" target="_blank" rel="noopener noreferrer">rn-diff-purge</a>, an upgrade helper website (coming soon). We’ll also make sure to communicate breaking changes and exciting new features by publishing blog posts for each major release. Many of these improvements will make future upgrades beyond the 0.60 release significantly easier.</li><li><strong>Support / Uncertainty:</strong> Many people were frustrated with the lack of activity on Pull Requests and general uncertainty about Facebook's investment in React Native. As we've shown above, we can confidently say that we are ready for many more Pull Requests and we are eagerly looking forward to your proposals and contributions!</li><li><strong>Performance:</strong> React Native 0.59 shipped with a new and much faster version of JavaScriptCore (JSC). Separately, we have been working on making it easier to enable <a href="/docs/performance#ram-bundles-inline-requires">inline-requires</a> by default and we have more exciting updates for you in the next couple of months.</li><li><strong>Documentation:</strong> We recently started an effort to <a href="https://github.com/facebook/react-native-website/issues/929" target="_blank" rel="noopener noreferrer">overhaul and rewrite all of React Native's documentation</a>. If you are looking to contribute, we’d love to get your help!</li><li><strong>Warnings in Xcode:</strong> We <a href="https://github.com/facebook/react-native/issues/22609" target="_blank" rel="noopener noreferrer">got rid of all the existing warnings</a> and are making an effort not to introduce new warnings.</li><li><strong>Hot Reloading:</strong> The React team is building a <a href="https://twitter.com/dan_abramov/status/1126948870137753605" target="_blank" rel="noopener noreferrer">new hot reloading system</a> that will soon be integrated into React Native.</li></ul><p>Unfortunately we weren’t able to improve everything just yet:</p><ul><li><strong>Debugging:</strong> We fixed many inconvenient bugs and issues people that we have been running into every day, but unfortunately we haven't made as much progress on this as we would like. We recognize that debugging with React Native isn't great and we'll prioritize improving this in the future.</li><li><strong>Metro symlinks:</strong> Unfortunately we haven't been able to implement a simple and straightforward solution for this yet. However, React Native users <a href="https://github.com/facebook/metro/issues/1" target="_blank" rel="noopener noreferrer">shared various workarounds</a> that may work for you.</li></ul><p>Given the large amount of changes in the past six months, we'd like to ask you the same question again. If you are using the latest version of React Native and you have things you'd like to give feedback on, please comment on our new edition of <a href="https://github.com/react-native-community/discussions-and-proposals/issues/134" target="_blank" rel="noopener noreferrer">“What do you dislike about React Native?”</a></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="continuous-integration">Continuous Integration<a class="hash-link" href="#continuous-integration" title="Direct link to heading">​</a></h2><p>Facebook merges all Pull Requests and internal changes directly into Facebook’s repository first and then syncs all commits back to GitHub. Facebook’s infrastructure is different from common continuous integration services and not all open source tests were run inside of Facebook. This means that commits that sync out to GitHub frequently break tests in open source which take a lot of time to fix.</p><p><a href="https://twitter.com/hectorramos" target="_blank" rel="noopener noreferrer">Héctor Ramos</a> from the React Native team spent the past two months improving React Native's continuous integration systems both at Facebook and on GitHub. Most of the open source tests are now run before changes are committed to React Native at Facebook which will keep CI stable on GitHub when commits are being synchronized.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next">Next<a class="hash-link" href="#next" title="Direct link to heading">​</a></h2><p>Make sure to check out our talks about the future of React Native! In the next couple of months, members of the React Native team at Facebook will speak at <a href="https://infinite.red/ChainReactConf" target="_blank" rel="noopener noreferrer">Chain React</a> and at <a href="https://react-native.eu/" target="_blank" rel="noopener noreferrer">React Native EU</a>. Also, watch out for our next release, 0.60, which is right around the corner. <em>It's going to be exciting</em> ✨</p>]]></content>
        <author>
            <name>Christoph Nakazawa</name>
            <uri>https://twitter.com/cpojer</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native at F8 and Open Source Podcast]]></title>
        <id>/2019/05/01/react-native-at-f8-and-podcast</id>
        <link href="https://reactnative.dev/blog/2019/05/01/react-native-at-f8-and-podcast"/>
        <updated>2019-05-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This week, Eli White gave a talk at F8 2019 about React Native in Facebook's Android and iOS applications. We are excited to share what we've been up to for the past two years and what we're doing next.]]></summary>
        <content type="html"><![CDATA[<p>This week, <a href="https://twitter.com/Eli_White" target="_blank" rel="noopener noreferrer">Eli White</a> gave a talk at <a href="https://developers.facebook.com/videos/2019/mobile-innovation-with-react-native-componentkit-and-litho/" target="_blank" rel="noopener noreferrer">F8 2019</a> about React Native in Facebook's Android and iOS applications. We are excited to share what we've been up to for the past two years and what we're doing next.</p><p>Check out the video on <a href="https://developers.facebook.com/videos/2019/mobile-innovation-with-react-native-componentkit-and-litho/" target="_blank" rel="noopener noreferrer">Facebook's developer website</a>:</p><a href="https://developers.facebook.com/videos/2019/mobile-innovation-with-react-native-componentkit-and-litho/" target="_blank" rel="noopener noreferrer"><img loading="lazy" src="/blog/assets/eli-at-f8.png" alt="F8 Talk about React Native" class="img_SS3x"></a><h4 class="anchor anchorWithStickyNavbar_JmGV" id="highlights-from-the-talk">Highlights from the talk:<a class="hash-link" href="#highlights-from-the-talk" title="Direct link to heading">​</a></h4><ul><li>We spent 2017 and 2018 focused on React Native's largest product, Facebook's Marketplace. We collaborated with the Marketplace team to improve quality and add delight to the product. At this point, Marketplace is one of the highest quality products in the Facebook app both on Android and iOS.</li><li>Marketplace's performance was a big challenge as well, especially on mid-end Android devices. We cut startup time by more than 50% over the last year with more improvements on the way! The biggest improvements are being built into React Native and will be coming to the community later this year.</li><li>We have the confidence that we can build the high quality and performant apps that Facebook needs with React Native. This confidence has let us invest in bigger bets, like <a href="https://www.youtube.com/watch?v=UcqRXTriUVI&amp;app=desktop" target="_blank" rel="noopener noreferrer">rethinking the core of React Native</a>.</li><li>Microsoft supports and uses React Native for Windows, enabling people to use their expertise and codebase to render to Microsofts's Universal Windows Platform. Check out Microsoft Build next week to <a href="https://mybuild.techcommunity.microsoft.com/sessions/77321" target="_blank" rel="noopener noreferrer">hear them talk about that more</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="react-radio-podcast-about-open-source">React Radio Podcast about Open Source<a class="hash-link" href="#react-radio-podcast-about-open-source" title="Direct link to heading">​</a></h3><p>Eli's talk concludes by talking about our recent open source work. We gave <a href="/blog/2019/03/01/react-native-open-source-update">an update on our progress in March</a> and recently <a href="https://twitter.com/dabit3" target="_blank" rel="noopener noreferrer">Nader Dabit</a> and <a href="https://twitter.com/GantLaborde" target="_blank" rel="noopener noreferrer">Gant Laborde</a> invited Christoph for a chat on their podcast, <a href="https://devchat.tv/react-native-radio/react-native-open-source-the-react-native-community-feat-christoph-nakazawa/" target="_blank" rel="noopener noreferrer">React Native Radio</a>, to chat about React Native in open source.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="highlights-from-the-podcast">Highlights from the podcast:<a class="hash-link" href="#highlights-from-the-podcast" title="Direct link to heading">​</a></h4><ul><li>We talked about how the React Native team at Facebook thinks about open source and how we are building a sustainable community that scales for a project of React Native's <a href="https://octoverse.github.com/projects#repositories" target="_blank" rel="noopener noreferrer">size</a>.</li><li>We are on track to remove multiple modules as part of the <a href="https://github.com/facebook/react-native/issues/23313" target="_blank" rel="noopener noreferrer">Lean Core</a> effort. Many modules like WebView and the React Native CLI have received more than 100 Pull Requests since they were extracted.</li><li>Next, we'll be focusing on overhauling the React Native website and documentation. Stay tuned!</li></ul><p>You'll find the episode in your favorite podcasting app soon or you can listen to the recording right here:</p><audio controls="" style="display:block;margin:0 auto" src="https://media.devchat.tv/reactnativeradio/React_Native_Radio_Episode_121.mp3"> <!-- --> <!-- --> Audio is unsupported in this browser.<!-- --> <!-- --> </audio>]]></content>
        <author>
            <name>Christoph Nakazawa</name>
            <uri>https://twitter.com/cpojer</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Releasing React Native 0.59]]></title>
        <id>/2019/03/12/releasing-react-native-059</id>
        <link href="https://reactnative.dev/blog/2019/03/12/releasing-react-native-059"/>
        <updated>2019-03-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Welcome to the 0.59 release of React Native! This is another big release with 644 commits by 88 contributors. Contributions also come in other forms, so thank you for maintaining issues, fostering communities, and teaching people about React Native. This month brings a number of highly anticipated changes, and we hope you enjoy them.]]></summary>
        <content type="html"><![CDATA[<p>Welcome to the 0.59 release of React Native! This is another big release with 644 commits by 88 contributors. Contributions also come in other forms, so <em>thank you</em> for maintaining issues, fostering communities, and teaching people about React Native. This month brings a number of highly anticipated changes, and we hope you enjoy them.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-hooks-are-here">🎣 Hooks are here<a class="hash-link" href="#-hooks-are-here" title="Direct link to heading">​</a></h2><p>React Hooks are part of this release, which let you reuse stateful logic across components. There is a lot of buzz about hooks, but if you haven't heard, take a look at some of the wonderful resources below:</p><blockquote><ul><li><a href="https://reactjs.org/docs/hooks-intro.html" target="_blank" rel="noopener noreferrer">Introducing Hooks</a> explains why we’re adding Hooks to React.</li><li><a href="https://reactjs.org/docs/hooks-overview.html" target="_blank" rel="noopener noreferrer">Hooks at a Glance</a> is a fast-paced overview of the built-in Hooks.</li><li><a href="https://reactjs.org/docs/hooks-custom.html" target="_blank" rel="noopener noreferrer">Building Your Own Hooks</a> demonstrates code reuse with custom Hooks.</li><li><a href="https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889" target="_blank" rel="noopener noreferrer">Making Sense of React Hooks</a> explores the new possibilities unlocked by Hooks.</li><li><a href="https://usehooks.com/" target="_blank" rel="noopener noreferrer">useHooks.com</a> showcases community-maintained Hooks recipes and demos.</li></ul></blockquote><p>Be sure to give this a try in your apps. We hope that you find the reuse as exciting as we do.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-updated-jsc-means-performance-gains-and-64-bit-support-on-android">📱 Updated JSC means performance gains and 64-bit support on Android<a class="hash-link" href="#-updated-jsc-means-performance-gains-and-64-bit-support-on-android" title="Direct link to heading">​</a></h2><p>React Native uses JSC (<a href="https://webkit.org/" target="_blank" rel="noopener noreferrer">JavaScriptCore</a>) to power your application. JSC on Android was a few years old, which meant that a lot of modern JavaScript features weren't supported. Even worse, it performed poorly compared iOS's modern JSC. With this release, that all changes.</p><p>Thanks to some awesome work by <a href="https://github.com/danielzlotin" target="_blank" rel="noopener noreferrer">@DanielZlotin</a>, <a href="https://github.com/dulmandakh" target="_blank" rel="noopener noreferrer">@dulmandakh</a>, <a href="https://github.com/gengjiawen" target="_blank" rel="noopener noreferrer">@gengjiawen</a>, <a href="https://github.com/kmagiera" target="_blank" rel="noopener noreferrer">@kmagiera</a>, and <a href="https://github.com/kudo" target="_blank" rel="noopener noreferrer">@kudo</a> JSC has caught up with the past few years. This brings with it 64-bit support, modern JavaScript support, and <a href="https://github.com/react-native-community/jsc-android-buildscripts/tree/master/measure" target="_blank" rel="noopener noreferrer">big performance improvements</a>. Kudos for also making this a maintainable process now so that we can take advantage of future WebKit improvements without so much legwork, and thank you Software Mansion and Expo for making this work possible.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-faster-app-launches-with-inline-requires">💨 Faster app launches with inline requires<a class="hash-link" href="#-faster-app-launches-with-inline-requires" title="Direct link to heading">​</a></h2><p>We want to help people have performant React Native apps by default and are working to bring Facebook's optimizations to the community. Applications load resources as needed rather than slowing down launch. This feature is called "inline requires", as it lets Metro identify components to be lazy loaded. Apps with a deep and varied component architecture will see the most improvement.</p><p><img loading="lazy" alt="source of the `metro.config.js` file in the 0.59 template, demonstrating where to enable `inlineRequires`" src="/assets/images/inline-requires-3cb1be96938288642a666bdf3dca62b5.png" width="724" height="485" class="img_SS3x"></p><p>We need the community to let us know how it works before we turn it on by default. When you upgrade to 0.59, there will be a new <code>metro.config.js</code> file; flip the options to true and give us <a href="https://twitter.com/hashtag/inline-requires" target="_blank" rel="noopener noreferrer">your feedback</a>! Read more about inline requires <a href="/docs/performance#inline-requires">in the performance docs</a> to benchmark your app.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-lean-core-is-underway">🚅 Lean core is underway<a class="hash-link" href="#-lean-core-is-underway" title="Direct link to heading">​</a></h2><p>React Native is a large and complex project with a complicated repository. This makes the codebase less approachable to contributors, difficult to test, and bloated as a dev dependency. <a href="https://github.com/react-native-community/discussions-and-proposals/issues/6" target="_blank" rel="noopener noreferrer">Lean Core</a> is our effort to address these issues by migrating code to separate libraries for better management. The past few releases have seen the first steps of this, but <a href="https://www.youtube.com/watch?v=FMLKb4or8yg" target="_blank" rel="noopener noreferrer">let's get serious</a>.</p><p>You may notice that additional components are now officially deprecated. This is great news, as there are now owners for these features actively maintaining them. Heed the warning messages and migrate to the new libraries for these features, because they will be removed in a future release. Below is a table indicating the component, its status, and where you may migrate your use to.</p><table><thead><tr><th>Component</th><th>Deprecated?</th><th>New home</th></tr></thead><tbody><tr><td><strong>AsyncStorage</strong></td><td>0.59</td><td><a href="https://github.com/react-native-community/react-native-async-storage" target="_blank" rel="noopener noreferrer">@react-native-community/react-native-async-storage</a></td></tr><tr><td><strong>ImageStore</strong></td><td>0.59</td><td><a href="https://github.com/expo/expo/tree/master/packages/expo-file-system" target="_blank" rel="noopener noreferrer">expo-file-system</a> or <a href="https://github.com/itinance/react-native-fs" target="_blank" rel="noopener noreferrer">react-native-fs</a></td></tr><tr><td><strong>MaskedViewIOS</strong></td><td>0.59</td><td><a href="https://github.com/react-native-community/react-native-masked-view" target="_blank" rel="noopener noreferrer">@react-native-community/react-native-masked-view</a></td></tr><tr><td><strong>NetInfo</strong></td><td>0.59</td><td><a href="https://github.com/react-native-community/react-native-netinfo" target="_blank" rel="noopener noreferrer">@react-native-community/react-native-netinfo</a></td></tr><tr><td><strong>Slider</strong></td><td>0.59</td><td><a href="https://github.com/react-native-community/react-native-slider" target="_blank" rel="noopener noreferrer">@react-native-community/react-native-slider</a></td></tr><tr><td><strong>ViewPagerAndroid</strong></td><td>0.59</td><td><a href="https://github.com/react-native-community/react-native-viewpager" target="_blank" rel="noopener noreferrer">@react-native-community/react-native-viewpager</a></td></tr></tbody></table><p>Over the coming months, there will be many more components following this path to a leaner core. We're looking for help with this <!-- -->—<!-- --> head over to the <a href="https://github.com/facebook/react-native/issues/23313" target="_blank" rel="noopener noreferrer">lean core umbrella</a> to pitch in.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-cli-improvements">👩🏽‍💻 CLI improvements<a class="hash-link" href="#-cli-improvements" title="Direct link to heading">​</a></h2><p>React Native's command line tools are developer's entry point to the ecosystem, but they had long-standing issues and lacked official support. The CLI tools have been moved to a <a href="https://github.com/react-native-community/react-native-cli" target="_blank" rel="noopener noreferrer">new repository</a>, and a <a href="https://blog.callstack.io/the-react-native-cli-has-a-new-home-79b63838f0e6" target="_blank" rel="noopener noreferrer">dedicated group of maintainers</a> have already made some exciting improvements.</p><p>Logs are formatted much better now. Commands now run nearly instantly <!-- -->—<!-- --> you'll immediately notice a difference:</p><p><img loading="lazy" alt="0.58&amp;#39;s CLI is slow to start" src="/assets/images/0.58-cli-speed-99311dbeb7f554d4beadd5960d82be74.png" width="724" height="399" class="img_SS3x"><img loading="lazy" alt="0.58&amp;#39;s CLI is nearly instantaneous" src="/assets/images/0.59-cli-speed-792273d28963a86e24e22ccfb69f1a99.png" width="724" height="399" class="img_SS3x"></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-upgrading-to-059">🚀 Upgrading to 0.59<a class="hash-link" href="#-upgrading-to-059" title="Direct link to heading">​</a></h2><p>We heard your feedback regarding the <a href="https://github.com/react-native-community/discussions-and-proposals/issues/68" target="_blank" rel="noopener noreferrer">React Native upgrade process</a> and we are taking steps to improve the experience in <a href="https://github.com/react-native-community/discussions-and-proposals/issues/64#issuecomment-444775432" target="_blank" rel="noopener noreferrer">future releases</a>. To upgrade to 0.59, we recommend using <a href="https://github.com/react-native-community/rn-diff-purge" target="_blank" rel="noopener noreferrer"><code>rn-diff-purge</code></a> to determine what has changed between your current React Native version and 0.59, then applying those changes manually. Once you've upgraded your project to 0.59, you will be able to use the newly improved <code>react-native upgrade</code> command (based on <code>rn-diff-purge</code>!) to upgrade to 0.60 and beyond as newer releases become available.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-breaking-changes">🔨 Breaking Changes<a class="hash-link" href="#-breaking-changes" title="Direct link to heading">​</a></h2><p>Android support in 0.59 has been cleaned up following Google's latest recommendations, which may result in potential breakage of existing apps. This issue might present as a runtime crash and a message, "You need to use a Theme.AppCompat theme (or descendant) with this activity". We recommend updating your project's <code>AndroidManifest.xml</code> file, making sure that the <code>android:theme</code> value is an <code>AppCompat</code> theme (such as <code>@style/Theme.AppCompat.Light.NoActionBar</code>).</p><p>The <code>react-native-git-upgrade</code> command has been removed in 0.59, in favor of the newly improved <code>react-native upgrade</code> command.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-thanks">🤗 Thanks<a class="hash-link" href="#-thanks" title="Direct link to heading">​</a></h2><p>Lots of new contributors helped with <a href="https://github.com/facebook/react-native/issues/22990" target="_blank" rel="noopener noreferrer">enabling generation of native code from flow types</a> and <a href="https://github.com/facebook/react-native/issues/22609" target="_blank" rel="noopener noreferrer">resolving Xcode warnings</a> - these are a great way to learn how React Native works and contributing to the greater good. Thank you! Look out for similar issues in the future.</p><p>While these are the highlights that we noted, there are many others to be excited about. To see all of the updates, take a look at the <a href="https://github.com/react-native-community/react-native-releases/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer">changelog</a>. 0.59 is a huge release – we can't wait for you to try it out.</p><p>We have even more improvements coming throughout the rest of the year. Stay tuned!</p><p><a href="https://github.com/turnrye" target="_blank" rel="noopener noreferrer">Ryan</a> and the whole <a href="https://twitter.com/reactnative" target="_blank" rel="noopener noreferrer">React Native core team</a></p>]]></content>
        <author>
            <name>Ryan Turner</name>
            <uri>https://twitter.com/turnrye</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Open Source Update March 2019]]></title>
        <id>/2019/03/01/react-native-open-source-update</id>
        <link href="https://reactnative.dev/blog/2019/03/01/react-native-open-source-update"/>
        <updated>2019-03-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We announced our React Native Open Source roadmap in Q4 2018 after deciding to invest more in the React Native open source community.]]></summary>
        <content type="html"><![CDATA[<p>We announced our <a href="/blog/2018/11/01/oss-roadmap">React Native Open Source roadmap</a> in Q4 2018 after deciding to invest more in the React Native open source community.</p><p>For our first milestone, we focused on identifying and improving the most visible aspects of our community. Our goals were to reduce outstanding pull requests, reduce the project's surface area, identify leading user problems, and establish guidelines for community management.</p><p>In the past two months, we made more progress than we expected. Read on for more details:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="pull-requests">Pull Requests<a class="hash-link" href="#pull-requests" title="Direct link to heading">​</a></h3><p>In order to build a healthy community, we must respond quickly to code contributions. In past years, we de-prioritized reviewing community contributions and accumulated 280 pull requests (December 2018). In the first milestone, we reduced the number of open pull requests to ~65. Simultaneously, the average number of pull requests opened per day increased from 3.5 to 7 which means we have handled about <a href="https://github.com/facebook/react-native/pulls?page=24&amp;q=is%3Apr+closed%3A%3E2018-12-01&amp;utf8=%E2%9C%93" target="_blank" rel="noopener noreferrer">600 pull requests</a> in the last three months.</p><p>We merged <a href="https://github.com/facebook/react-native/pulls?utf8=%E2%9C%93&amp;q=is%3Apr+closed%3A%3E2018-12-01+label%3A%22Merged%22+" target="_blank" rel="noopener noreferrer">almost two-thirds</a> and closed one-third of the pull requests. They were closed without being merged if they are obsolete or low quality, or if they unnecessarily increase the project's surface area. Most of the merged pull requests fixed bugs, improved cross-platform parity, or introduced new features. Notable contributions include improving type safety and the ongoing work to support AndroidX.</p><p>At Facebook, we run React Native from master, so we test all changes first before they make it into a React Native Release. Out of all the merged pull requests, only six caused issues: four only affected internal development and two were caught in the release candidate state.</p><p>One of the more visible community contributions was <a href="https://github.com/facebook/react-native/pull/22242" target="_blank" rel="noopener noreferrer">the updated “RedBox” screen</a>. It's a good example of how the community is making the developer experience friendlier.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="lean-core">Lean Core<a class="hash-link" href="#lean-core" title="Direct link to heading">​</a></h3><p>React Native currently has a very wide surface area with many unmaintained abstractions that we do not use a lot at Facebook. We are working on reducing the surface area in order to make React Native smaller and allow the community to take better care of abstractions that are mostly unused at Facebook.</p><p>In the first milestone, <a href="https://twitter.com/reactnative/status/1093171521114247171" target="_blank" rel="noopener noreferrer">we asked the community for help on the Lean Core project</a>. The response was overwhelming and we could barely keep up with all the progress. <a href="https://github.com/facebook/react-native/issues/23313" target="_blank" rel="noopener noreferrer">Check out all the work completed in less than a month</a>!</p><p>What we are most excited about is that maintainers have jumped in fixing long standing issues, adding tests, and supporting long requested features. These modules are getting more support than they ever did within React Native, showing that this is a great step for the community. Examples of such projects are <a href="https://github.com/react-native-community/react-native-webview" target="_blank" rel="noopener noreferrer">WebView</a> that has <a href="https://twitter.com/titozzz/status/1101283928026034176" target="_blank" rel="noopener noreferrer">received many pull requests</a> since their extraction and the CLI that is now <a href="https://blog.callstack.io/the-react-native-cli-has-a-new-home-79b63838f0e6" target="_blank" rel="noopener noreferrer">maintained by members of the community</a> and received much needed improvements and fixes.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="leading-user-problems">Leading User Problems<a class="hash-link" href="#leading-user-problems" title="Direct link to heading">​</a></h3><p>In December, we asked the community what they <a href="https://github.com/react-native-community/discussions-and-proposals/issues/64" target="_blank" rel="noopener noreferrer">disliked about React Native</a>. We aggregated the responses and <a href="https://github.com/react-native-community/discussions-and-proposals/issues/104" target="_blank" rel="noopener noreferrer">replied to each and every problem</a>. Fortunately, many of the issues that our community faces are also problems at Facebook. In our next milestone, we plan to address some of the main problems.</p><p>One of the highest voted problems was the developer experience of upgrading to newer versions of React Native. Unfortunately, this is not something that we experience ourselves because we run React Native from master. Thankfully, members from the community already stepped up to address this problem:</p><ul><li><a href="https://github.com/thymikee" target="_blank" rel="noopener noreferrer">Michał Pierzchała</a> from Callstack <a href="https://github.com/react-native-community/react-native-cli/pull/176/files" target="_blank" rel="noopener noreferrer">improved react-native upgrade</a> by using <a href="https://github.com/react-native-community/rn-diff-purge" target="_blank" rel="noopener noreferrer">rn-diff-purge</a> under the hood. We also updated the website to remove outdated upgrade instructions.</li><li><a href="https://github.com/facebook/react-native/pull/23563" target="_blank" rel="noopener noreferrer">We plan on recommending CocoaPods by default for iOS projects</a> which will reduce churn in project files when upgrading React Native. This will make it easier for people to install and link third-party modules which is even more important in the context of Lean Core as we expect projects to link more modules by default.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="059-release">0.59 Release<a class="hash-link" href="#059-release" title="Direct link to heading">​</a></h3><p>Without the help of the React Native community, especially <a href="https://github.com/grabbou" target="_blank" rel="noopener noreferrer">Mike Grabowski</a> and <a href="https://github.com/kelset" target="_blank" rel="noopener noreferrer">Lorenzo Sciandra</a>, we would not be able to ship releases. We want to improve the release management process and plan to be more involved from now on:</p><ul><li>We will work with community members to create a blog post for each major release.</li><li>We will show breaking changes directly in the CLI when people upgrade to new versions.</li><li>We will reduce the time it takes to make a release. We are exploring ways to increase automated testing and also creating an improved manual test plan.</li></ul><p>Many of these plans will be incorporated in the upcoming <a href="https://github.com/facebook/react-native/releases/tag/v0.59.0-rc.3" target="_blank" rel="noopener noreferrer">React Native 0.59 release</a>. 0.59 will ship with React Hooks, a new 64-bit version of JavaScriptCore for Android, and many performance and functionality improvements. It is currently published as a release candidate and is expected to be stable within the next two weeks.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="next-steps">Next Steps<a class="hash-link" href="#next-steps" title="Direct link to heading">​</a></h3><p>For the next two months, we will continue managing pull requests <a href="https://k03lwm00zo.codesandbox.io/" target="_blank" rel="noopener noreferrer">to stay on track</a> while also starting to reduce the number of outstanding GitHub issues. We will continue reducing the surface area of React Native through the Lean Core project. We plan to address 5 of the top community problems. As we finalize the community guidelines, we will turn attention to our website and documentation.</p><p>We are very excited to host over ten contributors from our community at Facebook London in March to help drive several of these efforts. We are glad that you are using React Native and hope that you'll see and feel the improvements we are working on in 2019. We'll be back with another update in a few months and <em>will be merging your pull requests in the meantime!</em> ⚛️✌️</p>]]></content>
        <author>
            <name>Christoph Nakazawa</name>
            <uri>https://twitter.com/cpojer</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[The State of the React Native Community in 2018]]></title>
        <id>/2019/01/07/state-of-react-native-community</id>
        <link href="https://reactnative.dev/blog/2019/01/07/state-of-react-native-community"/>
        <updated>2019-01-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[In 2018 the React Native Community made a number of changes to the way we develop and communicate about React Native. We believe that a few years from now we will look back and see that this shift was a turning point for React Native.]]></summary>
        <content type="html"><![CDATA[<p>In 2018 the React Native Community made a number of changes to the way we develop and communicate about React Native. We believe that a few years from now we will look back and see that this shift was a turning point for React Native.</p><p>A lot of people are excited about the rewrite of React Native's architecture, widely known as <a href="https://github.com/react-native-community/discussions-and-proposals/issues/4" target="_blank" rel="noopener noreferrer">Fabric</a>. Among other things, this will fix fundamental limitations in React Native's architecture and will set up React Native for success in the future together with <a href="https://github.com/react-native-community/discussions-and-proposals/issues/40" target="_blank" rel="noopener noreferrer">JSI and TurboModules</a>.</p><p>The biggest shift in 2018 was to empower the React Native Community. From the beginning, Facebook encouraged developers from all around the world to participate in React Native's open source project. Since then, a number of core contributors emerged to handle, among other things, the release process.</p><p>These members took a few substantial steps towards making the whole community more empowered to shape the future of this project with the following resources:</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="react-native-releases-"><a href="https://github.com/react-native-community/react-native-releases" target="_blank" rel="noopener noreferrer"><code>react-native-releases</code></a> 📬<a class="hash-link" href="#react-native-releases-" title="Direct link to heading">​</a></h2><p>This repository, created in January, serves the dual purpose of allowing everyone to keep up the new releases in a more collaborative manner and opened the conversation of what would be part of a certain release to whomever wanted to suggest a cherry-pick (like for <a href="https://github.com/react-native-community/react-native-releases/issues/71" target="_blank" rel="noopener noreferrer">0.57.8</a> and all its previous versions).</p><p>This has been the driving force behind moving away from a monthly release cycle, and the "long term support" approach currently used for version 0.57.x.</p><p>Half of the credit for reaching these decisions goes to the other repository created this year:</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="discussions-and-proposals-"><a href="https://github.com/react-native-community/discussions-and-proposals" target="_blank" rel="noopener noreferrer"><code>discussions-and-proposals</code></a> 🗣<a class="hash-link" href="#discussions-and-proposals-" title="Direct link to heading">​</a></h2><p>This repository, created in July, expanded on the idea of a more open environment for conversations on React Native. Previously, this need was handled by issues labelled <a href="https://github.com/facebook/react-native/labels/For%20Discussion" target="_blank" rel="noopener noreferrer"><code>For Discussion</code></a> in the main repository, but we wanted to expand this strategy to an RFC approach that other libraries have (e.g. React).</p><p>This experiment immediately found its role in the React Native lifecycle. The Facebook team is now using the community RFC process to discuss what could <a href="https://github.com/react-native-community/discussions-and-proposals/issues/64" target="_blank" rel="noopener noreferrer">be improved in React Native</a>, and coordinate the efforts around the <a href="https://github.com/react-native-community/discussions-and-proposals/issues/6" target="_blank" rel="noopener noreferrer">Lean Core project</a> - among other interesting discussions.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="reactnativecomm-"><a href="https://twitter.com/ReactNativeComm" target="_blank" rel="noopener noreferrer">@ReactNativeComm</a> 🐣<a class="hash-link" href="#reactnativecomm-" title="Direct link to heading">​</a></h2><p>We are aware that our approach to communicate these efforts has not been as effective as we would have liked, and in an attempt to give you all an easier time keeping up with everything going on in the React Native Community (from releases to active discussions) we created a new twitter account that you can rely on <a href="https://twitter.com/ReactNativeComm" target="_blank" rel="noopener noreferrer">@ReactNativeComm</a>.</p><p>If you are not on that social network, remember that you can always watch repositories via GitHub; this feature improved these past few months with the possibility of being notified only for releases, so you should consider using it anyway.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="what-awaits-ahead-">What awaits ahead 🎓<a class="hash-link" href="#what-awaits-ahead-" title="Direct link to heading">​</a></h2><p>Over the past 7-8 months, core contributors enhanced the <a href="https://github.com/react-native-community" target="_blank" rel="noopener noreferrer">React Native Community GitHub organization</a> to take more ownership over the development of React Native, and enhance collaboration with Facebook. But this always lacked the formal structure that similar projects may have in place.</p><p>This organization can set the example for everyone in the larger developer community by enforcing a set of standards for all the packages/repos hosted in it, providing a single place for maintainers to help each other and contribute quality code that conforms to community-agreed standards.</p><p>In early 2019, we will have this new set of guidelines in place. Let us know what you think in the <a href="https://github.com/react-native-community/discussions-and-proposals/issues/63" target="_blank" rel="noopener noreferrer">dedicated discussion</a>.</p><p>We are confident that with these changes, the community will become more collaborative so that when we reach 1.0, we will all continue to write (even more) awesome apps by leveraging this joint effort 🤗</p><hr><p>I hope you are as excited as we are about the future of this community. We're excited to see all of you involved either in the conversations happening in the repositories listed above or via the awesome code you’ll produce.</p><p>Happy coding!</p>]]></content>
        <author>
            <name>Lorenzo Sciandra</name>
            <uri>https://github.com/kelset</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Open Source Roadmap]]></title>
        <id>/2018/11/01/oss-roadmap</id>
        <link href="https://reactnative.dev/blog/2018/11/01/oss-roadmap"/>
        <updated>2018-11-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[This year, the React Native team has focused on a large scale re-architecture of React Native. As Sophie mentioned in her State of React Native post, we've sketched out a plan to better support the thriving population of React Native users and collaborators outside of Facebook. It's now time to share more details about what we've been working on. Before I do so, I'd like to lay out our long-term vision for React Native in open source.]]></summary>
        <content type="html"><![CDATA[<p><img loading="lazy" src="/assets/images/oss-roadmap-hero-3e488e41aaa6ecb2107c16608d5d9392.jpg" width="1817" height="787" class="img_SS3x"></p><p>This year, the React Native team has focused on a large scale <a href="https://github.com/react-native-community/discussions-and-proposals/issues/4" target="_blank" rel="noopener noreferrer">re-architecture of React Native</a>. As Sophie mentioned in her <a href="/blog/2018/06/14/state-of-react-native-2018">State of React Native post,</a> we've sketched out a plan to better support the thriving population of React Native users and collaborators outside of Facebook. It's now time to share more details about what we've been working on. Before I do so, I'd like to lay out our long-term vision for React Native in open source.</p><p>Our vision for React Native is...</p><ul><li><strong>A healthy GitHub repository.</strong> Issues and pull requests get handled within a reasonable period of time.<ul><li>Increased test coverage.</li><li>Commits that sync out from the Facebook code repository should not break open source tests.</li><li>A higher scale of meaningful community contributions.</li></ul></li><li><strong>Stable APIs,</strong> making it easier to interface with open source dependencies.<ul><li>Facebook uses the same public API as open source</li><li>React Native releases that follow semantic versioning.</li></ul></li><li><strong>A vibrant eco-system.</strong> High quality ViewManagers, native modules, and multiple platform support maintained by the community.</li><li><strong>Excellent documentation.</strong> Focus on helping users create high quality experiences, and up-to-date API reference docs.</li></ul><p>We have identified the following focus areas to help us achieve this vision.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="️-lean-core">✂️ Lean Core<a class="hash-link" href="#️-lean-core" title="Direct link to heading">​</a></h2><p>Our goal is to <a href="https://github.com/react-native-community/discussions-and-proposals/issues/6" target="_blank" rel="noopener noreferrer">reduce the surface area of React Native</a> by removing non-core and unused components. We'll transfer non-core components to the community to allow it to move faster. The reduced surface area will make it easier to manage contributions to React Native.</p><p><a href="https://github.com/react-native-community/discussions-and-proposals/blob/master/proposals/0001-webview.md" target="_blank" rel="noopener noreferrer"><code>WebView</code></a> is an example of a component that we transferred to the community. We are working on a workflow that will allow internal teams to continue using these components after we remove them from the repository. We have identified <a href="https://github.com/react-native-community/discussions-and-proposals/issues/6" target="_blank" rel="noopener noreferrer">dozens more components</a> that we'll give ownership of to the community.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-open-sourcing-internals-and-updated-tooling">🎁 Open Sourcing Internals and 🛠Updated Tooling<a class="hash-link" href="#-open-sourcing-internals-and-updated-tooling" title="Direct link to heading">​</a></h2><p>The React Native development experience for product teams at Facebook can be quite different from open source. Tools that may be popular in the open source community are not used at Facebook. There may be an internal tool that achieves the same purpose. In some cases, Facebook teams have become used to tools that do not exist outside of Facebook. These disparities can pose challenges when we open source our upcoming architecture work.</p><p>We'll work on releasing some of these internal tools. We'll also improve support for tools popular with the open source community. Here's a non-exhaustive list of projects we'll tackle:</p><ul><li>Open source JSI and enable the community to bring their own JavaScript VMs, replacing the existing JavaScriptCore from RN's initial release. We'll be covering what JSI is in a future post, in the meantime you can learn more about JSI from <a href="https://www.youtube.com/watch?v=UcqRXTriUVI" target="_blank" rel="noopener noreferrer">Parashuram's talk at React Conf</a>.</li><li>Support 64-bit libraries on Android.</li><li>Enable debugging under the new architecture.</li><li>Improve support for CocoaPods, Gradle, Maven, and new Xcode build system.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-testing-infrastructure">✅ Testing Infrastructure<a class="hash-link" href="#-testing-infrastructure" title="Direct link to heading">​</a></h2><p>When Facebook engineers publish code, it's considered safe to land if it passes all tests. These tests identify whether a change might break one of our own React Native surfaces. Yet, there are differences in how Facebook uses React Native. This has allowed us to unknowingly break React Native in open source.</p><p>We'll shore up our internal tests to ensure they run in an environment that is as close as possible to open source. This will help prevent code that breaks these tests from making it to open source. We will also work on infrastructure to enable better testing of the core repo on GitHub, enabling future pull requests to easily include tests.</p><p>Combined with the reduced surface area, this will allow contributors to merge pull requests quicker, with confidence.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-public-api">📜 Public API<a class="hash-link" href="#-public-api" title="Direct link to heading">​</a></h2><p>Facebook will consume React Native via the public API, the same way open source does, to reduce unintentional breaking changes. We have started converting internal call sites to address this. Our goal is to converge on a stable, public API, leading to the adoption of semantic versioning in version 1.0.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="-communication">📣 Communication<a class="hash-link" href="#-communication" title="Direct link to heading">​</a></h2><p>React Native is one of the <a href="https://octoverse.github.com/#top-and-trending-projects" target="_blank" rel="noopener noreferrer">top open source projects on GitHub</a> by contributor count. That makes us really happy, and we'd like to keep it going. We'll continue working on initiatives that lead to involved contributors, such as increased transparency and open discussion. The documentation is one of the first things someone new to React Native will encounter, yet it has not been a priority. We'd like to fix that, starting with bringing back auto-generated API reference docs, creating additional content focused on creating <a href="/docs/improvingux">quality user experiences</a>, and improving our <a href="https://github.com/react-native-community/react-native-releases/issues/47" target="_blank" rel="noopener noreferrer">release notes</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="timeline">Timeline<a class="hash-link" href="#timeline" title="Direct link to heading">​</a></h2><p>We're planning to land these projects throughout the next year or so. Some of these efforts are already ongoing, such as <a href="https://github.com/facebook/react-native/compare/e337bcafb0b017311c37f2dbc24e5a757af0a205...8427f64e06456f171f9df0316c6ca40613de7a20" target="_blank" rel="noopener noreferrer">JSI which has already landed in open source</a>. Others will take a bit longer to complete, such as reducing the surface area. We'll do our best to keep the community up to date with our progress. Please join us in the <a href="https://github.com/react-native-community/discussions-and-proposals" target="_blank" rel="noopener noreferrer">Discussions and Proposals</a> repository, a initiative from the React Native community that has led to the creation of several of the initiatives discussed in this roadmap.</p>]]></content>
        <author>
            <name>Héctor Ramos</name>
            <uri>https://hectorramos.com/about</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing new iOS WebViews]]></title>
        <id>/2018/08/27/wkwebview</id>
        <link href="https://reactnative.dev/blog/2018/08/27/wkwebview"/>
        <updated>2018-08-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[For a long time now, Apple has discouraged using UIWebViews in favor of WKWebView. In iOS 12, which will be released in the upcoming months, UIWebViews will be formally deprecated. React Native's iOS WebView implementation relies heavily on the UIWebView class. Therefore, in light of these developments, we've built a new native iOS backend to the WebView React Native component that uses WKWebView.]]></summary>
        <content type="html"><![CDATA[<p>For a long time now, Apple has discouraged using UIWebViews in favor of WKWebView. In iOS 12, which will be released in the upcoming months, <a href="https://developer.apple.com/videos/play/wwdc2018/234/?time=104" target="_blank" rel="noopener noreferrer">UIWebViews will be formally deprecated</a>. React Native's iOS WebView implementation relies heavily on the UIWebView class. Therefore, in light of these developments, we've built a new native iOS backend to the WebView React Native component that uses WKWebView.</p><p>The tail end of these changes were landed in <a href="https://github.com/facebook/react-native/commit/33b353c97c31190439a22febbd3d2a9ead49d3c9" target="_blank" rel="noopener noreferrer">this commit</a>, and will become available in the 0.57 release.</p><p>To opt into this new implementation, please use the <a href="https://reactnative.dev/docs/0.63/webview#usewebkit" target="_blank" rel="noopener noreferrer"><code>useWebKit</code></a> prop:</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">WebView</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  useWebKit</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  source</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token punctuation" style="color:#657b83">{</span><span class="token literal-property property" style="color:#2aa198">url</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'https://www.google.com'</span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">/</span><span class="token operator" style="color:#fc929e">&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="improvements">Improvements<a class="hash-link" href="#improvements" title="Direct link to heading">​</a></h2><p><code>UIWebView</code> had no legitimate way to facilitate communication between the JavaScript running in the WebView, and React Native. When messages were sent from the WebView, we relied on a hack to deliver them to React Native. Succinctly, we encoded the message data into a url with a special scheme, and navigated the WebView to it. On the native side, we intercepted and cancelled this navigation, parsed the data from the url, and finally called into React Native. This implementation was error prone and insecure. I'm glad to announce that we've leveraged <code>WKWebView</code> features to completely replace it.</p><p>Other benefits of WKWebView over UIWebView include faster JavaScript execution, and a multi-process architecture. Please see this <a href="https://developer.apple.com/videos/play/wwdc2014/206" target="_blank" rel="noopener noreferrer">2014 WWDC</a> for more details.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="caveats">Caveats<a class="hash-link" href="#caveats" title="Direct link to heading">​</a></h2><p>If your components use the following props, then you may experience problems when switching to WKWebView. For the time being, we suggest that you avoid using these props:</p><p><strong>Inconsistent behavior:</strong></p><p><code>automaticallyAdjustContentInsets</code> and <code>contentInsets</code> (<a href="https://github.com/facebook/react-native/commit/bacfd9297657569006bab2b1f024ad1f289b1b27" target="_blank" rel="noopener noreferrer">commit</a>)</p><p>When you add contentInsets to a <code>WKWebView</code>, it doesn't change the <code>WKWebView</code>'s viewport. The viewport remains the same size as the frame. With <code>UIWebView</code>, the viewport size actually changes (gets smaller, if the content insets are positive).</p><p><code>backgroundColor</code> (<a href="https://github.com/facebook/react-native/commit/215fa14efc2a817c7e038075163491c8d21526fd" target="_blank" rel="noopener noreferrer">commit</a>)</p><p>With the new iOS implementation of WebView, there's a chance that your background color will flicker into view if you use this property. Furthermore, <code>WKWebView</code> renders transparent backgrounds differently from <code>UIWebview</code>. Please look at the commit description for more details.</p><p><strong>Not supported:</strong></p><p><code>scalesPageToFit</code> (<a href="https://github.com/facebook/react-native/commit/b18fddadfeae5512690a0a059a4fa80c864f43a3" target="_blank" rel="noopener noreferrer">commit</a>)</p><p>WKWebView didn't support the scalesPageToFit prop, so we couldn't implement this on the WebView React Native component.</p>]]></content>
        <author>
            <name>Ramanpreet Nara</name>
            <uri>https://github.com/rsnara</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Accessibility API Updates]]></title>
        <id>/2018/08/13/react-native-accessibility-updates</id>
        <link href="https://reactnative.dev/blog/2018/08/13/react-native-accessibility-updates"/>
        <updated>2018-08-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Motivation]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_JmGV" id="motivation">Motivation<a class="hash-link" href="#motivation" title="Direct link to heading">​</a></h2><p>As technology advances and mobile apps become increasingly important to everyday life, the necessity of creating accessible applications has likewise grown in importance.</p><p>React Native's limited Accessibility API has always been a huge pain point for developers, so we've made a few updates to the Accessibility API to make it easier to create inclusive mobile applications.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="problems-with-the-existing-api">Problems With the Existing API<a class="hash-link" href="#problems-with-the-existing-api" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_JmGV" id="problem-one-two-completely-different-yet-similar-props---accessibilitycomponenttype-android-and-accessibilitytraits-ios">Problem One: Two Completely Different Yet Similar Props - accessibilityComponentType (Android) and accessibilityTraits (iOS)<a class="hash-link" href="#problem-one-two-completely-different-yet-similar-props---accessibilitycomponenttype-android-and-accessibilitytraits-ios" title="Direct link to heading">​</a></h3><p><code>accessibilityComponentType</code> and <code>accessibilityTraits</code> are two properties that are used to tell TalkBack on Android and VoiceOver on iOS what kind of UI element the user is interacting with. The two biggest problems with these properties are that:</p><ol><li><strong>They are two different properties with different usage methods, yet have the same purpose.</strong> In the previous API, these are two separate properties (one for each platform), which was not only inconvenient, but also confusing to many developers. <code>accessibilityTraits</code> on iOS allows 17 different values while <code>accessibilityComponentType</code> on Android allows only 4 values. Furthermore, the values for the most part had no overlap. Even the input types for these two properties are different. <code>accessibilityTraits</code> allows either an array of traits to be passed in or a single trait, while <code>accessibilityComponentType</code> allows only a single value.</li><li><strong>There is very limited functionality on Android.</strong> With the old property, the only UI elements that Talkback were able to recognize were “button,” “radiobutton_checked,” and “radiobutton_unchecked.”</li></ol><h3 class="anchor anchorWithStickyNavbar_JmGV" id="problem-two-non-existent-accessibility-hints">Problem Two: Non-existent Accessibility Hints:<a class="hash-link" href="#problem-two-non-existent-accessibility-hints" title="Direct link to heading">​</a></h3><p>Accessibility Hints help users using TalkBack or VoiceOver understand what will happen when they perform an action on an accessibility element that is not apparent by only the accessibility label. These hints can be turned on and off in the settings panel. Previously, React Native's API did not support accessibility hints at all.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="problem-three-ignoring-inverted-colors">Problem Three: Ignoring Inverted Colors:<a class="hash-link" href="#problem-three-ignoring-inverted-colors" title="Direct link to heading">​</a></h3><p>Some users with vision loss use inverted colors on their mobile phones to have greater screen contrast. Apple provided an API for iOS which allows developers to ignore certain views. This way, images and videos aren't distorted when a user has the inverted colors setting on. This API is currently unsupported by React Native.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="design-of-the-new-api">Design of the New API<a class="hash-link" href="#design-of-the-new-api" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_JmGV" id="solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios">Solution One: Combining accessibilityComponentType (Android) and accessibilityTraits (iOS)<a class="hash-link" href="#solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios" title="Direct link to heading">​</a></h3><p>In order to solve the confusion between <code>accessibilityComponentType</code> and <code>accessibilityTraits</code>, we decided to merge them into a single property. This made sense because they technically had the same intended functionality and by merging them, developers no longer had to worry about platform specific intricacies when building accessibility features.</p><p><strong>Background</strong></p><p>On iOS, <code>UIAccessibilityTraits</code> is a property that can be set on any NSObject. Each of the 17 traits passed in through the javascript property to native is mapped to a <code>UIAccessibilityTraits</code> element in Objective-C. Traits are each represented by a long int, and every trait that is set is ORed together.</p><p>On Android however, <code>AccessibilityComponentType</code> is a concept that was made up by React Native, and doesn't directly map to any properties in Android. Accessibility is handled by an accessibility delegate. Each view has a default accessibility delegate. If you want to customize any accessibility actions, you have to create a new accessibility delegate, override specific methods you want to customize, and then set the accessibility delegate of the view you are handling to be associated with the new delegate. When a developer set <code>AccessibilityComponentType</code>, the native code created a new delegate based off of the component that was passed in, and set the view to have that accessibility delegate.</p><p><strong>Changes Made</strong></p><p>For our new property, we wanted to create a superset of the two properties. We decided to keep the new property modeled mostly after the existing property <code>accessibilityTraits</code>, since <code>accessibilityTraits</code> has significantly more values. The functionality of Android for these traits would be polyfilled in by modifying the Accessibility Delegate.</p><p>There are 17 values of UIAccessibilityTraits that <code>accessibilityTraits</code> on iOS can be set to. However, we didn't include all of them as possible values to our new property. This is because the effect of setting some of these traits is actually not very well known, and many of these values are virtually never used.</p><p>The values UIAccessibilityTraits were set to generally took on one of two purposes. They either described a role that UI element had, or they described the state a UI element was in. Most uses of the previous properties we observed usually used one value that represented a role and combined it with either “state selected,” “state disabled,” or both. Therefore, we decided to create two new accessibility properties: <code>accessibilityRole</code> and <code>accessibilityState</code>.</p><p><strong><code>accessibilityRole</code></strong></p><p>The new property, <code>accessibilityRole</code>, is used to tell Talkback or Voiceover the role of a UI Element. This new property can take on one of the following values:</p><ul><li><code>none</code></li><li><code>button</code></li><li><code>link</code></li><li><code>search</code></li><li><code>image</code></li><li><code>keyboardkey</code></li><li><code>text</code></li><li><code>adjustable</code></li><li><code>header</code></li><li><code>summary</code></li><li><code>imagebutton</code></li></ul><p>This property only allows one value to be passed in because UI elements generally don't logically take on more than one of these. The exception is image and button, so we've added a role imagebutton that is a combination of both.</p><p><strong><code>accessibilityStates</code></strong></p><p>The new property, <code>accessibilityStates</code>, is used to tell Talkback or Voiceover the state a UI Element is in. This property takes on an Array containing one or both of the following values:</p><ul><li><code>selected</code></li><li><code>disabled</code></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="solution-two-adding-accessibility-hints">Solution Two: Adding Accessibility Hints<a class="hash-link" href="#solution-two-adding-accessibility-hints" title="Direct link to heading">​</a></h3><p>For this, we added a new property, <code>accessibilityHint</code>. Setting this property will allow Talkback or Voiceover to recite the hint to users.</p><p><strong><code>accessibilityHint</code></strong></p><p>This property takes in the accessibility hint to be read in the form of a String.</p><p>On iOS, setting this property will set the corresponding native property AccessibilityHint on the view. The hint will then be read by Voiceover if Accessibility Hints are turned on in the iPhone.</p><p>On Android, setting this property appends the value of the hint to the end of the accessibility label. The upside to this implementation is that it mimics the behavior of hints on iOS, but the downside to this implementation is that these hints cannot be turned off in the settings on Android the way they can be on iOS.</p><p>The reason we made this decision on Android is because normally, accessibility hints correspond with a specific action (e.g. click), and we wanted to keep behaviors consistent across platforms.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="solution-to-problem-three">Solution to Problem Three<a class="hash-link" href="#solution-to-problem-three" title="Direct link to heading">​</a></h3><p><strong><code>accessibilityIgnoresInvertColors</code></strong></p><p>We exposed Apple's api AccessibilityIgnoresInvertColors to JavaScript, so now when you have a view where you don't want colors to be inverted (e.g image), you can set this property to true, and it won't be inverted.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="new-usage">New Usage<a class="hash-link" href="#new-usage" title="Direct link to heading">​</a></h2><p>These new properties will become available in the React Native 0.57 release.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="how-to-upgrade">How to Upgrade<a class="hash-link" href="#how-to-upgrade" title="Direct link to heading">​</a></h3><p>If you are currently using <code>accessibilityComponentType</code> and <code>accessibilityTraits</code>, here are the steps you can take to upgrade to the new properties.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="1-using-jscodeshift">1. Using jscodeshift<a class="hash-link" href="#1-using-jscodeshift" title="Direct link to heading">​</a></h4><p>The most simple use cases can be replaced by running a jscodeshift script.</p><p>This <a href="https://gist.github.com/ziqichen6/246e5778617224d2b4aff198dab0305d" target="_blank" rel="noopener noreferrer">script</a> replaces the following instances:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">accessibilityTraits</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain">“trait”</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">accessibilityTraits</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain">“trait”</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>With</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">accessibilityRole</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> “trait”</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This script also removes instances of <code>AccessibilityComponentType</code> (assuming everywhere you set <code>AccessibilityComponentType</code>, you would also set <code>AccessibilityTraits</code>).</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="2-using-a-manual-codemod">2. Using a manual codemod<a class="hash-link" href="#2-using-a-manual-codemod" title="Direct link to heading">​</a></h4><p>For the cases that used <code>AccessibilityTraits</code> that don't have a corresponding value for <code>AccessibilityRole</code>, and the cases where multiple traits were passed into <code>AccessibilityTraits</code>, a manual codemod would have to be done.</p><p>In general,</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">accessibilityTraits</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain">“button”</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> “selected”</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>would be manually replaced with</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">accessibilityRole</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain">“button”</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">accessibilityStates</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain">“selected”</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>These properties are already being used in Facebook's codebase. The codemod for Facebook was surprisingly simple. The jscodeshift script fixed about half of our instances, and the other half was fixed manually. Overall, the entire process took less than a few hours.</p><p>Hopefully you will find the updated API useful! And please continue making apps accessible! #inclusion</p>]]></content>
        <author>
            <name>Ziqi Chen</name>
            <uri>https://ziqichen.com/</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Releasing 0.56]]></title>
        <id>/2018/07/04/releasing-react-native-056</id>
        <link href="https://reactnative.dev/blog/2018/07/04/releasing-react-native-056"/>
        <updated>2018-07-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The long-awaited 0.56 version of React Native is now available 🎉. This blog post highlights some of the changes introduced in this new release. We also want to take the opportunity to explain what has kept us busy since March.]]></summary>
        <content type="html"><![CDATA[<p>The long-awaited 0.56 version of React Native is now available 🎉. This blog post highlights some of the <a href="https://github.com/react-native-community/react-native-releases/blob/master/CHANGELOG.md#highlights" target="_blank" rel="noopener noreferrer">changes</a> introduced in this new release. We also want to take the opportunity to explain what has kept us busy since March.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="the-breaking-changes-dilemma-or-when-to-release">The breaking changes dilemma, or, "when to release?"<a class="hash-link" href="#the-breaking-changes-dilemma-or-when-to-release" title="Direct link to heading">​</a></h3><p>The <a href="https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">Contributor's Guide</a> explains the integration process that all changes to React Native go through. The project has is composed by <a href="https://github.com/facebook/react-native-website/issues/370" target="_blank" rel="noopener noreferrer">many different tools</a>, requiring coordination and constant support to keep everything working properly. Add to this the vibrant open source community that contributes back to the project, and you will get a sense of the mind-bending scale of it all.</p><p>With React Native's impressive adoption, breaking changes must be made with great care, and the process is not as smooth as we'd like. A decision was made to skip the April and May releases to allow the core team to integrate and test a new set of breaking changes. <a href="https://github.com/react-native-community/react-native-releases/issues/14" target="_blank" rel="noopener noreferrer">Dedicated community communication</a> channels were used along the way to ensure that the June 2018 (<code>0.56.0</code>) release is as hassle-free as possible to adopt by those who patiently waited for the stable release.</p><p>Is <code>0.56.0</code> perfect? No, as every piece of software out there: but we reached a point where the tradeoff between "waiting for more stability" versus "testing led to successful results so we can push forward" that we feel ready to release it. Moreover, we are aware <a href="https://github.com/facebook/react-native/issues/19955" target="_blank" rel="noopener noreferrer">of</a> <a href="https://github.com/facebook/react-native/issues/19827" target="_blank" rel="noopener noreferrer">a</a> <a href="https://github.com/facebook/react-native/issues/19763" target="_blank" rel="noopener noreferrer">few</a> <a href="https://github.com/facebook/react-native/issues/19859" target="_blank" rel="noopener noreferrer">issues</a> that are not solved in the final <code>0.56.0</code> release. Most developers should have no issues upgrading to <code>0.56.0</code>. For those that are blocked by the aforementioned issues, we hope to see you around in our discussions and we are looking forward to working with you on a solution to these issues.</p><p>You might consider <code>0.56.0</code> as a fundamental building block towards a more stable framework: it will take probably a week or two of widespread adoption before all the edge cases will be sanded off, but this will lead to an even better July 2018 (<code>0.57.0</code>) release.</p><p>We'd like to conclude this section by thanking <a href="https://github.com/facebook/react-native/compare/v0.55.4...v0.56.0-rc.4" target="_blank" rel="noopener noreferrer">all the 67 contributors who worked on a total of 818 commits</a> (!) that will help make your apps even better 👏.</p><p>And now, without further ado...</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="the-big-changes">The Big Changes<a class="hash-link" href="#the-big-changes" title="Direct link to heading">​</a></h2><h3 class="anchor anchorWithStickyNavbar_JmGV" id="babel-7">Babel 7<a class="hash-link" href="#babel-7" title="Direct link to heading">​</a></h3><p>As you may know, the transpiler tool that allows us all to use the latest and greatest features of JavaScript, Babel, is moving to <a href="https://babeljs.io/blog/2017/12/27/nearing-the-7.0-release" target="_blank" rel="noopener noreferrer">v7 soon</a>. Since this new version brings along some important changes, we felt that now it would be a good time to upgrade, allowing <a href="https://github.com/facebook/metro" target="_blank" rel="noopener noreferrer">Metro</a> to <a href="https://github.com/facebook/metro/issues/92" target="_blank" rel="noopener noreferrer">leverage on its improvements</a>.</p><p>If you find yourself in trouble with upgrading, please refer to the <a href="https://new.babeljs.io/docs/en/next/v7-migration.html" target="_blank" rel="noopener noreferrer">documentation section related to it</a>.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="modernizing-android-support">Modernizing Android support<a class="hash-link" href="#modernizing-android-support" title="Direct link to heading">​</a></h3><p>On Android, much of the surrounding tooling has changed. We've updated to <a href="https://github.com/facebook/react-native/commit/699e5eebe807d1ced660d2d2f39b5679d26925da" target="_blank" rel="noopener noreferrer">Gradle 3.5</a>, <a href="https://github.com/facebook/react-native/commit/065c5b6590de18281a8c592a04240751c655c03c" target="_blank" rel="noopener noreferrer">Android SDK 26</a>, <a href="https://github.com/facebook/react-native/commit/6b07602915157f54c39adbf0f9746ac056ad2d13" target="_blank" rel="noopener noreferrer">Fresco to 1.9.0, and OkHttp to 3.10.0</a> and even the <a href="https://github.com/facebook/react-native/commit/5ae97990418db613cd67b1fb9070ece976d17dc7" target="_blank" rel="noopener noreferrer">NDK API target to API 16</a>. These changes should go without issue and result in faster builds. More importantly, it will help developers comply with the <a href="https://android-developers.googleblog.com/2017/12/improving-app-security-and-performance.html" target="_blank" rel="noopener noreferrer">new Play Store requirements</a> coming into effect next month.</p><p>Related to this, we'd like to particularly thank <a href="https://github.com/dulmandakh" target="_blank" rel="noopener noreferrer">Dulmandakh</a> for the many PRs submitted in order to make it possible 👏.</p><p>There are some more steps that need to be taken in this direction, and you can follow along with the future planning and discussion of updating the Android support in the <a href="https://github.com/facebook/react-native/issues/19297" target="_blank" rel="noopener noreferrer">dedicated issue</a> (and a side one for the <a href="https://github.com/facebook/react-native/issues/19737" target="_blank" rel="noopener noreferrer">JSC</a>).</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="new-node-xcode-react-and-flow--oh-my">New Node, Xcode, React, and Flow – oh my!<a class="hash-link" href="#new-node-xcode-react-and-flow--oh-my" title="Direct link to heading">​</a></h3><p>Node 8 is now the standard for React Native. It was actually already being tested already, but we've put both feet forward as Node 6 entered maintenance mode. React was also updated to 16.4, which brings a ton of fixes with it.</p><p>We're dropping support for iOS 8, <a href="https://github.com/facebook/react-native/commit/f50df4f5eca4b4324ff18a49dcf8be3694482b51" target="_blank" rel="noopener noreferrer">making iOS 9 the oldest iOS version that can be targeted</a>. We do not foresee this being a problem, as any device that can run iOS 8, can be upgraded to iOS 9. This change allowed us to remove rarely-used code that implemented workarounds for older devices running iOS 8.</p><p>The continuous integration toolchain has been updated <a href="https://github.com/facebook/react-native/commit/c55bcd6ea729cdf57fc14a5478b7c2e3f6b2a94d" target="_blank" rel="noopener noreferrer">to use Xcode 9.4</a>, ensuring that all iOS tests are run on the latest developer tools provided by Apple.</p><p>We have upgraded to <a href="https://github.com/facebook/react-native/commit/6264b6932a08e1cefd83c4536ff7839d91938730" target="_blank" rel="noopener noreferrer">Flow 0.75</a> to use the new error format <a href="https://twitter.com/dan_abramov/status/998610821096857602" target="_blank" rel="noopener noreferrer">that many devs appreciate</a>. We've also created types for many more components. If you're not yet enforcing static typing in your project, please consider using Flow to identify problems as you code instead of at runtime.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="and-a-lot-of-other-things">And a lot of other things...<a class="hash-link" href="#and-a-lot-of-other-things" title="Direct link to heading">​</a></h3><p>For instance, YellowBox was <a href="https://github.com/facebook/react-native/commit/d0219a0301e59e8b0ef75dbd786318d4b4619f4c" target="_blank" rel="noopener noreferrer">replaced</a> with a new implementation that makes debugging a lot better.</p><p>For the complete release notes, please reference the full <a href="https://github.com/react-native-community/react-native-releases/blob/master/CHANGELOG.md" target="_blank" rel="noopener noreferrer">changelog here</a>. And remember to keep an eye on the <a href="/docs/upgrading">upgrading guide</a> to avoid issues moving to this new version.</p><hr><p>A final note: starting this week, the React Native core team will resume holding monthly meetings. We'll make sure to keep everyone up-to-date with what's covered, and ensure to keep your feedback at hand for future meetings.</p><p>Happy coding everyone!</p><p><a href="https://twitter.com/Kelset" target="_blank" rel="noopener noreferrer">Lorenzo</a>, <a href="https://github.com/turnrye" target="_blank" rel="noopener noreferrer">Ryan</a>, and the whole <a href="https://twitter.com/reactnative" target="_blank" rel="noopener noreferrer">React Native core team</a></p><p><strong>PS:</strong> as always, we'd like to remind everyone that React Native is still in 0.x versioning because of the many changes still undergoing - so remember when upgrading that yes, probably, something may still crash or be broken. Be helpful towards each other in the issues and when submitting PRs - and remember to follow the <a href="https://code.fb.com/codeofconduct/" target="_blank" rel="noopener noreferrer">CoC</a> enforced: there's always a human on the other side of the screen.</p>]]></content>
        <author>
            <name>Lorenzo Sciandra</name>
            <uri>https://github.com/kelset</uri>
        </author>
        <category label="announcement" term="announcement"/>
        <category label="release" term="release"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[State of React Native 2018]]></title>
        <id>/2018/06/14/state-of-react-native-2018</id>
        <link href="https://reactnative.dev/blog/2018/06/14/state-of-react-native-2018"/>
        <updated>2018-06-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[It's been a while since we last published a status update about React Native.]]></summary>
        <content type="html"><![CDATA[<p>It's been a while since we last published a status update about React Native.</p><p>At Facebook, we're using React Native more than ever and for many important projects. One of our most popular products is Marketplace, one of the top-level tabs in our app which is used by 800 million people each month. Since its creation in 2015, all of Marketplace has been built with React Native, including over a hundred full-screen views throughout different parts of the app.</p><p>We're also using React Native for many new parts of the app. If you watched the F8 keynote last month, you'll recognize Blood Donations, Crisis Response, Privacy Shortcuts, and Wellness Checks – all recent features built with React Native. And projects outside the main Facebook app are using React Native too. The new Oculus Go VR headset includes <a href="https://www.oculus.com/app/" target="_blank" rel="noopener noreferrer">a companion mobile app</a> that is fully built with React Native, not to mention React VR powering many experiences in the headset itself.</p><p>Naturally, we also use many other technologies to build our apps. <a href="https://fblitho.com/" target="_blank" rel="noopener noreferrer">Litho</a> and <a href="https://componentkit.org/" target="_blank" rel="noopener noreferrer">ComponentKit</a> are two libraries we use extensively in our apps; both provide a React-like component API for building native screens. It's never been a goal for React Native to replace all other technologies – we are focused on making React Native itself better, but we love seeing other teams borrow ideas from React Native, like bringing <a href="https://instagram-engineering.com/instant-feedback-in-ios-engineering-workflows-c3f6508c76c8" target="_blank" rel="noopener noreferrer">instant reload</a> to non-JavaScript code too.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="architecture">Architecture<a class="hash-link" href="#architecture" title="Direct link to heading">​</a></h2><p>When we started the React Native project in 2013, we designed it to have a single “bridge” between JavaScript and native that is asynchronous, serializable, and batched. Just as React DOM turns React state updates into imperative, mutative calls to DOM APIs like <code>document.createElement(attrs)</code> and <code>.appendChild()</code>, React Native was designed to return a single JSON message that lists mutations to perform, like <code>[["createView", attrs], ["manageChildren", ...]]</code>. We designed the entire system to never rely on getting a synchronous response back and to ensure everything in that list could be fully serialized to JSON and back. We did this for the flexibility it gave us: on top of this architecture, we were able to build tools like <a href="/docs/debugging#chrome-developer-tools">Chrome debugging</a>, which runs all the JavaScript code asynchronously over a WebSocket connection.</p><p>Over the last 5 years, we found that these initial principles have made building some features harder. An asynchronous bridge means you can't integrate JavaScript logic directly with many native APIs expecting synchronous answers. A batched bridge that queues native calls means it's harder to have React Native apps call into functions that are implemented natively. And a serializable bridge means unnecessary copying instead of directly sharing memory between the two worlds. For apps that are entirely built in React Native, these restrictions are usually bearable. But for apps with complex integration between React Native and existing app code, they are frustrating.</p><p><strong>We're working on a large-scale rearchitecture of React Native to make the framework more flexible and integrate better with native infrastructure in hybrid JavaScript/native apps.</strong> With this project, we'll apply what we've learned over the last 5 years and incrementally bring our architecture to a more modern one. We're rewriting many of React Native's internals, but most of the changes are under the hood: existing React Native apps will continue to work with few or no changes.</p><p>To make React Native more lightweight and fit better into existing native apps, this rearchitecture has three major internal changes. First, we are changing the threading model. Instead of each UI update needing to perform work on three different threads, it will be possible to call synchronously into JavaScript on any thread for high-priority updates while still keeping low-priority work off the main thread to maintain responsiveness. Second, we are incorporating <a href="https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html" target="_blank" rel="noopener noreferrer">async rendering</a> capabilities into React Native to allow multiple rendering priorities and to simplify asynchronous data handling. Finally, we are simplifying our bridge to make it faster and more lightweight; direct calls between native and JavaScript are more efficient and will make it easier to build debugging tools like cross-language stack traces.</p><p>Once these changes are completed, closer integrations will be possible. Today, it's not possible to incorporate native navigation and gesture handling or native components like UICollectionView and RecyclerView without complex hacks. After our changes to the threading model, building features like this will be straightforward.</p><p>We'll release more details about this work later this year as it approaches completion.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="community">Community<a class="hash-link" href="#community" title="Direct link to heading">​</a></h2><p>Alongside the community inside Facebook, we're happy to have a thriving population of React Native users and collaborators outside Facebook. We'd like to support the React Native community more, both by serving React Native users better and by making the project easier to contribute to.</p><p>Just as our architecture changes will help React Native interoperate more cleanly with other native infrastructure, React Native should be slimmer on the JavaScript side to fit better with the JavaScript ecosystem, which includes making the VM and bundler swappable. We know the pace of breaking changes can be hard to keep up with, so we'd like to find ways to have fewer major releases. Finally, we know that some teams are looking for more thorough documentation in topics like startup optimization, where our expertise hasn't yet been written down. Expect to see some of these changes over the coming year.</p><p>If you're using React Native, you're part of our community; keep letting us know how we can make React Native better for you.</p><p>React Native is just one tool in a mobile developer's toolbox, but it's one that we strongly believe in – and we're making it better every day, with over 2500 commits in the last year from 500+ contributors.</p>]]></content>
        <author>
            <name>Sophie Alpert</name>
            <uri>https://github.com/sophiebits</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Using TypeScript with React Native]]></title>
        <id>/2018/05/07/using-typescript-with-react-native</id>
        <link href="https://reactnative.dev/blog/2018/05/07/using-typescript-with-react-native"/>
        <updated>2018-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[JavaScript! We all love it. But some of us also love types. Luckily, options exist to add stronger types to JavaScript. My favourite is TypeScript, but React Native supports Flow out of the box. Which you prefer is a matter of preference, they each have their own approach on how to add the magic of types to JavaScript. Today, we're going to look at how to use TypeScript in React Native apps.]]></summary>
        <content type="html"><![CDATA[<p>JavaScript! We all love it. But some of us also love <a href="https://en.wikipedia.org/wiki/Data_type" target="_blank" rel="noopener noreferrer">types</a>. Luckily, options exist to add stronger types to JavaScript. My favourite is <a href="https://www.typescriptlang.org" target="_blank" rel="noopener noreferrer">TypeScript</a>, but React Native supports <a href="https://flow.org" target="_blank" rel="noopener noreferrer">Flow</a> out of the box. Which you prefer is a matter of preference, they each have their own approach on how to add the magic of types to JavaScript. Today, we're going to look at how to use TypeScript in React Native apps.</p><p>This post uses Microsoft's <a href="https://github.com/Microsoft/TypeScript-React-Native-Starter" target="_blank" rel="noopener noreferrer">TypeScript-React-Native-Starter</a> repo as a guide.</p><p><strong>Update</strong>: Since this blog post was written, things have gotten even easier. You can replace all the set up described in this blog post by running just one command:</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">npx react-native init MyAwesomeProject --template react-native-template-typescript</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>However, there <em>are</em> some limitations to Babel's TypeScript support, which the blog post above goes into in detail. The steps outlined in <em>this</em> post still work, and Artsy is still using <a href="https://github.com/ds300/react-native-typescript-transformer" target="_blank" rel="noopener noreferrer">react-native-typescript-transformer</a> in production, but the fastest way to get up and running with React Native and TypeScript is using the above command. You can always switch later if you have to.</p><p>In any case, have fun! The original blog post continues below.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="prerequisites">Prerequisites<a class="hash-link" href="#prerequisites" title="Direct link to heading">​</a></h2><p>Because you might be developing on one of several different platforms, targeting several different types of devices, basic setup can be involved. You should first ensure that you can run a plain React Native app without TypeScript. Follow <a href="/docs/getting-started">the instructions on the React Native website to get started</a>. When you've managed to deploy to a device or emulator, you'll be ready to start a TypeScript React Native app.</p><p>You will also need <a href="https://nodejs.org/en/" target="_blank" rel="noopener noreferrer">Node.js</a>, <a href="https://www.npmjs.com" target="_blank" rel="noopener noreferrer">npm</a>, and <a href="https://yarnpkg.com/lang/en" target="_blank" rel="noopener noreferrer">Yarn</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="initializing">Initializing<a class="hash-link" href="#initializing" title="Direct link to heading">​</a></h2><p>Once you've tried scaffolding out an ordinary React Native project, you'll be ready to start adding TypeScript. Let's go ahead and do that.</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">react-native init MyAwesomeProject</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">cd MyAwesomeProject</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="adding-typescript">Adding TypeScript<a class="hash-link" href="#adding-typescript" title="Direct link to heading">​</a></h2><p>The next step is to add TypeScript to your project. The following commands will:</p><ul><li>add TypeScript to your project</li><li>add <a href="https://github.com/ds300/react-native-typescript-transformer" target="_blank" rel="noopener noreferrer">React Native TypeScript Transformer</a> to your project</li><li>initialize an empty TypeScript config file, which we'll configure next</li><li>add an empty React Native TypeScript Transformer config file, which we'll configure next</li><li>adds <a href="https://github.com/DefinitelyTyped/DefinitelyTyped" target="_blank" rel="noopener noreferrer">typings</a> for React and React Native</li></ul><p>Okay, let's go ahead and run these.</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">yarn add --dev typescript</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">yarn add --dev react-native-typescript-transformer</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">yarn tsc --init --pretty --jsx react</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">touch rn-cli.config.js</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">yarn add --dev @types/react @types/react-native</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The <code>tsconfig.json</code> file contains all the settings for the TypeScript compiler. The defaults created by the command above are mostly fine, but open the file and uncomment the following line:</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token comment" style="color:#93a1a1">/* Search the config file for the following line and uncomment it. */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token comment" style="color:#93a1a1">// "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The <code>rn-cli.config.js</code> contains the settings for the React Native TypeScript Transformer. Open it and add the following:</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">getTransformModulePath</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> require</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">resolve</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'react-native-typescript-transformer'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">getSourceExts</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token string" style="color:#8dc891">'ts'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'tsx'</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="migrating-to-typescript">Migrating to TypeScript<a class="hash-link" href="#migrating-to-typescript" title="Direct link to heading">​</a></h2><p>Rename the generated <code>App.js</code> and <code>__tests_/App.js</code> files to <code>App.tsx</code>. <code>index.js</code> needs to use the <code>.js</code> extension. All new files should use the <code>.tsx</code> extension (or <code>.ts</code> if the file doesn't contain any JSX).</p><p>If you tried to run the app now, you'd get an error like <code>object prototype may only be an object or null</code>. This is caused by a failure to import the default export from React as well as a named export on the same line. Open <code>App.tsx</code> and modify the import at the top of the file:</p><div class="language-diff codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-diff codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token deleted-sign deleted prefix deleted" style="color:#cb4b16">-</span><span class="token deleted-sign deleted line" style="color:#cb4b16">import React, { Component } from 'react';</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token deleted-sign deleted line" style="color:#cb4b16"></span><span class="token inserted-sign inserted prefix inserted" style="color:#859900">+</span><span class="token inserted-sign inserted line" style="color:#859900">import React from 'react'</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token inserted-sign inserted line" style="color:#859900"></span><span class="token inserted-sign inserted prefix inserted" style="color:#859900">+</span><span class="token inserted-sign inserted line" style="color:#859900">import { Component } from 'react';</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Some of this has to do with differences in how Babel and TypeScript interoperate with CommonJS modules. In the future, the two will stabilize on the same behaviour.</p><p>At this point, you should be able to run the React Native app.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="adding-typescript-testing-infrastructure">Adding TypeScript Testing Infrastructure<a class="hash-link" href="#adding-typescript-testing-infrastructure" title="Direct link to heading">​</a></h2><p>React Native ships with <a href="https://github.com/facebook/jest" target="_blank" rel="noopener noreferrer">Jest</a>, so for testing a React Native app with TypeScript, we'll want to add <a href="https://www.npmjs.com/package/ts-jest" target="_blank" rel="noopener noreferrer">ts-jest</a> to our <code>devDependencies</code>.</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">yarn add --dev ts-jest</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Then, we'll open up our <code>package.json</code> and replace the <code>jest</code> field with the following:</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token string-property property" style="color:#2aa198">"jest"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string-property property" style="color:#2aa198">"preset"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"react-native"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string-property property" style="color:#2aa198">"moduleFileExtensions"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string" style="color:#8dc891">"ts"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string" style="color:#8dc891">"tsx"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string" style="color:#8dc891">"js"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string-property property" style="color:#2aa198">"transform"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string-property property" style="color:#2aa198">"^.+\\.(js)$"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"&lt;rootDir&gt;/node_modules/babel-jest"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string-property property" style="color:#2aa198">"\\.(ts|tsx)$"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"&lt;rootDir&gt;/node_modules/ts-jest/preprocessor.js"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string-property property" style="color:#2aa198">"testRegex"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string-property property" style="color:#2aa198">"testPathIgnorePatterns"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string" style="color:#8dc891">"\\.snap$"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string" style="color:#8dc891">"&lt;rootDir&gt;/node_modules/"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string-property property" style="color:#2aa198">"cacheDirectory"</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">".jest/cache"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This will configure Jest to run <code>.ts</code> and <code>.tsx</code> files with <code>ts-jest</code>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="installing-dependency-type-declarations">Installing Dependency Type Declarations<a class="hash-link" href="#installing-dependency-type-declarations" title="Direct link to heading">​</a></h2><p>To get the best experience in TypeScript, we want the type-checker to understand the shape and API of our dependencies. Some libraries will publish their packages with <code>.d.ts</code> files (type declaration/type definition files), which can describe the shape of the underlying JavaScript. For other libraries, we'll need to explicitly install the appropriate package in the <code>@types/</code> npm scope.</p><p>For example, here we'll need types for Jest, React, and React Native, and React Test Renderer.</p><div class="language-ts codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-ts codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">yarn add </span><span class="token operator" style="color:#fc929e">--</span><span class="token plain">dev </span><span class="token decorator at operator" style="color:#fc929e">@</span><span class="token decorator function" style="color:#79b6f2">types</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">jest </span><span class="token decorator at operator" style="color:#fc929e">@</span><span class="token decorator function" style="color:#79b6f2">types</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">react </span><span class="token decorator at operator" style="color:#fc929e">@</span><span class="token decorator function" style="color:#79b6f2">types</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">react</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">native </span><span class="token decorator at operator" style="color:#fc929e">@</span><span class="token decorator function" style="color:#79b6f2">types</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">react</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">test</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">renderer</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We saved these declaration file packages to our <em>dev</em> dependencies because this is a React Native <em>app</em> that only uses these dependencies during development and not during runtime. If we were publishing a library to NPM, we might have to add some of these type dependencies as regular dependencies.</p><p>You can read more <a href="https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html" target="_blank" rel="noopener noreferrer">here about getting <code>.d.ts</code> files</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="ignoring-more-files">Ignoring More Files<a class="hash-link" href="#ignoring-more-files" title="Direct link to heading">​</a></h2><p>For your source control, you'll want to start ignoring the <code>.jest</code> folder. If you're using git, we can just add entries to our <code>.gitignore</code> file.</p><div class="language-config codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-config codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain"># Jest</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">#</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">.jest/</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>As a checkpoint, consider committing your files into version control.</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">git init</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">git add .gitignore # import to do this first, to ignore our files</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">git add .</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">git commit -am "Initial commit."</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="adding-a-component">Adding a Component<a class="hash-link" href="#adding-a-component" title="Direct link to heading">​</a></h2><p>Let's add a component to our app. Let's go ahead and create a <code>Hello.tsx</code> component. It's a pedagogical component, not something that you'd actually write in an app, but something nontrivial that shows off how to use TypeScript in React Native.</p><p>Create a <code>components</code> directory and add the following example.</p><div class="language-ts codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-ts codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// components/Hello.tsx</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> React </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">Button</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> StyleSheet</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> Text</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> View</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">Props</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  name</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token builtin" style="color:#2aa198">string</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  enthusiasmLevel</span><span class="token operator" style="color:#fc929e">?</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token builtin" style="color:#2aa198">number</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">interface</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">State</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  enthusiasmLevel</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token builtin" style="color:#2aa198">number</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">class</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">Hello</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">extends</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">React</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">Component</span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">Props</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> State</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">constructor</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">props</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> Props</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">super</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">props</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">enthusiasmLevel </span><span class="token operator" style="color:#fc929e">||</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">&lt;=</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token keyword" style="color:#c5a5c5">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">Error</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token string" style="color:#8dc891">'You could be a little more enthusiastic. :D'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">state </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      enthusiasmLevel</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">enthusiasmLevel </span><span class="token operator" style="color:#fc929e">||</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function-variable function" style="color:#79b6f2">onIncrement</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">setState</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      enthusiasmLevel</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">enthusiasmLevel </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function-variable function" style="color:#79b6f2">onDecrement</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">setState</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      enthusiasmLevel</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">enthusiasmLevel </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function-variable function" style="color:#79b6f2">getExclamationMarks</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">numChars</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token builtin" style="color:#2aa198">number</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token function" style="color:#79b6f2">Array</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">numChars </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">join</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'!'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">render</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">View style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">root</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">Text style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">greeting</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          Hello</span><span class="token punctuation" style="color:#657b83">{</span><span class="token string" style="color:#8dc891">' '</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          </span><span class="token punctuation" style="color:#657b83">{</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">name </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">getExclamationMarks</span><span class="token punctuation" style="color:#657b83">(</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">enthusiasmLevel</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">Text</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">View style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">buttons</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">View style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">button</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">Button</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              title</span><span class="token operator" style="color:#fc929e">=</span><span class="token string" style="color:#8dc891">"-"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              onPress</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">onDecrement</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              accessibilityLabel</span><span class="token operator" style="color:#fc929e">=</span><span class="token string" style="color:#8dc891">"decrement"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              color</span><span class="token operator" style="color:#fc929e">=</span><span class="token string" style="color:#8dc891">"red"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            </span><span class="token operator" style="color:#fc929e">/</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">View</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">View style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">button</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">Button</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              title</span><span class="token operator" style="color:#fc929e">=</span><span class="token string" style="color:#8dc891">"+"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              onPress</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">onIncrement</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              accessibilityLabel</span><span class="token operator" style="color:#fc929e">=</span><span class="token string" style="color:#8dc891">"increment"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">              color</span><span class="token operator" style="color:#fc929e">=</span><span class="token string" style="color:#8dc891">"blue"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            </span><span class="token operator" style="color:#fc929e">/</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">View</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">View</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">View</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// styles</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> styles </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> StyleSheet</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">create</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  root</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    alignItems</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'center'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    alignSelf</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'center'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  buttons</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    flexDirection</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'row'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    minHeight</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">70</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    alignItems</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'stretch'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    alignSelf</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'center'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    borderWidth</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">5</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  button</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    flex</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    paddingVertical</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  greeting</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    color</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'#999'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    fontWeight</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'bold'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Whoa! That's a lot, but let's break it down:</p><ul><li>Instead of rendering HTML elements like <code>div</code>, <code>span</code>, <code>h1</code>, etc., we're rendering components like <code>View</code> and <code>Button</code>. These are native components that work across different platforms.</li><li>Styling is specified using the <code>StyleSheet.create</code> function that React Native gives us. React's stylesheets allow us to control our layout using Flexbox, and style using other constructs similar to those in CSS.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="adding-a-component-test">Adding a Component Test<a class="hash-link" href="#adding-a-component-test" title="Direct link to heading">​</a></h2><p>Now that we've got a component, let's try testing it.</p><p>We already have Jest installed as a test runner. We're going to write snapshot tests for our components, let's add the required add-on for snapshot tests:</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">yarn add --dev react-addons-test-utils</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Now let's create a <code>__tests__</code> folder in the <code>components</code> directory and add a test for <code>Hello.tsx</code>:</p><div class="language-ts codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-ts codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// components/__tests__/Hello.tsx</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> React </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> renderer </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-test-renderer'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">Hello</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'../Hello'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token function" style="color:#79b6f2">it</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'renders correctly with defaults'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> button </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> renderer</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">create</span><span class="token punctuation" style="color:#657b83">(</span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain">Hello name</span><span class="token operator" style="color:#fc929e">=</span><span class="token string" style="color:#8dc891">"World"</span><span class="token plain"> enthusiasmLevel</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">/</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">toJSON</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">expect</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">button</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">toMatchSnapshot</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The first time the test is run, it will create a snapshot of the rendered component and store it in the <code>components/__tests__/__snapshots__/Hello.tsx.snap</code> file. When you modify your component, you'll need to update the snapshots and review the update for inadvertent changes. You can read more about testing React Native components <a href="https://facebook.github.io/jest/docs/en/tutorial-react-native.html" target="_blank" rel="noopener noreferrer">here</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-steps">Next Steps<a class="hash-link" href="#next-steps" title="Direct link to heading">​</a></h2><p>Check out the official <a href="https://reactjs.org/tutorial/tutorial.html" target="_blank" rel="noopener noreferrer">React tutorial</a> and state-management library <a href="http://redux.js.org" target="_blank" rel="noopener noreferrer">Redux</a>. These resources can be helpful when writing React Native apps. Additionally, you may want to look at <a href="https://microsoft.github.io/reactxp/" target="_blank" rel="noopener noreferrer">ReactXP</a>, a component library written entirely in TypeScript that supports both React on the web as well as React Native.</p><p>Have fun in a more type-safe React Native development environment!</p>]]></content>
        <author>
            <name>Ash Furrow</name>
            <uri>https://github.com/ashfurrow</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Built with React Native - The Build.com app]]></title>
        <id>/2018/04/09/build-com-app</id>
        <link href="https://reactnative.dev/blog/2018/04/09/build-com-app"/>
        <updated>2018-04-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Build.com, headquartered in Chico, California, is one of the largest online retailers for home improvement items. The team has had a strong web-centric business for 18 years and began thinking about a mobile App in 2015. Building unique Android and iOS apps wasn’t practical due to our small team and limited native experience. Instead, we decided to take a risk on the very new React Native framework. Our initial commit was on August 12, 2015 using React Native v0.8.0! We were live in both App Stores on October 15, 2016. Over the last two years, we’ve continued to upgrade and expand the app. We are currently on React Native version 0.53.0.]]></summary>
        <content type="html"><![CDATA[<p><a href="https://www.build.com/" target="_blank" rel="noopener noreferrer">Build.com</a>, headquartered in Chico, California, is one of the largest online retailers for home improvement items. The team has had a strong web-centric business for 18 years and began thinking about a mobile App in 2015. Building unique Android and iOS apps wasn’t practical due to our small team and limited native experience. Instead, we decided to take a risk on the very new React Native framework. Our initial commit was on August 12, 2015 using React Native v0.8.0! We were live in both App Stores on October 15, 2016. Over the last two years, we’ve continued to upgrade and expand the app. We are currently on React Native version 0.53.0.</p><p>You can check out the app at <a href="https://www.build.com/app" target="_blank" rel="noopener noreferrer">https://www.build.com/app</a>.</p><p align="center"><img loading="lazy" src="/blog/assets/build-com-blog-image.jpg" class="img_SS3x"></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="features">Features<a class="hash-link" href="#features" title="Direct link to heading">​</a></h2><p>Our app is full featured and includes everything that you’d expect from an e-commerce app: product listings, search and sorting, the ability to configure complex products, favorites, etc. We accept standard credit card payment methods as well as PayPal, and Apple Pay for our iOS users.</p><p>A few standout features you might not expect include:</p><ol><li>3D models available for around 40 products with 90 finishes</li><li>Augmented Reality (AR) to allow the user to see how lights and faucets will look in their home at 98% size accuracy. The Build.com React Native App is featured in the Apple App Store for AR Shopping! AR is now available for Android and iOS!</li><li>Collaborative project management features that allow people to put together shopping lists for the different phases of their project and collaborate around selection</li></ol><p>We’re working on many new and exciting features that will continue to improve our app experience including the next phase of Immersive Shopping with AR.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="our-development-workflow">Our Development Workflow<a class="hash-link" href="#our-development-workflow" title="Direct link to heading">​</a></h2><p>Build.com allows each dev to choose the tools that best suit them.</p><ul><li>IDEs include Atom, IntelliJ, VS Code, Sublime, Eclipse, etc.</li><li>For Unit testing, developers are responsible for creating Jest unit tests for any new components and we’re working to increase the coverage of older parts of the app using <code>jest-coverage-ratchet</code>.</li><li>We use Jenkins to build out our beta and release candidates. This process works well for us but still requires significant work to create the release notes and other artifacts.</li><li>Integration Testing include a shared pool of testers that work across desktop, mobile and web. Our automation engineer is building out our suite of automated integration tests using Java and Appium.</li><li>Other parts of the workflow include a detailed eslint configuration, custom rules that enforce properties needed for testing, and pre-push hooks that block offending changes.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="libraries-used-in-the-app">Libraries Used in the App<a class="hash-link" href="#libraries-used-in-the-app" title="Direct link to heading">​</a></h2><p>The Build.com app relies on a number of common open source libraries including: Redux, Moment, Numeral, Enzyme and a bunch of React Native bridge modules. We also use a number of forked open source libraries; forked either because they were abandoned or because we needed custom features. A quick count shows around 115 JavaScript and native dependencies. We would like to explore tools that remove unused libraries.</p><p>We're in the process of adding static typing via TypeScript and looking into optional chaining. These features could help us with solving a couple classes of bugs that we still see:</p><ul><li>Data that is the wrong type</li><li>Data that is undefined because an object didn’t contain what we expected</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="open-source-contributions">Open Source Contributions<a class="hash-link" href="#open-source-contributions" title="Direct link to heading">​</a></h2><p>Since we rely so heavily on open source, our team is committed to contributing back to the community. Build.com allows the team to open source libraries that we've built and encourages us contribute back to the libraries that we use.</p><p>We’ve released and maintained a number of React Native libraries:</p><ul><li><code>react-native-polyfill</code></li><li><code>react-native-simple-store</code></li><li><code>react-native-contact-picker</code></li></ul><p>We have also contributed to a long list of libraries including: React and React Native, <code>react-native-schemes-manager</code>, <code>react-native-swipeable</code>, <code>react-native-gallery</code>, <code>react-native-view-transformer</code>, <code>react-native-navigation</code>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="our-journey">Our Journey<a class="hash-link" href="#our-journey" title="Direct link to heading">​</a></h2><p>We’ve seen a lot of growth in React Native and the ecosystem in the past couple years. Early on, it seemed that every version of React Native would fix some bugs but introduce several more. For example, Remote JS Debugging was broken on Android for several months. Thankfully, things became much more stable in 2017.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="navigation-libraries">Navigation Libraries<a class="hash-link" href="#navigation-libraries" title="Direct link to heading">​</a></h3><p>One of our big recurring challenges has been with navigation libraries. For a long time, we were using Expo’s ex-nav library. It worked well for us but it was eventually deprecated. However, we were in heavy feature development at the time so taking time to change out a navigation library wasn’t feasible. That meant we had to fork the library and patch it to support React 16 and the iPhone X. Eventually, we were able to migrate to <a href="https://github.com/wix/react-native-navigation" target="_blank" rel="noopener noreferrer"><code>react-native-navigation</code></a> and hopefully that will see continued support.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="bridge-modules">Bridge Modules<a class="hash-link" href="#bridge-modules" title="Direct link to heading">​</a></h3><p>Another big challenge has been with bridge modules. When we first started, a lot of critical bridges were missing. One of my teammates wrote <code>react-native-contact-picker</code> because we needed access to the Android contact picker in our app. We’ve also seen a lot of bridges that were broken by changes within React Native. For example, there was a breaking change within React Native v40 and when we upgraded our app, I had to submit PRs to fix 3 or 4 libraries that had not yet been updated.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="looking-forward">Looking Forward<a class="hash-link" href="#looking-forward" title="Direct link to heading">​</a></h2><p>As React Native continues to grow, our wishlist to our community include:</p><ul><li>Stabilize and improve the navigation libraries</li><li>Maintain support for libraries in the React Native ecosystem</li><li>Improve the experience for adding native libraries and bridge modules to a project</li></ul><p>Companies and individuals in the React Native community have been great about volunteering their time and effort to improve the tools that we all use. If you haven’t gotten involved in open source, I hope you’ll take a look at improving the code or documentation for some of the libraries that you use. There are a lot of articles to help you get started and it may be a lot easier than you think!</p>]]></content>
        <author>
            <name>Garrett McCullough</name>
            <uri>https://twitter.com/gwmccull</uri>
        </author>
        <category label="showcase" term="showcase"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Building <InputAccessoryView> For React Native]]></title>
        <id>/2018/03/22/building-input-accessory-view-for-react-native</id>
        <link href="https://reactnative.dev/blog/2018/03/22/building-input-accessory-view-for-react-native"/>
        <updated>2018-03-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Motivation]]></summary>
        <content type="html"><![CDATA[<h2 class="anchor anchorWithStickyNavbar_JmGV" id="motivation">Motivation<a class="hash-link" href="#motivation" title="Direct link to heading">​</a></h2><p>Three years ago, a GitHub issue was opened to support input accessory view from React Native.</p><img loading="lazy" src="/blog/assets/input-accessory-1.png" class="img_SS3x"><p>In the ensuing years, there have been countless '+1s', various workarounds, and zero concrete changes to RN on this issue - until today. Starting with iOS, <a href="/docs/inputaccessoryview">we're exposing an API</a> for accessing the native input accessory view and we are excited to share how we built it.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="background">Background<a class="hash-link" href="#background" title="Direct link to heading">​</a></h2><p>What exactly is an input accessory view? Reading <a href="https://developer.apple.com/documentation/uikit/uiresponder/1621119-inputaccessoryview?language=objc" target="_blank" rel="noopener noreferrer">Apple's developer documentation</a>, we learn that it's a custom view which can be anchored to the top of the system keyboard whenever a receiver becomes the first responder. Anything that inherits from <code>UIResponder</code> can redeclare the <code>.inputAccessoryView</code> property as read-write, and manage a custom view here. The responder infrastructure mounts the view, and keeps it in sync with the system keyboard. Gestures which dismiss the keyboard, like a drag or tap, are applied to the input accessory view at the framework level. This allows us to build content with interactive keyboard dismissal, an integral feature in top-tier messaging apps like iMessage and WhatsApp.</p><p>There are two common use cases for anchoring a view to the top of the keyboard. The first is creating a keyboard toolbar, like the Facebook composer background picker.</p><img loading="lazy" src="/blog/assets/input-accessory-2.gif" style="float:left;padding-right:70px;padding-top:20px" class="img_SS3x"><p>In this scenario, the keyboard is focused on a text input field, and the input accessory view is used to provide additional keyboard functionality. This functionality is contextual to the type of input field. In a mapping application it could be address suggestions, or in a text editor, it could be rich text formatting tools.</p><hr style="clear:both;margin-bottom:20px"><p>The Objective-C UIResponder who owns the <code>&lt;InputAccessoryView&gt;</code> in this scenario should be clear. The <code>&lt;TextInput&gt;</code> has become first responder, and under the hood this becomes an instance of <code>UITextView</code> or <code>UITextField</code>.</p><p>The second common scenario is sticky text inputs:</p><img loading="lazy" src="/blog/assets/input-accessory-3.gif" style="float:left;padding-right:70px;padding-top:20px" class="img_SS3x"><p>Here, the text input is actually part of the input accessory view itself. This is commonly used in messaging applications, where a message can be composed while scrolling through a thread of previous messages.</p><hr style="clear:both;margin-bottom:20px"><p>Who owns the <code>&lt;InputAccessoryView&gt;</code> in this example? Can it be the <code>UITextView</code> or <code>UITextField</code> again? The text input is <em>inside</em> the input accessory view, this sounds like a circular dependency. Solving this issue alone is <a href="http://derpturkey.com/uitextfield-docked-like-ios-messenger/" target="_blank" rel="noopener noreferrer">another blog post</a> in itself. Spoilers: the owner is a generic <code>UIView</code> subclass who we manually tell to <a href="https://developer.apple.com/documentation/uikit/uiresponder/1621113-becomefirstresponder?language=objc" target="_blank" rel="noopener noreferrer">becomeFirstResponder</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="api-design">API Design<a class="hash-link" href="#api-design" title="Direct link to heading">​</a></h2><p>We now know what an <code>&lt;InputAccessoryView&gt;</code> is, and how we want to use it. The next step is designing an API that makes sense for both use cases, and works well with existing React Native components like <code>&lt;TextInput&gt;</code>.</p><p>For keyboard toolbars, there are a few things we want to consider:</p><ol><li>We want to be able to hoist any generic React Native view hierarchy into the <code>&lt;InputAccessoryView&gt;</code>.</li><li>We want this generic and detached view hierarchy to accept touches and be able to manipulate application state.</li><li>We want to link an <code>&lt;InputAccessoryView&gt;</code> to a particular <code>&lt;TextInput&gt;</code>.</li><li>We want to be able to share an <code>&lt;InputAccessoryView&gt;</code> across multiple text inputs, without duplicating any code.</li></ol><p>We can achieve #1 using a concept similar to <a href="https://reactjs.org/docs/portals.html" target="_blank" rel="noopener noreferrer">React portals</a>. In this design, we portal React Native views to a <code>UIView</code> hierarchy managed by the responder infrastructure. Since React Native views render as UIViews, this is actually quite straightforward - we can just override:</p><p><code>- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex</code></p><p>and pipe all the subviews to a new UIView hierarchy. For #2, we set up a new <a href="https://github.com/facebook/react-native/blob/master/React/Base/RCTTouchHandler.h" target="_blank" rel="noopener noreferrer">RCTTouchHandler</a> for the <code>&lt;InputAccessoryView&gt;</code>. State updates are achieved by using regular event callbacks. For #3 and #4, we use the <a href="https://github.com/facebook/react-native/blob/master/React/Views/UIView%2BReact.h#L28" target="_blank" rel="noopener noreferrer">nativeID</a> field to locate the accessory view UIView hierarchy in native code during the creation of a <code>&lt;TextInput&gt;</code> component. This function uses the <code>.inputAccessoryView</code> property of the underlying native text input. Doing this effectively links <code>&lt;InputAccessoryView&gt;</code> to <code>&lt;TextInput&gt;</code> in their ObjC implementations.</p><p>Supporting sticky text inputs (scenario 2) adds a few more constraints. For this design, the input accessory view has a text input as a child, so linking via nativeID is not an option. Instead, we set the <code>.inputAccessoryView</code> of a generic off-screen <code>UIView</code> to our native <code>&lt;InputAccessoryView&gt;</code> hierarchy. By manually telling this generic <code>UIView</code> to become first responder, the hierarchy is mounted by responder infrastructure. This concept is explained thoroughly in the aforementioned blog post.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="pitfalls">Pitfalls<a class="hash-link" href="#pitfalls" title="Direct link to heading">​</a></h2><p>Of course not everything was smooth sailing while building this API. Here are a few pitfalls we encountered, along with how we fixed them.</p><p>An initial idea for building this API involved listening to <code>NSNotificationCenter</code> for UIKeyboardWill(Show/Hide/ChangeFrame) events. This pattern is used in some open-sourced libraries, and internally in some parts of the Facebook app. Unfortunately, <code>UIKeyboardDidChangeFrame</code> events were not being called in time to update the <code>&lt;InputAccessoryView&gt;</code> frame on swipes. Also, changes in keyboard height are not captured by these events. This creates a class of bugs that manifest like this:</p><img loading="lazy" src="/blog/assets/input-accessory-4.gif" style="float:left;padding-right:70px;padding-top:20px" class="img_SS3x"><p>On iPhone X, text and emoji keyboard are different heights. Most applications using keyboard events to manipulate text input frames had to fix the above bug. Our solution was to commit to using the <code>.inputAccessoryView</code> property, which meant that the responder infrastructure handles frame updates like this.</p><hr style="clear:both;margin-bottom:20px"><p>Another tricky bug we encountered was avoiding the home pill on iPhone X. You may be thinking, “Apple developed <a href="https://developer.apple.com/documentation/uikit/uiview/2891102-safearealayoutguide?language=objc" target="_blank" rel="noopener noreferrer">safeAreaLayoutGuide</a> for this very reason, this is trivial!”. We were just as naive. The first issue is that the native <code>&lt;InputAccessoryView&gt;</code> implementation has no window to anchor to until the moment it is about to appear. That's alright, we can override <code>-(BOOL)becomeFirstResponder</code> and enforce layout constraints there. Adhering to these constraints bumps the accessory view up, but another bug arises: <img loading="lazy" src="/blog/assets/input-accessory-5.gif" style="float:left;padding-right:70px;padding-top:20px" class="img_SS3x"></p><p>The input accessory view successfully avoids the home pill, but now content behind the unsafe area is visible. The solution lies in this <a href="http://www.openradar.me/34411433" target="_blank" rel="noopener noreferrer">radar</a>. I wrapped the native <code>&lt;InputAccessoryView&gt;</code> hierarchy in a container which doesn't conform to the <code>safeAreaLayoutGuide</code> constraints. The native container covers the content in the unsafe area, while the <code>&lt;InputAccessoryView&gt;</code> stays within the safe area boundaries.</p><hr style="clear:both;margin-bottom:20px"><h2 class="anchor anchorWithStickyNavbar_JmGV" id="example-usage">Example Usage<a class="hash-link" href="#example-usage" title="Direct link to heading">​</a></h2><p>Here's an example which builds a keyboard toolbar button to reset <code>&lt;TextInput&gt;</code> state.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">class</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">TextInputAccessoryViewExample</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">extends</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">React</span><span class="token class-name punctuation" style="color:#657b83">.</span><span class="token class-name" style="color:#fac863">Component</span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">{</span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">*</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">constructor</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">props</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">super</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">props</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token literal-property property" style="color:#2aa198">text</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'Placeholder Text'</span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">render</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> inputAccessoryViewID </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'inputAccessoryView1'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">TextInput</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">          </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript keyword module" style="color:#c5a5c5">default</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">          </span><span class="token tag attr-name" style="color:#c5a5c5">inputAccessoryViewID</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">inputAccessoryViewID</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">          </span><span class="token tag attr-name" style="color:#c5a5c5">onChangeText</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript parameter" style="color:#fc929e">text</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript keyword" style="color:#c5a5c5">this</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript method function property-access" style="color:#79b6f2">setState</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">text</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">          </span><span class="token tag attr-name" style="color:#c5a5c5">value</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript keyword" style="color:#c5a5c5">this</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">state</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">text</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">        </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">InputAccessoryView</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">nativeID</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">inputAccessoryViewID</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">          </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">backgroundColor</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript string" style="color:#8dc891">'white'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">            </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Button</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">              </span><span class="token tag attr-name" style="color:#c5a5c5">onPress</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">                </span><span class="token tag script language-javascript keyword" style="color:#c5a5c5">this</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript method function property-access" style="color:#79b6f2">setState</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">text</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript string" style="color:#8dc891">'Placeholder Text'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">              </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">              </span><span class="token tag attr-name" style="color:#c5a5c5">title</span><span class="token tag attr-value punctuation attr-equals" style="color:#657b83">=</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag attr-value" style="color:#8dc891">Reset Text</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">            </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">          </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">InputAccessoryView</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Another example for <a href="https://github.com/facebook/react-native/blob/84ef7bc372ad870127b3e1fb8c13399fe09ecd4d/RNTester/js/InputAccessoryViewExample.js" target="_blank" rel="noopener noreferrer">Sticky Text Inputs can be found in the repository</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="when-will-i-be-able-to-use-this">When will I be able to use this?<a class="hash-link" href="#when-will-i-be-able-to-use-this" title="Direct link to heading">​</a></h2><p>The full commit for this feature implementation is <a href="https://github.com/facebook/react-native/commit/38197c8230657d567170cdaf8ff4bbb4aee732b8" target="_blank" rel="noopener noreferrer">here</a>. <a href="/docs/next/inputaccessoryview"><code>&lt;InputAccessoryView&gt;</code></a> will be available in the upcoming v0.55.0 release.</p><p>Happy keyboarding :)</p>]]></content>
        <author>
            <name>Peter Argany</name>
            <uri>https://github.com/PeteTheHeat</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Using AWS with React Native]]></title>
        <id>/2018/03/05/AWS-app-sync</id>
        <link href="https://reactnative.dev/blog/2018/03/05/AWS-app-sync"/>
        <updated>2018-03-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[AWS is well known in the technology industry as a provider of cloud services. These include compute, storage, and database technologies, as well as fully managed serverless offerings. The AWS Mobile team has been working closely with customers and members of the JavaScript ecosystem to make cloud-connected mobile and web applications more secure, scalable, and easier to develop and deploy. We began with a complete starter kit, but have a few more recent developments.]]></summary>
        <content type="html"><![CDATA[<p>AWS is well known in the technology industry as a provider of cloud services. These include compute, storage, and database technologies, as well as fully managed serverless offerings. The AWS Mobile team has been working closely with customers and members of the JavaScript ecosystem to make cloud-connected mobile and web applications more secure, scalable, and easier to develop and deploy. We began with a <a href="https://github.com/awslabs/aws-mobile-react-native-starter" target="_blank" rel="noopener noreferrer">complete starter kit</a>, but have a few more recent developments.</p><p>This blog post talks about some interesting things for React and React Native developers:</p><ul><li><a href="https://github.com/aws/aws-amplify" target="_blank" rel="noopener noreferrer"><strong>AWS Amplify</strong></a>, a declarative library for JavaScript applications using cloud services</li><li><a href="https://aws.amazon.com/appsync/" target="_blank" rel="noopener noreferrer"><strong>AWS AppSync</strong></a>, a fully managed GraphQL service with offline and real-time features</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="aws-amplify">AWS Amplify<a class="hash-link" href="#aws-amplify" title="Direct link to heading">​</a></h2><p>React Native applications are very easy to bootstrap using tools like Create React Native App and Expo. However, connecting them to the cloud can be challenging to navigate when you try to match a use case to infrastructure services. For example, your React Native app might need to upload photos. Should these be protected per user? That probably means you need some sort of registration or sign-in process. Do you want your own user directory or are you using a social media provider? Maybe your app also needs to call an API with custom business logic after users log in.</p><p>To help JavaScript developers with these problems, we released a library named AWS Amplify. The design is broken into "categories" of tasks, instead of AWS-specific implementations. For example, if you wanted users to register, log in, and then upload private photos, you would simply pull in <code>Auth</code> and <code>Storage</code> categories to your application:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Auth</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'aws-amplify'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">Auth</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">signIn</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">username</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> password</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">then</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">user</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">.</span><span class="token keyword control-flow" style="color:#c5a5c5">catch</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">err</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">Auth</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">confirmSignIn</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">user</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> code</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">then</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">data</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">data</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">.</span><span class="token keyword control-flow" style="color:#c5a5c5">catch</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">err</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">err</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>In the code above, you can see an example of some of the common tasks that Amplify helps you with, such as using multi-factor authentication (MFA) codes with either email or SMS. The supported categories today are:</p><ul><li><strong>Auth</strong>: Provides credential automation. Out-of-the-box implementation uses AWS credentials for signing, and OIDC JWT tokens from <a href="https://aws.amazon.com/cognito/" target="_blank" rel="noopener noreferrer">Amazon Cognito</a>. Common functionality, such as MFA features, is supported.</li><li><strong>Analytics</strong>: With a single line of code, get tracking for authenticated or unauthenticated users in <a href="https://aws.amazon.com/pinpoint/" target="_blank" rel="noopener noreferrer">Amazon Pinpoint</a>. Extend this for custom metrics or attributes, as you prefer.</li><li><strong>API</strong>: Provides interaction with RESTful APIs in a secure manner, leveraging <a href="https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html" target="_blank" rel="noopener noreferrer">AWS Signature Version 4</a>. The API module is great on serverless infrastructures with <a href="https://aws.amazon.com/api-gateway/" target="_blank" rel="noopener noreferrer">Amazon API Gateway</a>.</li><li><strong>Storage</strong>: Simplified commands to upload, download, and list content in <a href="https://aws.amazon.com/s3/" target="_blank" rel="noopener noreferrer">Amazon S3</a>. You can also easily group data into public or private content on a per-user basis.</li><li><strong>Caching</strong>: An LRU cache interface across web apps and React Native that uses implementation-specific persistence.</li><li><strong>i18n and Logging</strong>: Provides internationalization and localization capabilities, as well as debugging and logging capabilities.</li></ul><p>One of the nice things about Amplify is that it encodes "best practices" in the design for your specific programming environment. For example, one thing we found working with customers and React Native developers is that shortcuts taken during development to get things working quickly would make it through to production stacks. These can compromise either scalability or security, and force infrastructure rearchitecture and code refactoring.</p><p>One example of how we help developers avoid this is the <a href="https://www.allthingsdistributed.com/2016/06/aws-lambda-serverless-reference-architectures.html" target="_blank" rel="noopener noreferrer">Serverless Reference Architectures with AWS Lambda</a>. These show you best practices around using Amazon API Gateway and AWS Lambda together when building your backend. This pattern is encoded into the <code>API</code> category of Amplify. You can use this pattern to interact with several different REST endpoints, and pass headers all the way through to your Lambda function for custom business logic. We’ve also released an <a href="https://docs.aws.amazon.com/aws-mobile/latest/developerguide/react-native-getting-started.html" target="_blank" rel="noopener noreferrer">AWS Mobile CLI</a> for bootstrapping new or existing React Native projects with these features. To get started, just install via <strong>npm</strong>, and follow the configuration prompts:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">npm install </span><span class="token operator" style="color:#fc929e">--</span><span class="token plain">global awsmobile</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">cli</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">awsmobile configure</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Another example of encoded best practices that is specific to the mobile ecosystem is password security. The default <code>Auth</code> category implementation leverages Amazon Cognito user pools for user registration and sign-in. This service implements <a href="http://srp.stanford.edu" target="_blank" rel="noopener noreferrer">Secure Remote Password protocol</a> as a way of protecting users during authentication attempts. If you're inclined to read through the <a href="http://srp.stanford.edu/ndss.html#SECTION00032200000000000000" target="_blank" rel="noopener noreferrer">mathematics of the protocol</a>, you'll notice that you must use a large prime number when calculating the password verifier over a primitive root to generate a Group. In React Native environments, <a href="/docs/javascript-environment">JIT is disabled</a>. This makes BigInteger calculations for security operations such as this less performant. To account for this, we've released native bridges in Android and iOS that you can link inside your project:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">npm install </span><span class="token operator" style="color:#fc929e">--</span><span class="token plain">save aws</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">amplify</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">react</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">native</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">react</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">native link amazon</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">cognito</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">identity</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">js</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We're also excited to see that the Expo team has included this <a href="https://blog.expo.io/expo-sdk-v25-0-0-is-now-available-714d10a8c3f7" target="_blank" rel="noopener noreferrer">in their latest SDK</a> so that you can use Amplify without ejecting.</p><p>Finally, specific to React Native (and React) development, Amplify contains <a href="https://reactjs.org/docs/higher-order-components.html" target="_blank" rel="noopener noreferrer">higher order components (HOCs)</a> for easily wrapping functionality, such as for sign-up and sign-in to your app:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">Amplify</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports"> withAuthenticator </span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'aws-amplify-react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports">aws_exports</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'./aws-exports'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">Amplify</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">configure</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">aws_exports</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">class</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">App</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">extends</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">React</span><span class="token class-name punctuation" style="color:#657b83">.</span><span class="token class-name" style="color:#fac863">Component</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token spread operator" style="color:#fc929e">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">default</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">withAuthenticator</span><span class="token punctuation" style="color:#657b83">(</span><span class="token maybe-class-name">App</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The underlying component is also provided as <code>&lt;Authenticator /&gt;</code>, which gives you full control to customize the UI. It also gives you some properties around managing the state of the user, such as if they've signed in or are waiting for MFA confirmation, and callbacks that you can fire when state changes.</p><p>Similarly, you'll find general React components that you can use for different use cases. You can customize these to your needs, for example, to show all private images from Amazon S3 in the <code>Storage</code> module:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">S3Album</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">level</span><span class="token tag attr-value punctuation attr-equals" style="color:#657b83">=</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag attr-value" style="color:#8dc891">private</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">path</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">path</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">filter</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript parameter" style="color:#fc929e">item</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript regex regex-delimiter" style="color:#8dc891">/</span><span class="token tag script language-javascript regex regex-source language-regex" style="color:#8dc891">jpg</span><span class="token tag script language-javascript regex regex-delimiter" style="color:#8dc891">/</span><span class="token tag script language-javascript regex regex-flags" style="color:#8dc891">i</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript method function property-access" style="color:#79b6f2">test</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript" style="color:#fc929e">item</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">path</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You can control many of the component features via props, as shown earlier, with public or private storage options. There are even capabilities to automatically gather analytics when users interact with certain UI components:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">S3Album</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">track</span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>AWS Amplify favors a convention over configuration style of development, with a global initialization routine or initialization at the category level. The quickest way to get started is with an <a href="https://aws.amazon.com/blogs/mobile/enhanced-javascript-development-with-aws-mobile-hub/" target="_blank" rel="noopener noreferrer">aws-exports file</a>. However, developers can also use the library independently with existing resources.</p><p>For a deep dive into the philosophy and to see a full demo, check out the video from <a href="https://www.youtube.com/watch?v=vAjf3lyjf8c" target="_blank" rel="noopener noreferrer">AWS re:Invent</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="aws-appsync">AWS AppSync<a class="hash-link" href="#aws-appsync" title="Direct link to heading">​</a></h2><p>Shortly after the launch of AWS Amplify, we also released <a href="https://aws.amazon.com/appsync/" target="_blank" rel="noopener noreferrer">AWS AppSync</a>. This is a fully managed GraphQL service that has both offline and real-time capabilities. Although you can use GraphQL in different client programming languages (including native Android and iOS), it's quite popular among React Native developers. This is because the data model fits nicely into a unidirectional data flow and component hierarchy.</p><p>AWS AppSync enables you to connect to resources in your own AWS account, meaning you own and control your data. This is done by using data sources, and the service supports <a href="https://aws.amazon.com/dynamodb/" target="_blank" rel="noopener noreferrer">Amazon DynamoDB</a>, <a href="https://aws.amazon.com/elasticsearch-service/" target="_blank" rel="noopener noreferrer">Amazon Elasticsearch</a>, and <a href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener noreferrer">AWS Lambda</a>. This enables you to combine functionality (such as NoSQL and full-text search) in a single GraphQL API as a schema. This enables you to mix and match data sources. The AppSync service can also <a href="https://docs.aws.amazon.com/appsync/latest/devguide/provision-from-schema.html" target="_blank" rel="noopener noreferrer">provision from a schema</a>, so if you aren't familiar with AWS services, you can write GraphQL SDL, click a button, and you're automatically up and running.</p><p>The real-time functionality in AWS AppSync is controlled via <a href="http://graphql.org/blog/subscriptions-in-graphql-and-relay/" target="_blank" rel="noopener noreferrer">GraphQL subscriptions with a well-known, event-based pattern</a>. Because subscriptions in AWS AppSync are <a href="https://docs.aws.amazon.com/appsync/latest/devguide/real-time-data.html" target="_blank" rel="noopener noreferrer">controlled on the schema</a> with a GraphQL directive, and a schema can use any data source, this means you can trigger notifications from database operations with Amazon DynamoDB and Amazon Elasticsearch Service, or from other parts of your infrastructure with AWS Lambda.</p><p>In a way similar to AWS Amplify, you can use <a href="https://docs.aws.amazon.com/appsync/latest/devguide/security.html" target="_blank" rel="noopener noreferrer">enterprise security features</a> on your GraphQL API with AWS AppSync. The service lets you get started quickly with API keys. However, as you roll to production it can transition to using AWS Identity and Access Management (IAM) or OIDC tokens from Amazon Cognito user pools. You can control access at the resolver level with policies on types. You can even use logical checks for <a href="https://docs.aws.amazon.com/appsync/latest/devguide/security.html#fine-grained-access-control" target="_blank" rel="noopener noreferrer">fine-grained access control</a> checks at run time, such as detecting if a user is the owner of a specific database resource. There are also capabilities around checking group membership for executing resolvers or individual database record access.</p><p>To help React Native developers learn more about these technologies, there is a <a href="https://docs.aws.amazon.com/appsync/latest/devguide/quickstart.html" target="_blank" rel="noopener noreferrer">built-in GraphQL sample schema</a> that you can launch on the AWS AppSync console homepage. This sample deploys a GraphQL schema, provisions database tables, and connects queries, mutations, and subscriptions automatically for you. There is also a functioning <a href="https://github.com/aws-samples/aws-mobile-appsync-events-starter-react-native" target="_blank" rel="noopener noreferrer">React Native example for AWS AppSync</a> which leverages this built in schema (as well as a <a href="https://github.com/aws-samples/aws-mobile-appsync-events-starter-react" target="_blank" rel="noopener noreferrer">React example</a>), which enable you to get both your client and cloud components running in minutes.</p><p>Getting started is simple when you use the <code>AWSAppSyncClient</code>, which plugs in to the <a href="https://github.com/apollographql/apollo-client" target="_blank" rel="noopener noreferrer">Apollo Client</a>. The <code>AWSAppSyncClient</code> handles security and signing for your GraphQL API, offline functionality, and the subscription handshake and negotiation process:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">AWSAppSyncClient</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"aws-appsync"</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">Rehydrated</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'aws-appsync-react'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token constant" style="color:#5a9bcf">AUTH_TYPE</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"aws-appsync/lib/link/auth-link"</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> client </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">AWSAppSyncClient</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">url</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> awsconfig</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">graphqlEndpoint</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">region</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> awsconfig</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">region</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">auth</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token literal-property property" style="color:#2aa198">type</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token constant" style="color:#5a9bcf">AUTH_TYPE</span><span class="token punctuation" style="color:#657b83">.</span><span class="token constant" style="color:#5a9bcf">API_KEY</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">apiKey</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> awsconfig</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">apiKey</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The AppSync console provides a configuration file for download, which contains your GraphQL endpoint, AWS Region, and API key. You can then use the client with <a href="https://github.com/apollographql/react-apollo" target="_blank" rel="noopener noreferrer">React Apollo</a>:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> </span><span class="token function-variable function maybe-class-name" style="color:#79b6f2">WithProvider</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">ApolloProvider</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">client</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">client</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Rehydrated</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">          </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">App</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Rehydrated</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">ApolloProvider</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>At this point, you can use standard GraphQL queries:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">query </span><span class="token maybe-class-name">ListEvents</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    listEvents</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      items</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        __typename</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        id</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        name</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        where</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        when</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        description</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        comments</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          __typename</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          items</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            __typename</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            eventId</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            commentId</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            content</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            createdAt</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          nextToken</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The example above shows a query with the sample app schema provisioned by AppSync. It not only showcases interaction with DynamoDB, but also includes pagination of data (including encrypted tokens) and type relations between <code>Events</code> and <code>Comments</code>. Because the app is configured with the <code>AWSAppSyncClient</code>, data is automatically persisted offline and will synchronize when devices reconnect.</p><p>You can see a deep dive of the <a href="https://www.youtube.com/watch?v=FtkVlIal_m0" target="_blank" rel="noopener noreferrer">client technology behind this and a React Native demo in this video</a>.</p><iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/FtkVlIal_m0?rel=0" frameborder="0" allow="autoplay; encrypted-media"></iframe><h2 class="anchor anchorWithStickyNavbar_JmGV" id="feedback">Feedback<a class="hash-link" href="#feedback" title="Direct link to heading">​</a></h2><p>The team behind the libraries is eager to hear how these libraries and services work for you. They also want to hear what else we can do to make React and React Native development with cloud services easier for you. Reach out to the AWS Mobile team on GitHub for <a href="https://github.com/aws/aws-amplify" target="_blank" rel="noopener noreferrer">AWS Amplify</a> or <a href="https://github.com/aws-samples/aws-mobile-appsync-events-starter-react-native" target="_blank" rel="noopener noreferrer">AWS AppSync</a>.</p>]]></content>
        <author>
            <name>Richard Threlkeld</name>
            <uri>https://twitter.com/undef_obj</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Implementing Twitter’s App Loading Animation in React Native]]></title>
        <id>/2018/01/18/implementing-twitters-app-loading-animation-in-react-native</id>
        <link href="https://reactnative.dev/blog/2018/01/18/implementing-twitters-app-loading-animation-in-react-native"/>
        <updated>2018-01-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Twitter’s iOS app has a loading animation I quite enjoy.]]></summary>
        <content type="html"><![CDATA[<p>Twitter’s iOS app has a loading animation I quite enjoy.</p><img loading="lazy" src="/blog/assets/loading-screen-01.gif" style="float:left;padding-right:80px;padding-bottom:20px" class="img_SS3x"><p>Once the app is ready, the Twitter logo delightfully expands, revealing the app.</p><p>I wanted to figure out how to recreate this loading animation with React Native.</p><hr style="clear:both;margin-bottom:40px;width:80px"><p>To understand <em>how</em> to build it, I first had to understand the difference pieces of the loading animation. The easiest way to see the subtlety is to slow it down.</p><img loading="lazy" src="/blog/assets/loading-screen-02.gif" style="margin-top:20px;float:left;padding-right:80px;padding-bottom:20px" class="img_SS3x"><p>There are a few major pieces in this that we will need to figure out how to build.</p><ol><li>Scaling the bird.</li><li>As the bird grows, showing the app underneath</li><li>Scaling the app down slightly at the end</li></ol><p>It took me quite a while to figure out how to make this animation.</p><p>I started with an <em>incorrect</em> assumption that the blue background and Twitter bird were a layer on <em>top</em> of the app and that as the bird grew, it became transparent which revealed the app underneath. This approach doesn’t work because the Twitter bird becoming transparent would show the blue layer, not the app underneath!</p><p>Luckily for you, dear reader, you don’t have to go through the same frustration I did. You get this nice tutorial skipping to the good stuff!</p><hr style="clear:both;margin-bottom:40px;width:80px"><h2 class="anchor anchorWithStickyNavbar_JmGV" id="the-right-way">The right way<a class="hash-link" href="#the-right-way" title="Direct link to heading">​</a></h2><p>Before we get to code, it is important to understand how to break this down. To help visualize this effect, I recreated it in <a href="https://codepen.io/TheSavior/pen/NXNoJM" target="_blank" rel="noopener noreferrer">CodePen</a> (embedded in a few paragraphs) so you can interactively see the different layers.</p><img loading="lazy" src="/blog/assets/loading-screen-03.png" style="float:left;padding-right:80px;padding-bottom:20px" class="img_SS3x"><p>There are three main layers to this effect. The first is the blue background layer. Even though this seems to appear on top of the app, it is actually in the back.</p><p>We then have a plain white layer. And then lastly, in the very front, is our app.</p><hr style="clear:both;margin-bottom:40px;width:80px"><img loading="lazy" src="/blog/assets/loading-screen-04.png" style="float:left;padding-right:80px;padding-bottom:20px" class="img_SS3x"><p>The main trick to this animation is using the Twitter logo as a <code>mask</code> and masking both the app, and the white layer. I won’t go too deep on the details of masking, there are <a href="https://www.html5rocks.com/en/tutorials/masking/adobe/" target="_blank" rel="noopener noreferrer">plenty</a> of <a href="https://designshack.net/articles/graphics/a-complete-beginners-guide-to-masking-in-photoshop/" target="_blank" rel="noopener noreferrer">resources</a> <a href="https://www.sketchapp.com/docs/shapes/masking/" target="_blank" rel="noopener noreferrer">online</a> for that.</p><p>The basics of masking in this context are having images where opaque pixels of the mask show the content they are masking whereas transparent pixels of the mask hide the content they are masking.</p><p>We use the Twitter logo as a mask, and having it mask two layers; the solid white layer, and the app layer.</p><p>To reveal the app, we scale the mask up until it is larger than the entire screen.</p><p>While the mask is scaling up, we fade in the opacity of the app layer, showing the app and hiding the solid white layer behind it. To finish the effect, we start the app layer at a scale &gt; 1, and scale it down to 1 as the animation is ending. We then hide the non-app layers as they will never be seen again.</p><p>They say a picture is worth 1,000 words. How many words is an interactive visualization worth? Click through the animation with the “Next Step” button. Showing the layers gives you a side view perspective. The grid is there to help visualize the transparent layers.</p><iframe height="750" scrolling="no" title="Loading Screen Animation Steps" src="//codepen.io/TheSavior/embed/NXNoJM/?height=265&amp;theme-id=0&amp;default-tab=result&amp;embed-version=2" frameborder="no" allowfullscreen="" class="codepen">See the Pen<!-- --> <a href="https://codepen.io/TheSavior/pen/NXNoJM/" target="_blank" rel="noopener noreferrer">Loading Screen Animation Steps</a> <!-- -->by Eli White (<a href="https://codepen.io/TheSavior" target="_blank" rel="noopener noreferrer">@TheSavior</a>) on<!-- --> <a href="https://codepen.io" target="_blank" rel="noopener noreferrer">CodePen</a>.</iframe><h2 class="anchor anchorWithStickyNavbar_JmGV" id="now-for-the-react-native">Now, for the React Native<a class="hash-link" href="#now-for-the-react-native" title="Direct link to heading">​</a></h2><p>Alrighty. Now that we know what we are building and how the animation works, we can get down to the code — the reason you are really here.</p><p>The main piece of this puzzle is <a href="https://reactnative.dev/docs/0.63/maskedviewios" target="_blank" rel="noopener noreferrer">MaskedViewIOS</a>, a core React Native component.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">MaskedViewIOS</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">MaskedViewIOS</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">maskElement</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">Text</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&gt;</span><span class="token tag script language-javascript plain-text" style="color:#fc929e">Basic Mask</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">Text</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&gt;</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">backgroundColor</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript string" style="color:#8dc891">'blue'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">MaskedViewIOS</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><code>MaskedViewIOS</code> takes props <code>maskElement</code> and <code>children</code>. The children are masked by the <code>maskElement</code>. Note that the mask doesn’t need to be an image, it can be any arbitrary view. The behavior of the above example would be to render the blue view, but for it to be visible only where the words “Basic Mask” are from the <code>maskElement</code>. We just made complicated blue text.</p><p>What we want to do is render our blue layer, and then on top render our masked app and white layers with the Twitter logo.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  fullScreenBlueLayer</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">MaskedViewIOS</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">flex</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript number" style="color:#5a9bcf">1</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">maskElement</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">View</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript tag script language-javascript property-access" style="color:#fc929e">centeredFullScreen</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&gt;</span><span class="token tag script language-javascript plain-text" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript plain-text" style="color:#fc929e">      </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">Image</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">source</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">twitterLogo</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">/&gt;</span><span class="token tag script language-javascript plain-text" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript plain-text" style="color:#fc929e">    </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">View</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">  </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">fullScreenWhiteLayer</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">flex</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript number" style="color:#5a9bcf">1</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">MyApp</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">MaskedViewIOS</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This will give us the layers we see below.</p><img loading="lazy" src="/blog/assets/loading-screen-04.png" style="margin-left:auto;margin-right:auto;display:block" class="img_SS3x"><h2 class="anchor anchorWithStickyNavbar_JmGV" id="now-for-the-animated-part">Now for the Animated part<a class="hash-link" href="#now-for-the-animated-part" title="Direct link to heading">​</a></h2><p>We have all the pieces we need to make this work, the next step is animating them. To make this animation feel good, we will be utilizing React Native’s <a href="/docs/animated">Animated</a> API.</p><p>Animated lets us define our animations declaratively in JavaScript. By default, these animations run in JavaScript and tell the native layer what changes to make on every frame. Even though JavaScript will try to update the animation every frame, it will likely not be able to do that fast enough and will cause dropped frames (jank) to occur. Not what we want!</p><p>Animated has special behavior to allow you to get animations without this jank. Animated has a flag called <code>useNativeDriver</code> which sends your animation definition from JavaScript to native at the beginning of your animation, allowing the native side to process the updates to your animation without having to go back and forth to JavaScript every frame. The downside of <code>useNativeDriver</code> is you can only update a specific set of properties, mostly <code>transform</code> and <code>opacity</code>. You can’t animate things like background color with <code>useNativeDriver</code>, at least not yet — we will add more over time, and of course you can always submit a PR for properties you need for your project, benefitting the whole community 😀.</p><p>Since we want this animation to be smooth, we will work within these constraints. For a more in depth look at how <code>useNativeDriver</code> works under the hood, check out our <a href="/blog/2017/02/14/using-native-driver-for-animated">blog post announcing it</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="breaking-down-our-animation">Breaking down our animation<a class="hash-link" href="#breaking-down-our-animation" title="Direct link to heading">​</a></h2><p>There are 4 components to our animation:</p><ol><li>Enlarge the bird, revealing the app and the solid white layer</li><li>Fade in the app</li><li>Scale down the app</li><li>Hide the white layer and blue layer when it is done</li></ol><p>With Animated, there are two main ways to define your animation. The first is by using <code>Animated.timing</code> which lets you say exactly how long your animation will run for, along with an easing curve to smooth out the motion. The other approach is by using the physics based apis such as <code>Animated.spring</code>. With <code>Animated.spring</code>, you specify parameters like the amount of friction and tension in the spring, and let physics run your animation.</p><p>We have multiple animations we want to be running at the same time which are all closely related to each other. For example, we want the app to start fading in while the mask is mid-reveal. Because these animations are closely related, we will use <code>Animated.timing</code> with a single <code>Animated.Value</code>.</p><p><code>Animated.Value</code> is a wrapper around a native value that Animated uses to know the state of an animation. You typically want to only have one of these for a complete animation. Most components that use Animated will store the value in state.</p><p>Since I’m thinking about this animation as steps occurring at different points in time along the complete animation, we will start our <code>Animated.Value</code> at 0, representing 0% complete, and end our value at 100, representing 100% complete.</p><p>Our initial component state will be the following.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">state </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">loadingProgress</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">Animated</span><span class="token class-name punctuation" style="color:#657b83">.</span><span class="token class-name" style="color:#fac863">Value</span><span class="token punctuation" style="color:#657b83">(</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>When we are ready to begin the animation, we tell Animated to animate this value to 100.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">timing</span><span class="token punctuation" style="color:#657b83">(</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">loadingProgress</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">toValue</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">duration</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1000</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">useNativeDriver</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// This is important!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">start</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>I then try to figure out a rough estimate of the different pieces of the animations and the values I want them to have at different stages of the overall animation. Below is a table of the different pieces of the animation, and what I think their values should be at different points as we progress through time.</p><p><img loading="lazy" src="/assets/images/loading-screen-05-9b5c5f9b785287a11b6444ad4a8afcad.png" width="800" height="123" class="img_SS3x"></p><p>The Twitter bird mask should start at scale 1, and it gets smaller before it shoots up in size. So at 10% through the animation, it should have a scale value of .8 before shooting up to scale 70 at the end. Picking 70 was pretty arbitrary to be honest, it needed to be large enough that the bird fully revealed the screen and 60 wasn’t big enough 😀. Something interesting about this part though is that the higher the number, the faster it will look like it is growing because it has to get there in the same amount of time. This number took some trial and error to make look good with this logo. Logos / devices of different sizes will require this end-scale to be different to ensure the entire screen is revealed.</p><p>The app should stay opaque for a while, at least through the Twitter logo getting smaller. Based on the official animation, I want to start showing it when the bird is mid way through scaling it up and to fully reveal it pretty quickly. So at 15% we start showing it, and at 30% through the overall animation it is fully visible.</p><p>The app scale starts at 1.1 and scales down to its regular scale by the end of the animation.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="and-now-in-code">And now, in code.<a class="hash-link" href="#and-now-in-code" title="Direct link to heading">​</a></h2><p>What we essentially did above is map the values from the animation progress percentage to the values for the individual pieces. We do that with Animated using <code>.interpolate</code>. We create 3 different style objects, one for each piece of the animation, using interpolated values based off of <code>this.state.loadingProgress</code>.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> loadingProgress </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">loadingProgress</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> opacityClearToVisible </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">opacity</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> loadingProgress</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">interpolate</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">inputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">15</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">30</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">outputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">extrapolate</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'clamp'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token comment" style="color:#93a1a1">// clamp means when the input is 30-100, output should stay at 1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> imageScale </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">transform</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token literal-property property" style="color:#2aa198">scale</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> loadingProgress</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">interpolate</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token literal-property property" style="color:#2aa198">inputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">10</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token literal-property property" style="color:#2aa198">outputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0.8</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">70</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> appScale </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">transform</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token literal-property property" style="color:#2aa198">scale</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> loadingProgress</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">interpolate</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token literal-property property" style="color:#2aa198">inputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token literal-property property" style="color:#2aa198">outputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">1.1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Now that we have these style objects, we can use them when rendering the snippet of the view from earlier in the post. Note that only <code>Animated.View</code>, <code>Animated.Text</code>, and <code>Animated.Image</code> are able to use style objects that use <code>Animated.Value</code>.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> fullScreenBlueLayer </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">fullScreenBlueLayer</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> fullScreenWhiteLayer </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">fullScreenWhiteLayer</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">fullScreen</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">    </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">fullScreenBlueLayer</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">MaskedViewIOS</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">      </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">flex</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript number" style="color:#5a9bcf">1</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">      </span><span class="token tag attr-name" style="color:#c5a5c5">maskElement</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">        </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">View</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript tag script language-javascript property-access" style="color:#fc929e">centeredFullScreen</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&gt;</span><span class="token tag script language-javascript plain-text" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript plain-text" style="color:#fc929e">          </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">Animated.Image</span><span class="token tag script language-javascript tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript tag" style="color:#fc929e">            </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript tag script language-javascript property-access" style="color:#fc929e">maskImageStyle</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e"> imageScale</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript tag" style="color:#fc929e">            </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">source</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">twitterLogo</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript tag" style="color:#fc929e">          </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">/&gt;</span><span class="token tag script language-javascript plain-text" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript plain-text" style="color:#fc929e">        </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">View</span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">      </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">      </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">fullScreenWhiteLayer</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Animated.View</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">        </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e">opacityClearToVisible</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> appScale</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">flex</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript number" style="color:#5a9bcf">1</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">        </span><span class="token punctuation" style="color:#657b83">{</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">children</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Animated.View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">MaskedViewIOS</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><img loading="lazy" src="/blog/assets/loading-screen-06.gif" style="float:left;padding-right:80px;padding-bottom:20px" class="img_SS3x"><p>Yay! We now have the animation pieces looking like we want. Now we just have to clean up our blue and white layers which will never be seen again.</p><p>To know when we can clean them up, we need to know when the animation is complete. Luckily where we call, <code>Animated.timing</code> ,<code>.start</code> takes an optional callback that runs when the animation is complete.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">timing</span><span class="token punctuation" style="color:#657b83">(</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">loadingProgress</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">toValue</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">100</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">duration</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1000</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">useNativeDriver</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">start</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">setState</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">animationDone</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Now that we have a value in <code>state</code> to know whether we are done with the animation, we can modify our blue and white layers to use that.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> fullScreenBlueLayer </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">animationDone</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">?</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#c5a5c5">null</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">fullScreenBlueLayer</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> fullScreenWhiteLayer </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">animationDone</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">?</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#c5a5c5">null</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e">styles</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">fullScreenWhiteLayer</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Voila! Our animation now works and we clean up our unused layers once the animation is done. We have built the Twitter app loading animation!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="but-wait-mine-doesnt-work">But wait, mine doesn’t work!<a class="hash-link" href="#but-wait-mine-doesnt-work" title="Direct link to heading">​</a></h2><p>Don’t fret, dear reader. I too hate when guides only give you chunks of the code and don’t give you the completed source.</p><p>This component has been published to npm and is on GitHub as <a href="https://github.com/TheSavior/react-native-mask-loader" target="_blank" rel="noopener noreferrer">react-native-mask-loader</a>. To try this out on your phone, it is <a href="https://expo.io/@eliwhite/react-native-mask-loader-example" target="_blank" rel="noopener noreferrer">available on Expo</a> here:</p><img loading="lazy" src="/blog/assets/loading-screen-07.png" style="margin-left:auto;margin-right:auto;display:block" class="img_SS3x"><h2 class="anchor anchorWithStickyNavbar_JmGV" id="more-reading--extra-credit">More Reading / Extra Credit<a class="hash-link" href="#more-reading--extra-credit" title="Direct link to heading">​</a></h2><ol><li><a href="http://browniefed.com/react-native-animation-book/" target="_blank" rel="noopener noreferrer">This gitbook</a> is a great resource to learn more about Animated after you have read the React Native docs.</li><li>The actual Twitter animation seems to speed up the mask reveal towards the end. Try modifying the loader to use a different easing function (or a spring!) to better match that behavior.</li><li>The current end-scale of the mask is hard coded and likely won’t reveal the entire app on a tablet. Calculating the end scale based on screen size and image size would be an awesome PR.</li></ol>]]></content>
        <author>
            <name>Eli White</name>
            <uri>https://github.com/TheSavior</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Monthly #6]]></title>
        <id>/2018/01/09/react-native-monthly-6</id>
        <link href="https://reactnative.dev/blog/2018/01/09/react-native-monthly-6"/>
        <updated>2018-01-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The React Native monthly meeting is still going strong! Make sure to check a note on the bottom of this post for the next sessions.]]></summary>
        <content type="html"><![CDATA[<p>The React Native monthly meeting is still going strong! Make sure to check a note on the bottom of this post for the next sessions.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="expo">Expo<a class="hash-link" href="#expo" title="Direct link to heading">​</a></h3><ul><li>Congratulations to <a href="https://github.com/dabbott" target="_blank" rel="noopener noreferrer">Devin Abbott</a> and <a href="https://twitter.com/hdjirdeh" target="_blank" rel="noopener noreferrer">Houssein Djirdeh</a> on their pre-release of the "Full Stack React Native" book! It walks you through learning React Native by building several small apps. You can try those apps out on <a href="https://www.fullstackreact.com/react-native/" target="_blank" rel="noopener noreferrer">https://www.fullstackreact.com/react-native/</a> before buying the book.</li><li>Released a first (experimental) version of <a href="https://github.com/react-community/reason-react-native-scripts" target="_blank" rel="noopener noreferrer">reason-react-native-scripts</a> to help people to easily try out <a href="https://reasonml.github.io/" target="_blank" rel="noopener noreferrer">ReasonML</a>.</li><li>Expo SDK 24 is <a href="https://blog.expo.io/expo-sdk-v24-0-0-is-now-available-bfcac3b50d51" target="_blank" rel="noopener noreferrer">released</a>! It uses <a href="https://github.com/facebook/react-native/releases/tag/v0.51.0" target="_blank" rel="noopener noreferrer">React Native 0.51</a> and includes a bunch of new features and improvements: bundling images in standalone apps (no need to cache on first load!), image manipulation API (crop, resize, rotate, flip), face detection API, new release channel features (set the active release for a given channel and rollback), web dashboard to track standalone app builds, and a fix longstanding bug with OpenGL Android implementation and the Android multi-tasker, just to name a few things.</li><li>We are allocating more resources to React Navigation starting this January. We strongly believe that it is both possible and desirable to build React Native navigation with just React components and primitives like Animated and <code>react-native-gesture-handler</code> and we’re really excited about some of the improvements we have planned. If you're looking to contribute to the community, check out <a href="https://github.com/react-community/react-native-maps" target="_blank" rel="noopener noreferrer">react-native-maps</a> and <a href="https://github.com/react-native-community/react-native-svg" target="_blank" rel="noopener noreferrer">react-native-svg</a>, which could both use some help!</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="infinite-red">Infinite Red<a class="hash-link" href="#infinite-red" title="Direct link to heading">​</a></h3><ul><li>We have our Keynote speakers for <a href="https://infinite.red/ChainReactConf" target="_blank" rel="noopener noreferrer">Chain React conf</a>: <a href="https://twitter.com/kentcdodds" target="_blank" rel="noopener noreferrer">Kent C. Dodds</a> and <a href="https://twitter.com/ladyleet" target="_blank" rel="noopener noreferrer">Tracy Lee</a>. We will be opening CFP very soon.</li><li><a href="http://community.infinite.red/" target="_blank" rel="noopener noreferrer">Community chat</a> now at 1600 people.</li><li><a href="http://reactnative.cc/" target="_blank" rel="noopener noreferrer">React Native Newsletter</a> now at 8500 subscribers.</li><li>Currently researching best practice for making RN crash resistant, reports to follow.</li><li>Adding ability to report from <a href="https://shift.infinite.red/effortless-environment-reports-d129d53eb405" target="_blank" rel="noopener noreferrer">Solidarity</a>.</li><li>Published a HOW-TO for releasing on <a href="https://shift.infinite.red/simple-react-native-android-releases-319dc5e29605" target="_blank" rel="noopener noreferrer">React Native and Android</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="microsoft">Microsoft<a class="hash-link" href="#microsoft" title="Direct link to heading">​</a></h3><ul><li>A <a href="https://github.com/Microsoft/react-native-windows/pull/1419" target="_blank" rel="noopener noreferrer">pull request</a> has been started to migrate the core React Native Windows bridge to .NET Standard, making it effectively OS-agnostic. The hope is that many other .NET Core platforms can extend the bridge with their own threading models, JavaScript runtimes, and UIManagers (think JavaScriptCore, Xamarin.Mac, Linux Gtk#, and Samsung Tizen options).</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="wix">Wix<a class="hash-link" href="#wix" title="Direct link to heading">​</a></h3><ul><li><a href="https://github.com/wix/detox" target="_blank" rel="noopener noreferrer">Detox</a><ul><li>In order for us to scale with E2E tests, we want to minimize time spent on CI, we are working on parallelization support for Detox.</li><li>Submitted a <a href="https://github.com/facebook/react-native/pull/16948" target="_blank" rel="noopener noreferrer">pull request</a> to enable support for custom flavor builds, to better support mocking on E2E.</li></ul></li><li><a href="https://github.com/wix/DetoxInstruments" target="_blank" rel="noopener noreferrer">DetoxInstruments</a><ul><li>Working on the killer feature of DetoxInstruments proves to be a very challenging task, taking JavaScript backtrace at any given time requires a custom JSCore implementation to support JS thread suspension. Testing the profiler internally on Wix’s app revealed interesting insights about the JS thread.</li><li>The project is still not stable enough for general use but is actively worked on, and we hope to announce it soon.</li></ul></li><li><a href="https://github.com/wix/react-native-navigation" target="_blank" rel="noopener noreferrer">React Native Navigation</a><ul><li>V2 development pace has been increased substantially, up until now, we only had 1 developer working on it 20% of his time, we now have 3 developers working on it full time!</li></ul></li><li>Android Performance<ul><li>Replacing the old JSCore bundled in RN with its newest version (tip of webkitGTK project, with custom JIT configuration) produced 40% performance increase on the JS thread. Next up is compiling a 64bit version of it. This effort is based on <a href="https://github.com/SoftwareMansion/jsc-android-buildscripts" target="_blank" rel="noopener noreferrer">JSC build scripts for Android</a>. Follow its current status <a href="https://github.com/DanielZlotin/jsc-android-buildscripts/tree/tip" target="_blank" rel="noopener noreferrer">here</a>.</li></ul></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-sessions">Next sessions<a class="hash-link" href="#next-sessions" title="Direct link to heading">​</a></h2><p>There's been some discussion on re-purposing this meeting to discuss a single and specific topic (e.g. navigation, moving React Native modules into separate repos, documentation, ...). That way we feel we can contribute the best to React Native community. It might take place in the next meeting session. Feel free to tweet what you'd like to see covered as a topic.</p>]]></content>
        <author>
            <name>Tomislav Tenodi</name>
            <uri>https://twitter.com/TomislavTenodi</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Monthly #5]]></title>
        <id>/2017/11/06/react-native-monthly-5</id>
        <link href="https://reactnative.dev/blog/2017/11/06/react-native-monthly-5"/>
        <updated>2017-11-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The React Native monthly meeting continues! Let's see what our teams are up to.]]></summary>
        <content type="html"><![CDATA[<p>The React Native monthly meeting continues! Let's see what our teams are up to.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="callstack">Callstack<a class="hash-link" href="#callstack" title="Direct link to heading">​</a></h3><ul><li>We’ve been working on React Native CI. Most importantly, we have migrated from Travis to Circle, leaving React Native with a single, unified CI pipeline.</li><li>We’ve organised <a href="https://blog.callstack.io/announcing-hacktoberfest-7313ea5ccf4f" target="_blank" rel="noopener noreferrer">Hacktoberfest - React Native edition</a> where, together with attendees, we tried to submit many pull requests to open source projects.</li><li>We keep working on <a href="https://github.com/callstack/haul" target="_blank" rel="noopener noreferrer">Haul</a>. Last month, we have submitted two new releases, including Webpack 3 support. We plan to add <a href="https://github.com/react-community/create-react-native-app" target="_blank" rel="noopener noreferrer">CRNA</a> and <a href="https://github.com/expo/expo" target="_blank" rel="noopener noreferrer">Expo</a> support as well as work on better HMR. Our roadmap is public on the issue tracker. If you would like to suggest improvements or give feedback, let us know!</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="expo">Expo<a class="hash-link" href="#expo" title="Direct link to heading">​</a></h3><ul><li>Released <a href="https://blog.expo.io/expo-sdk-v22-0-0-is-now-available-7745bfe97fc6" target="_blank" rel="noopener noreferrer">Expo SDK 22</a> (using React Native 0.49) and updated <a href="https://github.com/react-community/create-react-native-app" target="_blank" rel="noopener noreferrer">CRNA</a> for it.<ul><li>Includes improved splash screen API, basic ARKit support, “DeviceMotion” API, SFAuthenticationSession support on iOS11, and <a href="https://blog.expo.io/expo-sdk-v22-0-0-is-now-available-7745bfe97fc6" target="_blank" rel="noopener noreferrer">more</a>.</li></ul></li><li>Your <a href="https://snack.expo.io" target="_blank" rel="noopener noreferrer">snacks</a> can now have multiple JavaScript files and you can upload images and other assets by just dragging them into the editor.</li><li>Contribute to <a href="https://github.com/react-community/react-navigation" target="_blank" rel="noopener noreferrer">react-navigation</a> to add support for iPhone X.</li><li>Focus our attention on rough edges when building large applications with Expo. For example:<ul><li>First-class support for deploying to multiple environments: staging, production, and arbitrary channels. Channels will support rolling back and setting the active release for a given channel. Let us know if you want to be an early tester, <a href="https://twitter.com/expo_io" target="_blank" rel="noopener noreferrer">@expo_io</a>.</li><li>We are also working on improving our standalone app building infrastructure and adding support for bundling images and other non-code assets in standalone app builds while keeping the ability to update assets over the air.</li></ul></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="facebook">Facebook<a class="hash-link" href="#facebook" title="Direct link to heading">​</a></h3><ul><li>Better RTL support:<ul><li>We’re introducing a number of direction-aware styles.<ul><li>Position:<ul><li>(left|right) → (start|end)</li></ul></li><li>Margin:<ul><li>margin(Left|Right) → margin(Start|End)</li></ul></li><li>Padding:<ul><li>padding(Left|Right) → padding(Start|End)</li></ul></li><li>Border:<ul><li>borderTop(Left|Right)Radius → borderTop(Start|End)Radius</li><li>borderBottom(Left|Right)Radius → borderBottom(Start|End)Radius</li><li>border(Left|Right)Width → border(Start|End)Width</li><li>border(Left|Right)Color → border(Start|End)Color</li></ul></li></ul></li><li>The meaning of “left” and “right” were swapped in RTL for position, margin, padding, and border styles. Within a few months, we’re going to remove this behaviour and make “left” always mean “left,” and “right” always mean “right”. The breaking changes are hidden under a flag. Use <code>I18nManager.swapLeftAndRightInRTL(false)</code> in your React Native components to opt into them.</li></ul></li><li>Working on <a href="https://github.com/facebook/flow" target="_blank" rel="noopener noreferrer">Flow</a> typing our internal native modules and using those to generate interfaces in Java and protocols in ObjC that the native implementations must implement. We hope this codegen becomes open source next year, at the earliest.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="infinite-red">Infinite Red<a class="hash-link" href="#infinite-red" title="Direct link to heading">​</a></h3><ul><li>New OSS tool for helping React Native and other projects. More <a href="https://shift.infinite.red/solidarity-the-cli-for-developer-sanity-672fa81b98e9" target="_blank" rel="noopener noreferrer">here</a>.</li><li>Revamping <a href="https://github.com/infinitered/ignite" target="_blank" rel="noopener noreferrer">Ignite</a> for a new boilerplate release (Code name: Bowser)</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="shoutem">Shoutem<a class="hash-link" href="#shoutem" title="Direct link to heading">​</a></h3><ul><li>Improving the development flow on Shoutem. We want to streamline the process from creating an app to first custom screen and make it really easy, thus lowering the barrier for new React Native developers. Prepared a few workshops to test out new features. We also improved <a href="https://github.com/shoutem/cli" target="_blank" rel="noopener noreferrer">Shoutem CLI</a> to support new flows.</li><li><a href="https://github.com/shoutem/ui" target="_blank" rel="noopener noreferrer">Shoutem UI</a> received a few component improvements and bugfixes. We also checked compatibility with latest React Native versions.</li><li>Shoutem platform received a few notable updates, new integrations are available as part of the <a href="https://github.com/shoutem/extensions" target="_blank" rel="noopener noreferrer">open-source extensions project</a>. We are really excited to see active development on Shoutem extensions from other developers. We actively contact and offer advice and guidance about their extensions.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-session">Next session<a class="hash-link" href="#next-session" title="Direct link to heading">​</a></h2><p>The next session is scheduled for Wednesday 6, December 2017. Feel free to ping me <a href="https://twitter.com/TomislavTenodi" target="_blank" rel="noopener noreferrer">on Twitter</a> if you have any suggestion on how we should improve the output of the meeting.</p>]]></content>
        <author>
            <name>Tomislav Tenodi</name>
            <uri>https://github.com/tenodi</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Monthly #4]]></title>
        <id>/2017/09/21/react-native-monthly-4</id>
        <link href="https://reactnative.dev/blog/2017/09/21/react-native-monthly-4"/>
        <updated>2017-09-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The React Native monthly meeting continues! Here are the notes from each team:]]></summary>
        <content type="html"><![CDATA[<p>The React Native monthly meeting continues! Here are the notes from each team:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="callstack">Callstack<a class="hash-link" href="#callstack" title="Direct link to heading">​</a></h3><ul><li><a href="https://react-native.eu" target="_blank" rel="noopener noreferrer">React Native EU</a> is over. More than 300 participants from 33 countries have visited Wroclaw. Talks can be found <a href="https://www.youtube.com/channel/UCUNE_g1mQPuyW975WjgjYxA/videos" target="_blank" rel="noopener noreferrer">on YouTube</a>.</li><li>We are slowly getting back to our open source schedule after the conference. One thing worth mentioning is that we are working on a next release of <a href="https://github.com/callstack/react-native-opentok" target="_blank" rel="noopener noreferrer">react-native-opentok</a> that fixes most of the existing issues.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="geekyants">GeekyAnts<a class="hash-link" href="#geekyants" title="Direct link to heading">​</a></h3><p>Trying to lower the entry barrier for the developers embracing React Native with the following things:</p><ul><li>Announced <a href="https://builderx.io/" target="_blank" rel="noopener noreferrer">BuilderX.io</a> at <a href="https://react-native.eu" target="_blank" rel="noopener noreferrer">React Native EU</a>. BuilderX is a design tool that directly works with JavaScript files (only React Native is supported at the moment) to generate beautiful, readable, and editable code.</li><li>Launched <a href="http://reactnativeseed.com/" target="_blank" rel="noopener noreferrer">ReactNativeSeed.com</a> which provides a set of boilerplates for your next React Native project. It comes with a variety of options that include TypeScript &amp; Flow for data-types, MobX, Redux, and mobx-state-tree for state-management with CRNA and plain React-Native as the stack.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="expo">Expo<a class="hash-link" href="#expo" title="Direct link to heading">​</a></h3><ul><li>Will release SDK 21 shortly, which adds support for react-native 0.48.3 and a bunch of bugfixes/reliability improvements/new features in the Expo SDK, including video recording, a new splash screen API, support for <code>react-native-gesture-handler</code>, and improved error handling.</li><li>Re: <a href="https://github.com/kmagiera/react-native-gesture-handler" target="_blank" rel="noopener noreferrer">react-native-gesture-handler</a>, <a href="https://github.com/kmagiera" target="_blank" rel="noopener noreferrer">Krzysztof Magiera</a> of <a href="http://swmansion.com/" target="_blank" rel="noopener noreferrer">Software Mansion</a> continues pushing this forward and we've been helping him with testing it and funding part of his development time. Having this integrated in Expo in SDK21 will allow people to play with it easily in Snack, so we're excited to see what people come up with.</li><li>Re: improved error logging / handling - see <a href="https://gist.github.com/brentvatne/00407710a854627aa021fdf90490b958" target="_blank" rel="noopener noreferrer">this gist of an internal Expo PR</a> for details on logging, (in particular, "Problem 2"), and <a href="https://github.com/expo/xdl/commit/1d62eca293dfb867fc0afc920c3dad94b7209987" target="_blank" rel="noopener noreferrer">this commit</a> for a change that handles failed attempts to import npm standard library modules. There is plenty of opportunity to improve error messages upstream in React Native in this way and we will work on follow up upstream PRs. It would be great for the community to get involved too.</li><li><a href="http://native.directory/" target="_blank" rel="noopener noreferrer">native.directory</a> continues to grow, you can add your projects from <a href="https://github.com/react-community/native-directory" target="_blank" rel="noopener noreferrer">the GitHub repo</a>.</li><li>Visit hackathons around North America, including <a href="http://pennapps.com/" target="_blank" rel="noopener noreferrer">PennApps</a>, <a href="http://hackthenorth.com/" target="_blank" rel="noopener noreferrer">Hack The North</a>, <a href="https://hackmit.org/" target="_blank" rel="noopener noreferrer">HackMIT</a>, and soon <a href="https://mhacks.org/" target="_blank" rel="noopener noreferrer">MHacks</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="facebook">Facebook<a class="hash-link" href="#facebook" title="Direct link to heading">​</a></h3><ul><li>Working on improving <code>&lt;Text&gt;</code> and <code>&lt;TextInput&gt;</code> components on Android. (Native auto-growing for <code>&lt;TextInput&gt;</code>; deeply nested <code>&lt;Text&gt;</code> components layout issues; better code structure; performance optimizations).</li><li>We're still looking for additional contributors who would like to help triage issues and pull requests.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="microsoft">Microsoft<a class="hash-link" href="#microsoft" title="Direct link to heading">​</a></h3><ul><li>Released Code Signing feature for CodePush. React Native developers are now able to sign their application bundles in CodePush. The announcement can be found <a href="http://microsoft.github.io/code-push/articles/CodeSigningAnnouncement.html" target="_blank" rel="noopener noreferrer">here</a></li><li>Working on completing integration of CodePush to Mobile Center. Considering test/crash integration as well.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-session">Next session<a class="hash-link" href="#next-session" title="Direct link to heading">​</a></h2><p>The next session is scheduled for Wednesday 10, October 2017. As this was only our fourth meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me <a href="https://twitter.com/grabbou" target="_blank" rel="noopener noreferrer">on Twitter</a> if you have any suggestion on how we should improve the output of the meeting.</p>]]></content>
        <author>
            <name>Mike Grabowski</name>
            <uri>https://github.com/grabbou</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Monthly #3]]></title>
        <id>/2017/08/30/react-native-monthly-3</id>
        <link href="https://reactnative.dev/blog/2017/08/30/react-native-monthly-3"/>
        <updated>2017-08-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The React Native monthly meeting continues! This month's meeting was a bit shorter as most of our teams were busy shipping. Next month, we are at React Native EU conference in Wroclaw, Poland. Make sure to grab a ticket and see you there in person! Meanwhile, let's see what our teams are up to.]]></summary>
        <content type="html"><![CDATA[<p>The React Native monthly meeting continues! This month's meeting was a bit shorter as most of our teams were busy shipping. Next month, we are at <a href="https://react-native.eu/" target="_blank" rel="noopener noreferrer">React Native EU</a> conference in Wroclaw, Poland. Make sure to grab a ticket and see you there in person! Meanwhile, let's see what our teams are up to.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="teams">Teams<a class="hash-link" href="#teams" title="Direct link to heading">​</a></h2><p>On this third meeting, we had 5 teams join us:</p><ul><li><a href="https://github.com/callstack" target="_blank" rel="noopener noreferrer">Callstack</a></li><li><a href="https://github.com/expo" target="_blank" rel="noopener noreferrer">Expo</a></li><li><a href="https://github.com/facebook" target="_blank" rel="noopener noreferrer">Facebook</a></li><li><a href="https://github.com/microsoft" target="_blank" rel="noopener noreferrer">Microsoft</a></li><li><a href="https://github.com/shoutem" target="_blank" rel="noopener noreferrer">Shoutem</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="notes">Notes<a class="hash-link" href="#notes" title="Direct link to heading">​</a></h2><p>Here are the notes from each team:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="callstack">Callstack<a class="hash-link" href="#callstack" title="Direct link to heading">​</a></h3><ul><li>Recently open sourced <a href="https://github.com/callstack-io/react-native-material-palette" target="_blank" rel="noopener noreferrer"><code>react-native-material-palette</code></a>. It extracts prominent colors from images to help you create visually engaging apps. It's Android only at the moment, but we are looking into adding support for iOS in the future.</li><li>We have landed HMR support into <a href="https://github.com/callstack-io/haul" target="_blank" rel="noopener noreferrer"><code>haul</code></a> and a bunch of other, cool stuff! Check out latest releases.</li><li>React Native EU 2017 is coming! Next month is all about React Native and Poland! Make sure to grab last tickets available <a href="https://react-native.eu/" target="_blank" rel="noopener noreferrer">here</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="expo">Expo<a class="hash-link" href="#expo" title="Direct link to heading">​</a></h3><ul><li>Released support for installing npm packages on <a href="https://snack.expo.io" target="_blank" rel="noopener noreferrer">Snack</a>. Usual Expo restrictions apply -- packages can't depend on custom native APIs that aren't already included in Expo. We are also working on supporting multiple files and uploading assets in Snack. <a href="https://github.com/satya164" target="_blank" rel="noopener noreferrer">Satyajit</a> will talk about Snack at <a href="https://react-native.eu/" target="_blank" rel="noopener noreferrer">React Native Europe</a>.</li><li>Released SDK20 with camera, payments, secure storage, magnetometer, pause/resume fs downloads, and improved splash/loading screen.</li><li>Continuing to work with <a href="https://github.com/kmagiera" target="_blank" rel="noopener noreferrer">Krzysztof</a> on <a href="https://github.com/kmagiera/react-native-gesture-handler" target="_blank" rel="noopener noreferrer">react-native-gesture-handler</a>. Please give it a try, rebuild some gesture that you have previously built using PanResponder or native gesture recognizers and let us know what issues you encounter.</li><li>Experimenting with JSC debugging protocol, working on a bunch of feature requests on <a href="https://expo.canny.io/feature-requests" target="_blank" rel="noopener noreferrer">Canny</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="facebook">Facebook<a class="hash-link" href="#facebook" title="Direct link to heading">​</a></h3><ul><li>Last month we discussed management of the GitHub issue tracker and that we would try to make improvements to address the maintainability of the project.</li><li>Currently, the number of open issues is holding steady at around 600, and it seems like it may stay that way for a while. In the past month, we have closed 690 issues due to lack of activity (defined as no comments in the last 60 days). Out of those 690 issues, 58 were re-opened for a variety of reasons (a maintainer committed to providing a fix, or a contributor made a great case for keeping the issue open).</li><li>We plan to continue with the automated closing of stale issues for the foreseeable future. We’d like to be in a state where every impactful issue opened in the tracker is acted upon, but we’re not there yet. We need all the help we can from maintainers to triage issues and make sure we don't miss issues that introduce regressions or introduce breaking changes, especially those that affect newly created projects. People interested in helping out can use the Facebook GitHub Bot to triage issues and pull requests. The new Maintainers Guide contains more information on triage and use of the GitHub Bot. Please add yourself to the <a href="https://github.com/facebook/react-native/blob/master/bots/IssueCommands.txt" target="_blank" rel="noopener noreferrer">issue task force</a> and encourage other active community members to do the same!</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="microsoft">Microsoft<a class="hash-link" href="#microsoft" title="Direct link to heading">​</a></h3><ul><li>The new Skype app is built on top of React Native in order to facilitate sharing as much code between platforms as possible. The React Native-based Skype app is currently available in the Android and iOS app stores.</li><li>While building the Skype app on React Native, we send pull requests to React Native in order to address bugs and missing features that we come across. So far, we've gotten about <a href="https://github.com/facebook/react-native/pulls?utf8=%E2%9C%93&amp;q=is%3Apr%20author%3Arigdern%20" target="_blank" rel="noopener noreferrer">70 pull requests merged</a>.</li><li>React Native enabled us to power both the Android and iOS Skype apps from the same codebase. We also want to use that codebase to power the Skype web app. To help us achieve that goal, we built and open sourced a thin layer on top of React/React Native called <a href="https://microsoft.github.io/reactxp/blog/2017/04/06/introducing-reactxp.html" target="_blank" rel="noopener noreferrer">ReactXP</a>. ReactXP provides a set of cross platform components that get mapped to React Native when targeting iOS/Android and to react-dom when targeting the web. ReactXP's goals are similar to another open source library called React Native for Web. There's a brief description of how the approaches of these libraries differ in the <a href="https://microsoft.github.io/reactxp/docs/faq.html" target="_blank" rel="noopener noreferrer">ReactXP FAQ</a>.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="shoutem">Shoutem<a class="hash-link" href="#shoutem" title="Direct link to heading">​</a></h3><ul><li>We are continuing our efforts on improving and simplifying the developer experience when building apps using <a href="https://shoutem.github.io/" target="_blank" rel="noopener noreferrer">Shoutem</a>.</li><li>Started migrating all our apps to react-navigation, but we ended postponing this until a more stable version is released, or one of the native navigation solutions becomes stable.</li><li>Updating all our <a href="https://github.com/shoutem/extensions" target="_blank" rel="noopener noreferrer">extensions</a> and most of our open source libraries (<a href="https://github.com/shoutem/animation" target="_blank" rel="noopener noreferrer">animation</a>, <a href="https://github.com/shoutem/theme" target="_blank" rel="noopener noreferrer">theme</a>, <a href="https://github.com/shoutem/ui" target="_blank" rel="noopener noreferrer">ui</a>) to React Native 0.47.1.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-session">Next session<a class="hash-link" href="#next-session" title="Direct link to heading">​</a></h2><p>The next session is scheduled for Wednesday 13, September 2017. As this was only our third meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me <a href="https://twitter.com/grabbou" target="_blank" rel="noopener noreferrer">on Twitter</a> if you have any suggestion on how we should improve the output of the meeting.</p>]]></content>
        <author>
            <name>Mike Grabowski</name>
            <uri>https://github.com/grabbou</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Performance in Marketplace]]></title>
        <id>/2017/08/07/react-native-performance-in-marketplace</id>
        <link href="https://reactnative.dev/blog/2017/08/07/react-native-performance-in-marketplace"/>
        <updated>2017-08-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[React Native is used in multiple places across multiple apps in the Facebook family including a top level tab in the main Facebook apps. Our focus for this post is a highly visible product, Marketplace. It is available in a dozen or so countries and enables users to discover products and services provided by other users.]]></summary>
        <content type="html"><![CDATA[<p>React Native is used in multiple places across multiple apps in the Facebook family including a top level tab in the main Facebook apps. Our focus for this post is a highly visible product, <a href="https://newsroom.fb.com/news/2016/10/introducing-marketplace-buy-and-sell-with-your-local-community/" target="_blank" rel="noopener noreferrer">Marketplace</a>. It is available in a dozen or so countries and enables users to discover products and services provided by other users.</p><p>In the first half of 2017, through the joint effort of the Relay Team, the Marketplace team, the Mobile JS Platform team, and the React Native team, we cut Marketplace Time to Interaction (TTI) in half for Android <a href="https://code.facebook.com/posts/307478339448736/year-class-a-classification-system-for-android/" target="_blank" rel="noopener noreferrer">Year Class 2010-11 devices</a>. Facebook has historically considered these devices as low-end Android devices, and they have the slowest TTIs on any platform or device type.</p><p>A typical React Native startup looks something like this:</p><p><img loading="lazy" src="/assets/images/RNPerformanceStartup-1fd20cca7c74d0ee7a15fe9e8199610f.png" width="2444" height="271" class="img_SS3x"></p><blockquote><p>Disclaimer: ratios aren't representative and will vary depending on how React Native is configured and used.</p></blockquote><p>We first initialize the React Native core (aka the “Bridge”) before running the product specific JavaScript which determines what native views React Native will render in the Native Processing Time.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="a-different-approach">A different approach<a class="hash-link" href="#a-different-approach" title="Direct link to heading">​</a></h3><p>One of the earlier mistakes that we made was to let <a href="https://code.facebook.com/posts/747457662026706/performance-instrumentation-for-android-apps/" target="_blank" rel="noopener noreferrer">Systrace and CTScan</a> drive our performance efforts. These tools helped us find a lot of low-hanging fruit in 2016, but we discovered that both Systrace and CTScan are <strong>not representative of production scenarios</strong> and cannot emulate what happens in the wild. Ratios of time spent in the breakdowns are often incorrect and, wildly off-base at times. At the extreme, some things that we expected to take a few milliseconds actually take hundreds or thousands of milliseconds. That said, CTScan is useful and we've found it catches a third of regressions before they hit production.</p><p>On Android, we attribute the shortcomings of these tools to the fact that 1) React Native is a multithreaded framework, 2) Marketplace is co-located with a multitude of complex views such as Newsfeed and other top-level tabs, and 3) computation times vary wildly. Thus, this half, we let production measurements and breakdowns drive almost all of our decision making and prioritization.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="down-the-path-of-production-instrumentation">Down the path of production instrumentation<a class="hash-link" href="#down-the-path-of-production-instrumentation" title="Direct link to heading">​</a></h3><p>Instrumenting production may sound simple on the surface, but it turned out to be quite a complex process. It took multiple iteration cycles of 2-3 weeks each; due to the latency of landing a commit in master, to pushing the app to the Play Store, to gathering sufficient production samples to have confidence in our work. Each iteration cycle involved discovering if our breakdowns were accurate, if they had the right level of granularity, and if they properly added up to the whole time span. We could not rely on alpha and beta releases because they are not representative of the general population. In essence, we very tediously built a very accurate production trace based on the aggregate of millions of samples.</p><p>One of the reasons we meticulously verified that every millisecond in breakdowns properly added up to their parent metrics was that we realized early on there were gaps in our instrumentation. It turned out that our initial breakdowns did not account for stalls caused by thread jumps. Thread jumps themselves aren't expensive, but thread jumps to busy threads already doing work are very expensive. We eventually reproduced these blockages locally by sprinkling <code>Thread.sleep()</code> calls at the right moments, and we managed to fix them by:</p><ol><li>removing our dependency on AsyncTask,</li><li>undoing the forced initialization of ReactContext and NativeModules on the UI thread, and</li><li>removing the dependency on measuring the ReactRootView at initialization time.</li></ol><p>Together, removing these thread blockage issues reduced the startup time by over 25%.</p><p>Production metrics also challenged some of our prior assumptions. For example, we used to pre-load many JavaScript modules on the startup path under the assumption that co-locating modules in one bundle would reduce their initialization cost. However, the cost of pre-loading and co-locating these modules far outweighed the benefits. By re-configuring our inline require blacklists and removing JavaScript modules from the startup path, we were able to avoid loading unnecessary modules such as Relay Classic (when only <a href="https://relay.dev/docs/new-in-relay-modern" target="_blank" rel="noopener noreferrer">Relay Modern</a> was necessary). Today, our <code>RUN_JS_BUNDLE</code> breakdown is over 75% faster.</p><p>We also found wins by investigating product-specific native modules. For example, by lazily injecting a native module's dependencies, we reduced that native module's cost by 98%. By removing the contention of Marketplace startup with other products, we reduced startup by an equivalent interval.</p><p>The best part is that many of these improvements are broadly applicable to all screens built with React Native.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="conclusion">Conclusion<a class="hash-link" href="#conclusion" title="Direct link to heading">​</a></h2><p>People assume that React Native startup performance problems are caused by JavaScript being slow or exceedingly high network times. While speeding up things like JavaScript would bring down TTI by a non-trivial sum, each of these contribute a much smaller percentage of TTI than was previously believed.</p><p>The lesson so far has been to <em>measure, measure, measure!</em> Some wins come from moving run-time costs to build time, such as Relay Modern and <a href="https://github.com/facebook/react-native/commit/797ca6c219b2a44f88f10c61d91e8cc21e2f306e" target="_blank" rel="noopener noreferrer">Lazy NativeModules</a>. Other wins come from avoiding work by being smarter about parallelizing code or removing dead code. And some wins come from large architectural changes to React Native, such as cleaning up thread blockages. There is no grand solution to performance, and longer-term performance wins will come from incremental instrumentation and improvements. Do not let cognitive bias influence your decisions. Instead, carefully gather and interpret production data to guide future work.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="future-plans">Future plans<a class="hash-link" href="#future-plans" title="Direct link to heading">​</a></h2><p>In the long term, we want Marketplace TTI to be comparable to similar products built with Native, and, in general, have React Native performance on par with native performance. Further more, although this half we drastically reduced the bridge startup cost by about 80%, we plan to bring the cost of the React Native bridge close to zero via projects like <a href="https://prepack.io/" target="_blank" rel="noopener noreferrer">Prepack</a> and more build time processing.</p>]]></content>
        <author>
            <name>Aaron Chiu</name>
            <uri>https://www.facebook.com/aaronechiu</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Monthly #2]]></title>
        <id>/2017/07/28/react-native-monthly-2</id>
        <link href="https://reactnative.dev/blog/2017/07/28/react-native-monthly-2"/>
        <updated>2017-07-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The React Native monthly meeting continues! On this session, we were joined by Infinite Red, great minds behind Chain React, the React Native Conference. As most of the people here were presenting talks at Chain React, we pushed the meeting to a week later. Talks from the conference have been posted online and I encourage you to check them out. So, let's see what our teams are up to.]]></summary>
        <content type="html"><![CDATA[<p>The React Native monthly meeting continues! On this session, we were joined by <a href="https://infinite.red/" target="_blank" rel="noopener noreferrer">Infinite Red</a>, great minds behind <a href="https://infinite.red/ChainReactConf" target="_blank" rel="noopener noreferrer">Chain React, the React Native Conference</a>. As most of the people here were presenting talks at Chain React, we pushed the meeting to a week later. Talks from the conference have been <a href="https://www.youtube.com/playlist?list=PLFHvL21g9bk3RxJ1Ut5nR_uTZFVOxu522" target="_blank" rel="noopener noreferrer">posted online</a> and I encourage you to check them out. So, let's see what our teams are up to.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="teams">Teams<a class="hash-link" href="#teams" title="Direct link to heading">​</a></h2><p>On this second meeting, we had 9 teams join us:</p><ul><li><a href="https://github.com/airbnb" target="_blank" rel="noopener noreferrer">Airbnb</a></li><li><a href="https://github.com/callstack-io" target="_blank" rel="noopener noreferrer">Callstack</a></li><li><a href="https://github.com/expo" target="_blank" rel="noopener noreferrer">Expo</a></li><li><a href="https://github.com/facebook" target="_blank" rel="noopener noreferrer">Facebook</a></li><li><a href="https://github.com/GeekyAnts" target="_blank" rel="noopener noreferrer">GeekyAnts</a></li><li><a href="https://github.com/infinitered" target="_blank" rel="noopener noreferrer">Infinite Red</a></li><li><a href="https://github.com/microsoft" target="_blank" rel="noopener noreferrer">Microsoft</a></li><li><a href="https://github.com/shoutem" target="_blank" rel="noopener noreferrer">Shoutem</a></li><li><a href="https://github.com/wix" target="_blank" rel="noopener noreferrer">Wix</a></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="notes">Notes<a class="hash-link" href="#notes" title="Direct link to heading">​</a></h2><p>Here are the notes from each team:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="airbnb">Airbnb<a class="hash-link" href="#airbnb" title="Direct link to heading">​</a></h3><ul><li>Check out the <a href="https://github.com/airbnb" target="_blank" rel="noopener noreferrer">Airbnb repository</a> for React Native related projects.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="callstack">Callstack<a class="hash-link" href="#callstack" title="Direct link to heading">​</a></h3><ul><li><a href="https://github.com/grabbou" target="_blank" rel="noopener noreferrer">Mike Grabowski</a> has been managing React Native's monthly releases as always, including a few betas that were pushed out. In particular, working on getting a v0.43.5 build published to npm since it unblocks Windows users!</li><li>Slow but consistent work is happening on <a href="https://github.com/callstack-io/haul" target="_blank" rel="noopener noreferrer">Haul</a>. There is a pull request that adds HMR, and other improvements have shipped. Recently got a few industry leaders to adopt it. Possibly planning to start a full-time paid work in that area.</li><li><a href="https://twitter.com/thymikee" target="_blank" rel="noopener noreferrer">Michał Pierzchała</a> from the <a href="https://github.com/facebook/jest" target="_blank" rel="noopener noreferrer">Jest</a> team has joined us at Callstack this month. He will help maintain <a href="https://github.com/callstack-io/haul" target="_blank" rel="noopener noreferrer">Haul</a> and possibly work on <a href="https://github.com/facebook/metro" target="_blank" rel="noopener noreferrer">Metro Bundler</a> and <a href="https://github.com/facebook/jest" target="_blank" rel="noopener noreferrer">Jest</a>.</li><li><a href="https://twitter.com/satya164" target="_blank" rel="noopener noreferrer">Satyajit Sahoo</a> is now with us, yay!</li><li>Got a bunch of cool stuff coming up from our OSS department. In particular, working on bringing Material Palette API to React Native. Planning to finally release our native iOS kit which is aimed to provide 1:1 look &amp; feel of native components.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="expo">Expo<a class="hash-link" href="#expo" title="Direct link to heading">​</a></h3><ul><li>Recently launched <a href="https://native.directory" target="_blank" rel="noopener noreferrer">Native Directory</a> to help with discoverability and evaluation of libraries in React Native ecosystem. The problem: lots of libraries, hard to test, need to manually apply heuristics and not immediately obvious which ones are just the best ones that you should use. It's also hard to know if something is compatible with CRNA/Expo. So Native Directory tries to solve these problems. Check it out and <a href="https://github.com/react-community/native-directory" target="_blank" rel="noopener noreferrer">add your library</a> to it. The list of libraries is in <a href="https://github.com/react-community/native-directory/blob/master/react-native-libraries.json" target="_blank" rel="noopener noreferrer">here</a>. This is just our first pass of it, and we want this to be owned and run by the community, not just Expo folks. So please pitch in if you think this is valuable and want to make it better!</li><li>Added initial support for installing npm packages in <a href="https://snack.expo.io/" target="_blank" rel="noopener noreferrer">Snack</a> with Expo SDK 19. Let us know if you run into any issues with it, we are still working through some bugs. Along with Native Directory, this should make it easy to test libraries that have only JS dependencies, or dependencies included in <a href="https://github.com/expo/expo-sdk" target="_blank" rel="noopener noreferrer">Expo SDK</a>. Try it out:<ul><li><a href="https://snack.expo.io/ByBCD_2r-" target="_blank" rel="noopener noreferrer">react-native-modal</a></li><li><a href="https://snack.expo.io/SJfJguhrW" target="_blank" rel="noopener noreferrer">react-native-animatable</a></li><li><a href="https://snack.expo.io/HkoXUdhr-" target="_blank" rel="noopener noreferrer">react-native-calendars</a></li></ul></li><li><a href="https://blog.expo.io/expo-sdk-v19-0-0-is-now-available-821a62b58d3d" target="_blank" rel="noopener noreferrer">Released Expo SDK19</a> with a bunch of improvements across the board, and we're now using the <a href="https://github.com/SoftwareMansion/jsc-android-buildscripts" target="_blank" rel="noopener noreferrer">updated Android JSC</a>.</li><li>Working on a guide in docs with <a href="https://github.com/frantic" target="_blank" rel="noopener noreferrer">Alexander Kotliarskyi</a> with a list of tips on how to improve the user experience of your app. Please join in and add to the list or help write some of it!<ul><li>Issue: <a href="https://github.com/facebook/react-native/issues/14979" target="_blank" rel="noopener noreferrer">#14979</a></li><li>Initial pull request: <a href="https://github.com/facebook/react-native/pull/14993" target="_blank" rel="noopener noreferrer">#14993</a></li></ul></li><li>Continuing to work on: audio/video, camera, gestures (with Software Mansion, <code>react-native-gesture-handler</code>), GL camera integration and hoping to land some of these for the first time in SDK20 (August), and significant improvements to others by then as well. We're just getting started on building infrastructure into the Expo client for background work (geolocation, audio, handling notifications, etc.).</li><li><a href="https://twitter.com/skevy" target="_blank" rel="noopener noreferrer">Adam Miskiewicz</a> has made some nice progress on imitating the transitions from <a href="https://developer.apple.com/documentation/uikit/uinavigationcontroller" target="_blank" rel="noopener noreferrer">UINavigationController</a> in <a href="https://github.com/react-community/react-navigation" target="_blank" rel="noopener noreferrer">react-navigation</a>. Check out an earlier version of it in <a href="https://twitter.com/skevy/status/884932473070735361" target="_blank" rel="noopener noreferrer">his tweet</a> - release coming with it soon. Also check out <code>MaskedViewIOS</code> which he <a href="https://github.com/facebook/react-native/commit/8ea6cea39a3db6171dd74838a6eea4631cf42bba" target="_blank" rel="noopener noreferrer">upstreamed</a>. If you have the skills and desire to implement <code>MaskedView</code> for Android that would be awesome!</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="facebook">Facebook<a class="hash-link" href="#facebook" title="Direct link to heading">​</a></h3><ul><li>Facebook is internally exploring being able to embed native <a href="http://componentkit.org/" target="_blank" rel="noopener noreferrer">ComponentKit</a> and <a href="https://fblitho.com/" target="_blank" rel="noopener noreferrer">Litho</a> components inside of React Native.</li><li>Contributions to React Native are very welcome! If you are wondering how you can contribute, the <a href="https://github.com/facebook/react-native-website/blob/master/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer">"How to Contribute" guide</a> describes our development process and lays out the steps to send your first pull request. There are other ways to contribute that do not require writing code, such as by triaging issues or updating the docs.<ul><li>At the time of writing, React Native has <strong>635</strong> <a href="https://github.com/facebook/react-native/issues" target="_blank" rel="noopener noreferrer">open issues</a> and <strong>249</strong> <a href="https://github.com/facebook/react-native/pulls" target="_blank" rel="noopener noreferrer">open pull requests</a>. This is overwhelming for our maintainers, and when things get fixed internally, it is difficult to ensure the relevant tasks are updated.</li><li>We are unsure what the best approach is to handle this while keeping the community satisfied. Some (but not all!) options include closing stale issues, giving significantly more people permissions to manage issues, and automatically closing issues that do not follow the issue template. We wrote a "What to Expect from Maintainers" guide to set expectations and avoid surprises. If you have ideas on how we can make this experience better for maintainers as well as ensuring people opening issues and pull requests feel heard and valued, please let us know!</li></ul></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="geekyants">GeekyAnts<a class="hash-link" href="#geekyants" title="Direct link to heading">​</a></h3><ul><li>We demoed the Designer Tool which works with React Native files on Chain React. Many attendees signed up for the waiting list.</li><li>We are also looking at other cross-platform solutions like <a href="https://flutter.io/" target="_blank" rel="noopener noreferrer">Google Flutter</a> (a major comparison coming along), <a href="https://github.com/JetBrains/kotlin-native" target="_blank" rel="noopener noreferrer">Kotlin Native</a>, and <a href="https://weex.incubator.apache.org/" target="_blank" rel="noopener noreferrer">Apache Weex</a> to understand the architectural differences and what we can learn from them to improve the overall performance of React Native.</li><li>Switched to <a href="https://github.com/react-community/react-navigation" target="_blank" rel="noopener noreferrer">react-navigation</a> for most of our apps, which has improved the overall performance.</li><li>Also, announced <a href="https://market.nativebase.io/" target="_blank" rel="noopener noreferrer">NativeBase Market</a> - A marketplace for React Native components and apps (for and by the developers).</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="infinite-red">Infinite Red<a class="hash-link" href="#infinite-red" title="Direct link to heading">​</a></h3><ul><li>We want to introduce the <a href="https://github.com/infinitered/reactotron" target="_blank" rel="noopener noreferrer">Reactotron</a>. Check out the <a href="https://www.youtube.com/watch?v=tPBRfxswDjA" target="_blank" rel="noopener noreferrer">introductory video</a>. We'll be adding more features very soon!</li><li>Organised Chain React Conference. It was awesome, thanks all for coming! <a href="https://www.youtube.com/playlist?list=PLFHvL21g9bk3RxJ1Ut5nR_uTZFVOxu522" target="_blank" rel="noopener noreferrer">The videos are now online!</a></li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="microsoft">Microsoft<a class="hash-link" href="#microsoft" title="Direct link to heading">​</a></h3><ul><li><a href="https://github.com/Microsoft/code-push" target="_blank" rel="noopener noreferrer">CodePush</a> has now been integrated into <a href="https://mobile.azure.com/" target="_blank" rel="noopener noreferrer">Mobile Center</a>. Existing users will have no change in their workflow.<ul><li>Some people have reported an issue with duplicate apps - they already had an app on Mobile Center. We are working on resolving them, but if you have two apps, let us know, and we can merge them for you.</li></ul></li><li>Mobile Center now supports Push Notifications for CodePush. We also showed how a combination of Notifications and CodePush could be used for A/B testing apps - something unique to the ReactNative architecture.</li><li><a href="https://github.com/Microsoft/vscode" target="_blank" rel="noopener noreferrer">VS Code</a> has a known debugging issue with ReactNative - the next release of the extension in a couple of days will be fixing the issue.</li><li>Since there are many other teams also working on React Native inside Microsoft, we will work on getting better representation from all the groups for the next meeting.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="shoutem">Shoutem<a class="hash-link" href="#shoutem" title="Direct link to heading">​</a></h3><ul><li>Finished the process of making the React Native development easier on <a href="https://shoutem.github.io/" target="_blank" rel="noopener noreferrer">Shoutem</a>. You can use all the standard <code>react-native</code> commands when developing apps on Shoutem.</li><li>We did a lot of work trying to figure out how to best approach the profiling on React Native. A big chunk of <a href="/docs/performance">documentation</a> is outdated, and we'll do our best to create a pull request on the official docs or at least write some of our conclusions in a blog post.</li><li>Switching our navigation solution to <a href="https://github.com/react-community/react-navigation" target="_blank" rel="noopener noreferrer">react-navigation</a>, so we might have some feedback soon.</li><li>We released <a href="https://github.com/shoutem/ui/tree/develop/html" target="_blank" rel="noopener noreferrer">a new HTML component</a> in our toolkit which transforms the raw HTML to the React Native components tree.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="wix">Wix<a class="hash-link" href="#wix" title="Direct link to heading">​</a></h3><ul><li>We started working on a pull request to <a href="https://github.com/facebook/metro" target="_blank" rel="noopener noreferrer">Metro Bundler</a> with <a href="https://github.com/wix/react-native-repackager" target="_blank" rel="noopener noreferrer">react-native-repackager</a> capabilities. We updated react-native-repackager to support RN 44 (which we use in production). We are using it for our mocking infrastructure for <a href="https://github.com/wix/detox" target="_blank" rel="noopener noreferrer">detox</a>.</li><li>We have been covering the Wix app in detox tests for the last three weeks. It's an amazing learning experience of how to reduce manual QA in an app of this scale (over 40 engineers). We have resolved several issues with detox as a result, a new version was just published. I am happy to report that we are living up to the "zero flakiness policy" and the tests are passing consistently so far.</li><li>Detox for Android is moving forward nicely. We are getting significant help from the community. We are expecting an initial version in about two weeks.</li><li><a href="https://github.com/wix/detoxinstruments" target="_blank" rel="noopener noreferrer">DetoxInstruments</a>, our performance testing tool, is getting a little bigger than we originally intended. We are now planning to turn it into a standalone tool that will not be tightly coupled to detox. It will allow investigating the performance of iOS apps in general. It will also be integrated with detox so we can run automated tests on performance metrics.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-session">Next session<a class="hash-link" href="#next-session" title="Direct link to heading">​</a></h2><p>The next session is scheduled for August 16, 2017. As this was only our second meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me <a href="https://twitter.com/TomislavTenodi" target="_blank" rel="noopener noreferrer">on Twitter</a> if you have any suggestion on how we should improve the output of the meeting.</p>]]></content>
        <author>
            <name>Tomislav Tenodi</name>
            <uri>https://github.com/tenodi</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native Monthly #1]]></title>
        <id>/2017/06/21/react-native-monthly-1</id>
        <link href="https://reactnative.dev/blog/2017/06/21/react-native-monthly-1"/>
        <updated>2017-06-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[At Shoutem, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.]]></summary>
        <content type="html"><![CDATA[<p>At <a href="https://shoutem.github.io/" target="_blank" rel="noopener noreferrer">Shoutem</a>, we've been fortunate enough to work with React Native from its very beginnings. We decided we wanted to be part of the amazing community from day one. Soon enough, we realized it's almost impossible to keep up with the pace the community was growing and improving. That's why we decided to organize a monthly meeting where all major React Native contributors can briefly present what their efforts and plans are.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="monthly-meetings">Monthly meetings<a class="hash-link" href="#monthly-meetings" title="Direct link to heading">​</a></h2><p>We had our first session of the monthly meeting on June 14, 2017. The mission for React Native Monthly is simple and straightforward: <strong>improve the React Native community</strong>. Presenting teams' efforts eases collaboration between teams done offline.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="teams">Teams<a class="hash-link" href="#teams" title="Direct link to heading">​</a></h2><p>On the first meeting, we had 8 teams join us:</p><ul><li><a href="https://github.com/airbnb" target="_blank" rel="noopener noreferrer">Airbnb</a></li><li><a href="https://github.com/callstack-io" target="_blank" rel="noopener noreferrer">Callstack</a></li><li><a href="https://github.com/expo" target="_blank" rel="noopener noreferrer">Expo</a></li><li><a href="https://github.com/facebook" target="_blank" rel="noopener noreferrer">Facebook</a></li><li><a href="https://github.com/GeekyAnts" target="_blank" rel="noopener noreferrer">GeekyAnts</a></li><li><a href="https://github.com/microsoft" target="_blank" rel="noopener noreferrer">Microsoft</a></li><li><a href="https://github.com/shoutem" target="_blank" rel="noopener noreferrer">Shoutem</a></li><li><a href="https://github.com/wix" target="_blank" rel="noopener noreferrer">Wix</a></li></ul><p>We hope to have more core contributors join the upcoming sessions!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="notes">Notes<a class="hash-link" href="#notes" title="Direct link to heading">​</a></h2><p>As teams' plans might be of interest to a broader audience, we'll be sharing them here, on the React Native blog. So, here they are:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="airbnb">Airbnb<a class="hash-link" href="#airbnb" title="Direct link to heading">​</a></h3><ul><li>Plans to add some A11y (accessibility) APIs to <code>View</code> and the <code>AccessibilityInfo</code> native module.</li><li>Will be investigating adding some APIs to native modules on Android to allow for specifying threads for them to run on.</li><li>Have been investigating potential initialization performance improvements.</li><li>Have been investigating some more sophisticated bundling strategies to use on top of "unbundle".</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="callstack">Callstack<a class="hash-link" href="#callstack" title="Direct link to heading">​</a></h3><ul><li>Looking into improving the release process by using <a href="https://github.com/wix/detox" target="_blank" rel="noopener noreferrer">Detox</a> for E2E testing. Pull request should land soon.</li><li>Blob pull request they have been working on has been merged, subsequent pull requests coming up.</li><li>Increasing <a href="https://github.com/callstack-io/haul" target="_blank" rel="noopener noreferrer">Haul</a> adoption across internal projects to see how it performs compared to <a href="http://github.com/facebook/metro-bundler" target="_blank" rel="noopener noreferrer">Metro Bundler</a>. Working on better multi-threaded performance with the Webpack team.</li><li>Internally, they have implemented a better infrastructure to manage open source projects. Plans to be getting more stuff out in upcoming weeks.</li><li>The React Native Europe conference is coming along, nothing interesting yet, but y'all invited!</li><li>Stepped back from <a href="https://github.com/react-community/react-navigation" target="_blank" rel="noopener noreferrer">react-navigation</a> for a while to investigate alternatives (especially native navigations).</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="expo">Expo<a class="hash-link" href="#expo" title="Direct link to heading">​</a></h3><ul><li>Working on making it possible to install npm modules in <a href="https://snack.expo.io/" target="_blank" rel="noopener noreferrer">Snack</a>, will be useful for libraries to add examples to documentation.</li><li>Working with <a href="https://github.com/kmagiera" target="_blank" rel="noopener noreferrer">Krzysztof</a> and other people at <a href="https://github.com/software-mansion" target="_blank" rel="noopener noreferrer">Software Mansion</a> on a JSC update on Android and a gesture handling library.</li><li><a href="https://github.com/skevy" target="_blank" rel="noopener noreferrer">Adam Miskiewicz</a> is transitioning his focus towards <a href="https://github.com/react-community/react-navigation" target="_blank" rel="noopener noreferrer">react-navigation</a>.</li><li><a href="https://github.com/react-community/create-react-native-app" target="_blank" rel="noopener noreferrer">Create React Native App</a> is in the <a href="/docs/getting-started">Getting Started guide</a> in the docs. Expo wants to encourage library authors to explain clearly whether their lib works with CRNA or not, and if so, explain how to set it up.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="facebook">Facebook<a class="hash-link" href="#facebook" title="Direct link to heading">​</a></h3><ul><li>React Native's packager is now <a href="https://github.com/facebook/metro" target="_blank" rel="noopener noreferrer">Metro Bundler</a>, in an independent repo. The Metro Bundler team in London is excited to address the needs of the community, improve modularity for additional use-cases beyond React Native, and increase responsiveness on issues and PRs.</li><li>In the coming months, the React Native team will work on refining the APIs of primitive components. Expect improvements in layout quirks, accessibility, and flow typing.</li><li>The React Native team also plans on improving core modularity this year, by refactoring to fully support 3rd party platforms such as Windows and macOS.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="geekyants">GeekyAnts<a class="hash-link" href="#geekyants" title="Direct link to heading">​</a></h3><ul><li>The team is working on a UI/UX design app (codename: Builder) which directly works with <code>.js</code> files. Right now, it supports only React Native. It’s similar to Adobe XD and Sketch.</li><li>The team is working hard so that you can load up an existing React Native app in the editor, make changes (visually, as a designer) and save the changes directly to the JS file.</li><li>Folks are trying to bridge the gap between Designers and Developers and bring them on the same repo.</li><li>Also, <a href="https://github.com/GeekyAnts/NativeBase" target="_blank" rel="noopener noreferrer">NativeBase</a> recently reached 5,000 GitHub stars.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="microsoft">Microsoft<a class="hash-link" href="#microsoft" title="Direct link to heading">​</a></h3><ul><li><a href="https://github.com/Microsoft/code-push" target="_blank" rel="noopener noreferrer">CodePush</a> has now been integrated into <a href="https://mobile.azure.com/" target="_blank" rel="noopener noreferrer">Mobile Center</a>. This is the first step in providing a much more integrated experience with distribution, analytics and other services. See their announcement <a href="https://microsoft.github.io/code-push/articles/CodePushOnMobileCenter.html" target="_blank" rel="noopener noreferrer">here</a>.</li><li><a href="https://github.com/Microsoft/vscode" target="_blank" rel="noopener noreferrer">VS Code</a> has a bug with debugging, they are working on fixing that right now and will have a new build.</li><li>Investigating <a href="https://github.com/wix/detox" target="_blank" rel="noopener noreferrer">Detox</a> for Integration testing, looking at JSC Context to get variables alongside crash reports.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="shoutem">Shoutem<a class="hash-link" href="#shoutem" title="Direct link to heading">​</a></h3><ul><li>Making it easier to work on Shoutem apps with tools from the React Native community. You will be able to use all the React Native commands to run the apps created on <a href="https://shoutem.github.io/" target="_blank" rel="noopener noreferrer">Shoutem</a>.</li><li>Investigating profiling tools for React Native. They had a lot of problems setting it up and they will write some of the insights they discovered along the way.</li><li>Shoutem is working on making it easier to integrate React Native with existing native apps. They will document the concept that they developed internally in the company, in order to get the feedback from the community.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="wix">Wix<a class="hash-link" href="#wix" title="Direct link to heading">​</a></h3><ul><li>Working internally to adopt <a href="https://github.com/wix/detox" target="_blank" rel="noopener noreferrer">Detox</a> to move significant parts of the Wix app to "zero manual QA". As a result, Detox is being used heavily in a production setting by dozens of developers and maturing rapidly.</li><li>Working to add support to the <a href="https://github.com/facebook/metro" target="_blank" rel="noopener noreferrer">Metro Bundler</a> for overriding any file extension during the build. Instead of just "ios" and "android", it would support any custom extension like "e2e" or "detox". Plans to use this for E2E mocking. There's already a library out called <a href="https://github.com/wix/react-native-repackager" target="_blank" rel="noopener noreferrer">react-native-repackager</a>, now working on a PR.</li><li>Investigating automation of performance tests. This is a new repo called <a href="https://github.com/wix/DetoxInstruments" target="_blank" rel="noopener noreferrer">DetoxInstruments</a>. You can take a look, it's being developed open source.</li><li>Working with a contributor from KPN on Detox for Android and supporting real devices.</li><li>Thinking about "Detox as a platform" to allow building other tools that need to automate the simulator/device. An example is <a href="https://github.com/storybooks/react-native-storybook" target="_blank" rel="noopener noreferrer">Storybook</a> for React Native or Ram's idea for integration testing.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="next-session">Next session<a class="hash-link" href="#next-session" title="Direct link to heading">​</a></h2><p>Meetings will be held every four weeks. The next session is scheduled for July 12, 2017. As we just started with this meeting, we'd like to know how do these notes benefit the React Native community. Feel free to ping me <a href="https://twitter.com/TomislavTenodi" target="_blank" rel="noopener noreferrer">on Twitter</a> if you have any suggestion on what we should cover in the following sessions, or how we should improve the output of the meeting.</p>]]></content>
        <author>
            <name>Tomislav Tenodi</name>
            <uri>https://github.com/tenodi</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Better List Views in React Native]]></title>
        <id>/2017/03/13/better-list-views</id>
        <link href="https://reactnative.dev/blog/2017/03/13/better-list-views"/>
        <updated>2017-03-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Many of you have started playing with some of our new List components already after our teaser announcement in the community group, but we are officially announcing them today! No more ListViews or DataSources, stale rows, ignored bugs, or excessive memory consumption - with the latest React Native March 2017 release candidate (0.43-rc.1) you can pick from the new suite of components what best fits your use-case, with great perf and feature sets out of the box:]]></summary>
        <content type="html"><![CDATA[<p>Many of you have started playing with some of our new List components already after our <a href="https://www.facebook.com/groups/react.native.community/permalink/921378591331053" target="_blank" rel="noopener noreferrer">teaser announcement in the community group</a>, but we are officially announcing them today! No more <code>ListView</code>s or <code>DataSource</code>s, stale rows, ignored bugs, or excessive memory consumption - with the latest React Native March 2017 release candidate (<code>0.43-rc.1</code>) you can pick from the new suite of components what best fits your use-case, with great perf and feature sets out of the box:</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="flatlist"><a href="/docs/flatlist"><code>&lt;FlatList&gt;</code></a><a class="hash-link" href="#flatlist" title="Direct link to heading">​</a></h3><p>This is the workhorse component for simple, performant lists. Provide an array of data and a <code>renderItem</code> function and you're good to go:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">FlatList</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">data</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">title</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript string" style="color:#8dc891">'Title Text'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">key</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript string" style="color:#8dc891">'item1'</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">renderItem</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript parameter" style="color:#fc929e">item</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">ListItem</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">title</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">item</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript tag script language-javascript property-access" style="color:#fc929e">title</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">/&gt;</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e"></span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_JmGV" id="sectionlist"><a href="/docs/sectionlist"><code>&lt;SectionList&gt;</code></a><a class="hash-link" href="#sectionlist" title="Direct link to heading">​</a></h3><p>If you want to render a set of data broken into logical sections, maybe with section headers (e.g. in an alphabetical address book), and potentially with heterogeneous data and rendering (such as a profile view with some buttons followed by a composer, then a photo grid, then a friend grid, and finally a list of stories), this is the way to go.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">SectionList</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">renderItem</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript parameter" style="color:#fc929e">item</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">ListItem</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">title</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">item</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript tag script language-javascript property-access" style="color:#fc929e">title</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">/&gt;</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">renderSectionHeader</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript parameter" style="color:#fc929e">section</span><span class="token tag script language-javascript parameter punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">&lt;</span><span class="token tag script language-javascript tag class-name" style="color:#fac863">H1</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag attr-name" style="color:#c5a5c5">title</span><span class="token tag script language-javascript tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript tag script language-javascript" style="color:#fc929e">section</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript tag script language-javascript property-access" style="color:#fc929e">key</span><span class="token tag script language-javascript tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript tag" style="color:#fc929e"> </span><span class="token tag script language-javascript tag punctuation" style="color:#657b83">/&gt;</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">sections</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript comment" style="color:#93a1a1">// homogeneous rendering between sections</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">data</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">key</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">data</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">key</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">data</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">key</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">  </span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e"></span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">SectionList</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">sections</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript comment" style="color:#93a1a1">// heterogeneous rendering between sections</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">data</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">key</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">renderItem</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">data</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">key</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">renderItem</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">    </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">data</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">key</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">renderItem</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">  </span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e"></span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_JmGV" id="virtualizedlist"><a href="/docs/virtualizedlist"><code>&lt;VirtualizedList&gt;</code></a><a class="hash-link" href="#virtualizedlist" title="Direct link to heading">​</a></h3><p>The implementation behind the scenes with a more flexible API. Especially handy if your data is not in a plain array (e.g. an immutable list).</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="features">Features<a class="hash-link" href="#features" title="Direct link to heading">​</a></h2><p>Lists are used in many contexts, so we packed the new components full of features to handle the majority of use cases out of the box:</p><ul><li>Scroll loading (<code>onEndReached</code>).</li><li>Pull to refresh (<code>onRefresh</code> / <code>refreshing</code>).</li><li><a href="https://github.com/facebook/react-native/blob/master/Libraries/CustomComponents/Lists/ViewabilityHelper.js" target="_blank" rel="noopener noreferrer">Configurable</a> viewability (VPV) callbacks (<code>onViewableItemsChanged</code> / <code>viewabilityConfig</code>).</li><li>Horizontal mode (<code>horizontal</code>).</li><li>Intelligent item and section separators.</li><li>Multi-column support (<code>numColumns</code>)</li><li><code>scrollToEnd</code>, <code>scrollToIndex</code>, and <code>scrollToItem</code></li><li>Better Flow typing.</li></ul><h3 class="anchor anchorWithStickyNavbar_JmGV" id="some-caveats">Some Caveats<a class="hash-link" href="#some-caveats" title="Direct link to heading">​</a></h3><ul><li><p>The internal state of item subtrees is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.</p></li><li><p>These components are based on <code>PureComponent</code> which means that they will not re-render if <code>props</code> remains shallow-equal. Make sure that everything your <code>renderItem</code> function depends on directly is passed as a prop that is not <code>===</code> after updates, otherwise your UI may not update on changes. This includes the <code>data</code> prop and parent component state. For example:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">FlatList</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  data</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">data</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  renderItem</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter punctuation" style="color:#657b83">{</span><span class="token parameter">item</span><span class="token parameter punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">MyItem</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">      </span><span class="token tag attr-name" style="color:#c5a5c5">item</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">item</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">      </span><span class="token tag attr-name" style="color:#c5a5c5">onPress</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">        </span><span class="token tag script language-javascript keyword" style="color:#c5a5c5">this</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript method function property-access" style="color:#79b6f2">setState</span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript parameter" style="color:#fc929e">oldState</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript arrow operator" style="color:#fc929e">=&gt;</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">(</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">          </span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">selected</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">            </span><span class="token tag script language-javascript comment" style="color:#93a1a1">// New instance breaks `===`</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">            </span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript" style="color:#fc929e">oldState</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">selected</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript comment" style="color:#93a1a1">// copy old data</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">            </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e">item</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">key</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript operator" style="color:#fc929e">!</span><span class="token tag script language-javascript" style="color:#fc929e">oldState</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">selected</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e">item</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">key</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript comment" style="color:#93a1a1">// toggle</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">          </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">,</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">        </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript punctuation" style="color:#657b83">)</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">      </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">      </span><span class="token tag attr-name" style="color:#c5a5c5">selected</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">        </span><span class="token tag script language-javascript operator" style="color:#fc929e">!</span><span class="token tag script language-javascript operator" style="color:#fc929e">!</span><span class="token tag script language-javascript keyword" style="color:#c5a5c5">this</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">state</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">selected</span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript" style="color:#fc929e">item</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">key</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript comment" style="color:#93a1a1">// renderItem depends on state</span><span class="token tag script language-javascript" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag script language-javascript" style="color:#fc929e">      </span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">    </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  selected</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token comment" style="color:#93a1a1">// Can be any prop that doesn't collide with existing props</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">selected</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// A change to selected should re-render FlatList</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">/</span><span class="token operator" style="color:#fc929e">&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li><li><p>In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate and momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.</p></li><li><p>By default, these new lists look for a <code>key</code> prop on each item and use that for the React key. Alternatively, you can provide a custom <code>keyExtractor</code> prop.</p></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="performance">Performance<a class="hash-link" href="#performance" title="Direct link to heading">​</a></h2><p>Besides simplifying the API, the new list components also have significant performance enhancements, the main one being nearly constant memory usage for any number of rows. This is done by 'virtualizing' elements that are outside of the render window by completely unmounting them from the component hierarchy and reclaiming the JS memory from the react components, along with the native memory from the shadow tree and the UI views. This has a catch which is that internal component state will not be preserved, so <strong>make sure you track any important state outside of the components themselves, e.g. in Relay or Redux or Flux store.</strong></p><p>Limiting the render window also reduces the amount of work that needs to be done by React and the native platform, e.g from view traversals. Even if you are rendering the last of a million elements, with these new lists there is no need to iterate through all those elements in order to render. You can even jump to the middle with <code>scrollToIndex</code> without excessive rendering.</p><p>We've also made some improvements with scheduling which should help with application responsiveness. Items at the edge of the render window are rendered infrequently and at a lower priority after any active gestures or animations or other interactions have completed.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="advanced-usage">Advanced Usage<a class="hash-link" href="#advanced-usage" title="Direct link to heading">​</a></h2><p>Unlike <code>ListView</code>, all items in the render window are re-rendered any time any props change. Often this is fine because the windowing reduces the number of items to a constant number, but if your items are on the complex side, you should make sure to follow React best practices for performance and use <code>React.PureComponent</code> and/or <code>shouldComponentUpdate</code> as appropriate within your components to limit re-renders of the recursive subtree.</p><p>If you can calculate the height of your rows without rendering them, you can improve the user experience by providing the <code>getItemLayout</code> prop. This makes it much smoother to scroll to specific items with e.g. <code>scrollToIndex</code>, and will improve the scroll indicator UI because the height of the content can be determined without rendering it.</p><p>If you have an alternative data type, like an immutable list, <code>&lt;VirtualizedList&gt;</code> is the way to go. It takes a <code>getItem</code> prop that lets you return the item data for any given index and has looser flow typing.</p><p>There are also a bunch of parameters you can tweak if you have an unusual use case. For example, you can use <code>windowSize</code> to trade off memory usage vs. user experience, <code>maxToRenderPerBatch</code> to adjust fill rate vs. responsiveness, <code>onEndReachedThreshold</code> to control when scroll loading happens, and more.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="future-work">Future Work<a class="hash-link" href="#future-work" title="Direct link to heading">​</a></h2><ul><li>Migration of existing surfaces (ultimately deprecation of <code>ListView</code>).</li><li>More features as we see/hear the need (let us know!).</li><li>Sticky section header support.</li><li>More performance optimizations.</li><li>Support functional item components with state.</li></ul>]]></content>
        <author>
            <name>Spencer Ahrens</name>
            <uri>https://github.com/sahrens</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[idx: The Existential Function]]></title>
        <id>/2017/03/13/idx-the-existential-function</id>
        <link href="https://reactnative.dev/blog/2017/03/13/idx-the-existential-function"/>
        <updated>2017-03-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[At Facebook, we often need to access deeply nested values in data structures fetched with GraphQL. On the way to accessing these deeply nested values, it is common for one or more intermediate fields to be nullable. These intermediate fields may be null for a variety of reasons, from failed privacy checks to the mere fact that null happens to be the most flexible way to represent non-fatal errors.]]></summary>
        <content type="html"><![CDATA[<p>At Facebook, we often need to access deeply nested values in data structures fetched with GraphQL. On the way to accessing these deeply nested values, it is common for one or more intermediate fields to be nullable. These intermediate fields may be null for a variety of reasons, from failed privacy checks to the mere fact that null happens to be the most flexible way to represent non-fatal errors.</p><p>Unfortunately, accessing these deeply nested values is currently tedious and verbose.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">&amp;&amp;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">&amp;&amp;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">]</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">&amp;&amp;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>There is <a href="https://github.com/claudepache/es-optional-chaining" target="_blank" rel="noopener noreferrer">an ECMAScript proposal to introduce the existential operator</a> which will make this much more convenient. But until a time when that proposal is finalized, we want a solution that improves our quality of life, maintains existing language semantics, and encourages type safety with Flow.</p><p>We came up with an existential <em>function</em> we call <code>idx</code>.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token function" style="color:#79b6f2">idx</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">props</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token parameter">_</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> _</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The invocation in this code snippet behaves similarly to the boolean expression in the code snippet above, except with significantly less repetition. The <code>idx</code> function takes exactly two arguments:</p><ul><li>Any value, typically an object or array into which you want to access a nested value.</li><li>A function that receives the first argument and accesses a nested value on it.</li></ul><p>In theory, the <code>idx</code> function will try-catch errors that are the result of accessing properties on null or undefined. If such an error is caught, it will return either null or undefined. (And you can see how this might be implemented in <a href="https://github.com/facebookincubator/idx/blob/master/packages/idx/src/idx.js" target="_blank" rel="noopener noreferrer">idx.js</a>.)</p><p>In practice, try-catching every nested property access is slow, and differentiating between specific kinds of TypeErrors is fragile. To deal with these shortcomings, we created a Babel plugin that transforms the above <code>idx</code> invocation into the following expression:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">==</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#c5a5c5">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">?</span><span class="token plain"> props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">==</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#c5a5c5">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">?</span><span class="token plain"> props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">]</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">==</span><span class="token plain"> </span><span class="token keyword null nil" style="color:#c5a5c5">null</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">?</span><span class="token plain"> props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> props</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">user</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">friends</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Finally, we added a custom Flow type declaration for <code>idx</code> that allows the traversal in the second argument to be properly type-checked while permitting nested access on nullable properties.</p><p>The function, Babel plugin, and Flow declaration are now <a href="https://github.com/facebookincubator/idx" target="_blank" rel="noopener noreferrer">available on GitHub</a>. They are used by installing the <strong>idx</strong> and <strong>babel-plugin-idx</strong> npm packages, and adding “idx” to the list of plugins in your <code>.babelrc</code> file.</p>]]></content>
        <author>
            <name>Timothy Yung</name>
            <uri>https://github.com/yungsters</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Create React Native App]]></title>
        <id>/2017/03/13/introducing-create-react-native-app</id>
        <link href="https://reactnative.dev/blog/2017/03/13/introducing-create-react-native-app"/>
        <updated>2017-03-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we’re announcing Create React Native App: a new tool that makes it significantly easier to get started with a React Native project! It’s heavily inspired by the design of Create React App and is the product of a collaboration between Facebook and Expo (formerly Exponent).]]></summary>
        <content type="html"><![CDATA[<p>Today we’re announcing <a href="https://github.com/react-community/create-react-native-app" target="_blank" rel="noopener noreferrer">Create React Native App</a>: a new tool that makes it significantly easier to get started with a React Native project! It’s heavily inspired by the design of <a href="https://github.com/facebookincubator/create-react-app" target="_blank" rel="noopener noreferrer">Create React App</a> and is the product of a collaboration between <a href="https://code.facebook.com" target="_blank" rel="noopener noreferrer">Facebook</a> and <a href="https://expo.io" target="_blank" rel="noopener noreferrer">Expo</a> (formerly Exponent).</p><p>Many developers struggle with installing and configuring React Native’s current native build dependencies, especially for Android. With Create React Native App, there’s no need to use Xcode or Android Studio, and you can develop for your iOS device using Linux or Windows. This is accomplished using the Expo app, which loads and runs CRNA projects written in pure JavaScript without compiling any native code.</p><p>Try creating a new project (replace with suitable yarn commands if you have it installed):</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ npm i -g create-react-native-app</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ create-react-native-app my-project</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ cd my-project</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ npm start</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This will start the React Native packager and print a QR code. Open it in the <a href="https://expo.io" target="_blank" rel="noopener noreferrer">Expo app</a> to load your JavaScript. Calls to <code>console.log</code> are forwarded to your terminal. You can make use of any standard React Native APIs as well as the <a href="https://docs.expo.dev/versions/latest/" target="_blank" rel="noopener noreferrer">Expo SDK</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="what-about-native-code">What about native code?<a class="hash-link" href="#what-about-native-code" title="Direct link to heading">​</a></h2><p>Many React Native projects have Java or Objective-C/Swift dependencies that need to be compiled. The Expo app does include APIs for camera, video, contacts, and more, and bundles popular libraries like <a href="https://docs.expo.dev/versions/latest/sdk/map-view/" target="_blank" rel="noopener noreferrer">Airbnb’s react-native-maps</a>, or <a href="https://docs.expo.dev/versions/latest/sdk/facebook/" target="_blank" rel="noopener noreferrer">Facebook authentication</a>. However if you need a native code dependency that Expo doesn’t bundle then you’ll probably need to have your own build configuration for it. Just like Create React App, “ejecting” is supported by CRNA.</p><p>You can run <code>npm run eject</code> to get a project very similar to what <code>react-native init</code> would generate. At that point you’ll need Xcode and/or Android Studio just as you would if you started with <code>react-native init</code> , adding libraries with <code>react-native link</code> will work, and you’ll have full control over the native code compilation process.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="questions-feedback">Questions? Feedback?<a class="hash-link" href="#questions-feedback" title="Direct link to heading">​</a></h2><p>Create React Native App is now stable enough for general use, which means we’re very eager to hear about your experience using it! You can find me <a href="https://twitter.com/dika10sune" target="_blank" rel="noopener noreferrer">on Twitter</a> or open an issue on <a href="https://github.com/react-community/create-react-native-app" target="_blank" rel="noopener noreferrer">the GitHub repository</a>. Pull requests are very welcome!</p>]]></content>
        <author>
            <name>Adam Perry</name>
            <uri>https://github.com/dikaiosune</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Using Native Driver for Animated]]></title>
        <id>/2017/02/14/using-native-driver-for-animated</id>
        <link href="https://reactnative.dev/blog/2017/02/14/using-native-driver-for-animated"/>
        <updated>2017-02-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[For the past year, we've been working on improving performance of animations that use the Animated library. Animations are very important to create a beautiful user experience but can also be hard to do right. We want to make it easy for developers to create performant animations without having to worry about some of their code causing it to lag.]]></summary>
        <content type="html"><![CDATA[<p>For the past year, we've been working on improving performance of animations that use the Animated library. Animations are very important to create a beautiful user experience but can also be hard to do right. We want to make it easy for developers to create performant animations without having to worry about some of their code causing it to lag.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="what-is-this">What is this?<a class="hash-link" href="#what-is-this" title="Direct link to heading">​</a></h2><p>The Animated API was designed with a very important constraint in mind, it is serializable. This means we can send everything about the animation to native before it has even started and allows native code to perform the animation on the UI thread without having to go through the bridge on every frame. It is very useful because once the animation has started, the JS thread can be blocked and the animation will still run smoothly. In practice this can happen a lot because user code runs on the JS thread and React renders can also lock JS for a long time.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="a-bit-of-history">A bit of history...<a class="hash-link" href="#a-bit-of-history" title="Direct link to heading">​</a></h2><p>This project started about a year ago, when Expo built the li.st app on Android. <a href="https://twitter.com/kzzzf" target="_blank" rel="noopener noreferrer">Krzysztof Magiera</a> was contracted to build the initial implementation on Android. It ended up working well and li.st was the first app to ship with native driven animations using Animated. A few months later, <a href="https://github.com/buba447" target="_blank" rel="noopener noreferrer">Brandon Withrow</a> built the initial implementation on iOS. After that, <a href="https://twitter.com/ryangomba" target="_blank" rel="noopener noreferrer">Ryan Gomba</a> and myself worked on adding missing features like support for <code>Animated.event</code> as well as squash bugs we found when using it in production apps. This was truly a community effort and I would like to thanks everyone that was involved as well as Expo for sponsoring a large part of the development. It is now used by <code>Touchable</code> components in React Native as well as for navigation animations in the newly released <a href="https://github.com/react-community/react-navigation" target="_blank" rel="noopener noreferrer">React Navigation</a> library.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="how-does-it-work">How does it work?<a class="hash-link" href="#how-does-it-work" title="Direct link to heading">​</a></h2><p>First, let's check out how animations currently work using Animated with the JS driver. When using Animated, you declare a graph of nodes that represent the animations that you want to perform, and then use a driver to update an Animated value using a predefined curve. You may also update an Animated value by connecting it to an event of a <code>View</code> using <code>Animated.event</code>.</p><p><img loading="lazy" src="/assets/images/animated-diagram-127161e299f43a8c0e677715d6be7881.png" width="782" height="216" class="img_SS3x"></p><p>Here's a breakdown of the steps for an animation and where it happens:</p><ul><li>JS: The animation driver uses <code>requestAnimationFrame</code> to execute on every frame and update the value it drives using the new value it calculates based on the animation curve.</li><li>JS: Intermediate values are calculated and passed to a props node that is attached to a <code>View</code>.</li><li>JS: The <code>View</code> is updated using <code>setNativeProps</code>.</li><li>JS to Native bridge.</li><li>Native: The <code>UIView</code> or <code>android.View</code> is updated.</li></ul><p>As you can see, most of the work happens on the JS thread. If it is blocked the animation will skip frames. It also needs to go through the JS to Native bridge on every frame to update native views.</p><p>What the native driver does is move all of these steps to native. Since Animated produces a graph of animated nodes, it can be serialized and sent to native only once when the animation starts, eliminating the need to callback into the JS thread; the native code can take care of updating the views directly on the UI thread on every frame.</p><p>Here's an example of how we can serialize an animated value and an interpolation node (not the exact implementation, just an example).</p><p>Create the native value node, this is the value that will be animated:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">NativeAnimatedModule</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">createNode</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">id</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">type</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'value'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">initialValue</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Create the native interpolation node, this tells the native driver how to interpolate a value:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">NativeAnimatedModule</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">createNode</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">id</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">2</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">type</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'interpolation'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">inputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">10</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">outputRange</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">10</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">extrapolate</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'clamp'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Create the native props node, this tells the native driver which prop on the view it is attached to:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">NativeAnimatedModule</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">createNode</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">id</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">3</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">type</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'props'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">properties</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token string" style="color:#8dc891">'style.opacity'</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Connect nodes together:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">NativeAnimatedModule</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">connectNodes</span><span class="token punctuation" style="color:#657b83">(</span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">2</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">NativeAnimatedModule</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">connectNodes</span><span class="token punctuation" style="color:#657b83">(</span><span class="token number" style="color:#5a9bcf">2</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">3</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Connect the props node to a view:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">NativeAnimatedModule</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">connectToView</span><span class="token punctuation" style="color:#657b83">(</span><span class="token number" style="color:#5a9bcf">3</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token maybe-class-name">ReactNative</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">findNodeHandle</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">viewRef</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>With that, the native animated module has all the info it needs to update the native views directly without having to go to JS to calculate any value.</p><p>All there is left to do is actually start the animation by specifying what type of animation curve we want and what animated value to update. Timing animations can also be simplified by calculating every frame of the animation in advance in JS to make the native implementation smaller.</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">NativeAnimatedModule</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">startAnimation</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">type</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'timing'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">frames</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token number" style="color:#5a9bcf">0</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0.1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0.2</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0.4</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">0.65</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token spread operator" style="color:#fc929e">...</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">animatedValueId</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>And now here's the breakdown of what happens when the animation runs:</p><ul><li>Native: The native animation driver uses <code>CADisplayLink</code> or <code>android.view.Choreographer</code> to execute on every frame and update the value it drives using the new value it calculates based on the animation curve.</li><li>Native: Intermediate values are calculated and passed to a props node that is attached to a native view.</li><li>Native: The <code>UIView</code> or <code>android.View</code> is updated.</li></ul><p>As you can see, no more JS thread and no more bridge which means faster animations! 🎉🎉</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="how-do-i-use-this-in-my-app">How do I use this in my app?<a class="hash-link" href="#how-do-i-use-this-in-my-app" title="Direct link to heading">​</a></h2><p>For normal animations the answer is simple, just add <code>useNativeDriver: true</code> to the animation config when starting it.</p><p>Before:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">timing</span><span class="token punctuation" style="color:#657b83">(</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">animatedValue</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">toValue</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">duration</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">500</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">start</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>After:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">timing</span><span class="token punctuation" style="color:#657b83">(</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">animatedValue</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">toValue</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">duration</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">500</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">useNativeDriver</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// &lt;-- Add this</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">start</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Animated values are only compatible with one driver so if you use native driver when starting an animation on a value, make sure every animation on that value also uses the native driver.</p><p>It also works with <code>Animated.event</code>, this is very useful if you have an animation that must follow the scroll position because without the native driver it will always run a frame behind of the gesture because of the async nature of React Native.</p><p>Before:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">ScrollView</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  scrollEventThrottle</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token number" style="color:#5a9bcf">16</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  onScroll</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">event</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">[</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">nativeEvent</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">contentOffset</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">y</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">animatedValue</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">content</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">ScrollView</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>After:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access maybe-class-name">ScrollView</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// &lt;-- Use the Animated ScrollView wrapper</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  scrollEventThrottle</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// &lt;-- Use 1 here to make sure no events are ever missed</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  onScroll</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">event</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">[</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">nativeEvent</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">contentOffset</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">y</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">animatedValue</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#2aa198">useNativeDriver</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// &lt;-- Add this</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">content</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag class-name" style="color:#fac863">Animated.ScrollView</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="caveats">Caveats<a class="hash-link" href="#caveats" title="Direct link to heading">​</a></h2><p>Not everything you can do with Animated is currently supported in Native Animated. The main limitation is that you can only animate non-layout properties, things like <code>transform</code> and <code>opacity</code> will work but Flexbox and position properties won't. Another one is with <code>Animated.event</code>, it will only work with direct events and not bubbling events. This means it does not work with <code>PanResponder</code> but does work with things like <code>ScrollView#onScroll</code>.</p><p>Native Animated has also been part of React Native for quite a while but has never been documented because it was considered experimental. Because of that make sure you are using a recent version (0.40+) of React Native if you want to use this feature.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="resources">Resources<a class="hash-link" href="#resources" title="Direct link to heading">​</a></h2><p>For more information about animated I recommend watching <a href="https://www.youtube.com/watch?v=xtqUJVqpKNo" target="_blank" rel="noopener noreferrer">this talk</a> by <a href="https://twitter.com/Vjeux" target="_blank" rel="noopener noreferrer">Christopher Chedeau</a>.</p><p>If you want a deep dive into animations and how offloading them to native can improve user experience there is also <a href="https://www.youtube.com/watch?v=qgSMjYWqBk4" target="_blank" rel="noopener noreferrer">this talk</a> by <a href="https://twitter.com/kzzzf" target="_blank" rel="noopener noreferrer">Krzysztof Magiera</a>.</p>]]></content>
        <author>
            <name>Janic Duplessis</name>
            <uri>https://twitter.com/janicduplessis</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[A Monthly Release Cadence: Releasing December and January RC]]></title>
        <id>/2017/01/07/monthly-release-cadence</id>
        <link href="https://reactnative.dev/blog/2017/01/07/monthly-release-cadence"/>
        <updated>2017-01-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Shortly after React Native was introduced, we started releasing every two weeks to help the community adopt new features, while keeping versions stable for production use. At Facebook we had to stabilize the codebase every two weeks for the release of our production iOS apps, so we decided to release the open source versions at the same pace. Now, many of the Facebook apps ship once per week, especially on Android. Because we ship from master weekly, we need to keep it quite stable. So the bi-weekly release cadence doesn't even benefit internal contributors anymore.]]></summary>
        <content type="html"><![CDATA[<p>Shortly after React Native was introduced, we started releasing every two weeks to help the community adopt new features, while keeping versions stable for production use. At Facebook we had to stabilize the codebase every two weeks for the release of our production iOS apps, so we decided to release the open source versions at the same pace. Now, many of the Facebook apps ship once per week, especially on Android. Because we ship from master weekly, we need to keep it quite stable. So the bi-weekly release cadence doesn't even benefit internal contributors anymore.</p><p>We frequently hear feedback from the community that the release rate is hard to keep up with. Tools like <a href="https://expo.io/" target="_blank" rel="noopener noreferrer">Expo</a> had to skip every other release in order to manage the rapid change in version. So it seems clear that the bi-weekly releases did not serve the community well.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="now-releasing-monthly">Now releasing monthly<a class="hash-link" href="#now-releasing-monthly" title="Direct link to heading">​</a></h3><p>We're happy to announce the new monthly release cadence, and the December 2016 release, <code>v0.40</code>, which has been stabilizing for all last month and is ready to adopt. (Just make sure to <a href="https://github.com/facebook/react-native/releases/tag/v0.40.0" target="_blank" rel="noopener noreferrer">update headers in your native modules on iOS</a>).</p><p>Although it may vary a few days to avoid weekends or handle unforeseen issues, you can now expect a given release to be available on the first day of the month, and released on the last.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="use-the-current-month-for-the-best-support">Use the current month for the best support<a class="hash-link" href="#use-the-current-month-for-the-best-support" title="Direct link to heading">​</a></h3><p>The January release candidate is ready to try, and you can <a href="https://github.com/facebook/react-native/releases/tag/v0.41.0-rc.0" target="_blank" rel="noopener noreferrer">see what's new here</a>.</p><p>To see what changes are coming and provide better feedback to React Native contributors, always use the current month's release candidate when possible. By the time each version is released at the end of the month, the changes it contains will have been shipped in production Facebook apps for over two weeks.</p><p>You can easily upgrade your app with the new <a href="/blog/2016/12/05/easier-upgrades">react-native-git-upgrade</a> command:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">npm install </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">g react</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">native</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">git</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">upgrade</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">react</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">native</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">git</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">upgrade </span><span class="token number" style="color:#5a9bcf">0.41</span><span class="token number" style="color:#5a9bcf">.0</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">rc</span><span class="token punctuation" style="color:#657b83">.</span><span class="token number" style="color:#5a9bcf">0</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We hope this simpler approach will make it easier for the community to keep track of changes in React Native, and to adopt new versions as quickly as possible!</p><p>(Thanks go to <a href="https://github.com/mkonicek" target="_blank" rel="noopener noreferrer">Martin Konicek</a> for coming up with this plan and <a href="https://github.com/grabbou" target="_blank" rel="noopener noreferrer">Mike Grabowski</a> for making it happen)</p>]]></content>
        <author>
            <name>Eric Vicenti</name>
            <uri>https://twitter.com/EricVicenti</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Easier Upgrades Thanks to Git]]></title>
        <id>/2016/12/05/easier-upgrades</id>
        <link href="https://reactnative.dev/blog/2016/12/05/easier-upgrades"/>
        <updated>2016-12-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Upgrading to new versions of React Native has been difficult. You might have seen something like this before:]]></summary>
        <content type="html"><![CDATA[<p>Upgrading to new versions of React Native has been difficult. You might have seen something like this before:</p><p><img loading="lazy" src="/assets/images/git-upgrade-conflict-259c34d993954d886ad788010950c320.png" width="1105" height="649" class="img_SS3x"></p><p>None of those options is ideal. By overwriting the file we lose our local changes. By not overwriting we don't get the latest updates.</p><p>Today I am proud to introduce a new tool that helps solve this problem. The tool is called <code>react-native-git-upgrade</code> and uses Git behind the scenes to resolve conflicts automatically whenever possible.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="usage">Usage<a class="hash-link" href="#usage" title="Direct link to heading">​</a></h2><blockquote><p><strong>Requirement</strong>: Git has to be available in the <code>PATH</code>. Your project doesn't have to be managed by Git.</p></blockquote><p>Install <code>react-native-git-upgrade</code> globally:</p><div class="language-shell codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-shell codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ </span><span class="token function" style="color:#79b6f2">npm</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">install</span><span class="token plain"> -g react-native-git-upgrade</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>or, using <a href="https://yarnpkg.com/" target="_blank" rel="noopener noreferrer">Yarn</a>:</p><div class="language-shell codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-shell codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ </span><span class="token function" style="color:#79b6f2">yarn</span><span class="token plain"> global </span><span class="token function" style="color:#79b6f2">add</span><span class="token plain"> react-native-git-upgrade</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Then, run it inside your project directory:</p><div class="language-shell codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-shell codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ </span><span class="token builtin class-name" style="color:#fac863">cd</span><span class="token plain"> MyProject</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ react-native-git-upgrade </span><span class="token number" style="color:#5a9bcf">0.38</span><span class="token plain">.0</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><blockquote><p>Note: Do <strong>not</strong> run 'npm install' to install a new version of <code>react-native</code>. The tool needs to be able to compare the old and new project template to work correctly. Simply run it inside your app folder as shown above, while still on the old version.</p></blockquote><p>Example output:</p><p><img loading="lazy" src="/assets/images/git-upgrade-output-411aa7509a5c0465f149d7deb8e8b4ad.png" width="1353" height="1299" class="img_SS3x"></p><p>You can also run <code>react-native-git-upgrade</code> with no arguments to upgrade to the latest version of React Native.</p><p>We try to preserve your changes in Android and iOS build files, so you don't need to run <code>react-native link</code> after an upgrade.</p><p>We have designed the implementation to be as little intrusive as possible. It is entirely based on a local Git repository created on-the-fly in a temporary directory. It won't interfere with your project repository (no matter what VCS you use: Git, SVN, Mercurial, ... or none). Your sources are restored in case of unexpected errors.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="how-does-it-work">How does it work?<a class="hash-link" href="#how-does-it-work" title="Direct link to heading">​</a></h2><p>The key step is generating a Git patch. The patch contains all the changes made in the React Native templates between the version your app is using and the new version.</p><p>To obtain this patch, we need to generate an app from the templates embedded in the <code>react-native</code> package inside your <code>node_modules</code> directory (these are the same templates the <code>react-native init</code> commands uses). Then, after the native apps have been generated from the templates in both the current version and the new version, Git is able to produce a patch that is adapted to your project (i.e. containing your app name):</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token punctuation" style="color:#657b83">[</span><span class="token spread operator" style="color:#fc929e">...</span><span class="token punctuation" style="color:#657b83">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">diff </span><span class="token operator" style="color:#fc929e">--</span><span class="token plain">git a</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">ios</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">MyAwesomeApp</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Info</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">plist</span><span class="token plain"> b</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">ios</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">MyAwesomeApp</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Info</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">plist</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">index e98ebb0</span><span class="token punctuation" style="color:#657b83">.</span><span class="token punctuation" style="color:#657b83">.</span><span class="token plain">2fb6a11 </span><span class="token number" style="color:#5a9bcf">100644</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">--</span><span class="token operator" style="color:#fc929e">-</span><span class="token plain"> a</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">ios</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">MyAwesomeApp</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Info</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">plist</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">++</span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"> b</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">ios</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">MyAwesomeApp</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Info</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">plist</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">@@ </span><span class="token operator" style="color:#fc929e">-</span><span class="token number" style="color:#5a9bcf">45</span><span class="token punctuation" style="color:#657b83">,</span><span class="token number" style="color:#5a9bcf">7</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token number" style="color:#5a9bcf">45</span><span class="token punctuation" style="color:#657b83">,</span><span class="token number" style="color:#5a9bcf">7</span><span class="token plain"> @@</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag" style="color:#fc929e">dict</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">            </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag" style="color:#fc929e">key</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text">localhost</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag" style="color:#fc929e">key</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">            </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag" style="color:#fc929e">dict</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">-               </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag" style="color:#fc929e">key</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text">NSTemporaryExceptionAllowsInsecureHTTPLoads</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag" style="color:#fc929e">key</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">+               </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag" style="color:#fc929e">key</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text">NSExceptionAllowsInsecureHTTPLoads</span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag" style="color:#fc929e">key</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">                </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag" style="color:#fc929e">true</span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">            </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag" style="color:#fc929e">dict</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:#657b83">&lt;/</span><span class="token tag" style="color:#fc929e">dict</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">[</span><span class="token spread operator" style="color:#fc929e">...</span><span class="token punctuation" style="color:#657b83">]</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>All we need now is to apply this patch to your source files. While the old <code>react-native upgrade</code> process would have prompted you for any small difference, Git is able to merge most of the changes automatically using its 3-way merge algorithm and eventually leave us with familiar conflict delimiters:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">        13B07F951A680F5B00A75B9A </span><span class="token comment" style="color:#93a1a1">/* Release */</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            isa </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token maybe-class-name">XCBuildConfiguration</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">            buildSettings </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                </span><span class="token constant" style="color:#5a9bcf">ASSETCATALOG_COMPILER_APPICON_NAME</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token maybe-class-name">AppIcon</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">&lt;&lt;</span><span class="token operator" style="color:#fc929e">&lt;&lt;</span><span class="token operator" style="color:#fc929e">&lt;&lt;</span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token plain"> ours</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                </span><span class="token constant" style="color:#5a9bcf">CODE_SIGN_IDENTITY</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">"iPhone Developer"</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                </span><span class="token constant" style="color:#5a9bcf">FRAMEWORK_SEARCH_PATHS</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                    </span><span class="token string" style="color:#8dc891">"$(inherited)"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                    </span><span class="token string" style="color:#8dc891">"$(PROJECT_DIR)/HockeySDK.embeddedframework"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                    </span><span class="token string" style="color:#8dc891">"$(PROJECT_DIR)/HockeySDK-iOS/HockeySDK.embeddedframework"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">===</span><span class="token operator" style="color:#fc929e">===</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                </span><span class="token constant" style="color:#5a9bcf">CURRENT_PROJECT_VERSION</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">&gt;&gt;&gt;</span><span class="token operator" style="color:#fc929e">&gt;&gt;&gt;</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> theirs</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                </span><span class="token constant" style="color:#5a9bcf">HEADER_SEARCH_PATHS</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                    </span><span class="token string" style="color:#8dc891">"$(inherited)"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                    </span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Applications</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Xcode</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">app</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Contents</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Developer</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Toolchains</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">XcodeDefault</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">xctoolchain</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">usr</span><span class="token operator" style="color:#fc929e">/</span><span class="token plain">include</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                    </span><span class="token string" style="color:#8dc891">"$(SRCROOT)/../node_modules/react-native/React/**"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                    </span><span class="token string" style="color:#8dc891">"$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**"</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">                </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>These conflicts are generally easy to reason about. The delimiter <strong>ours</strong> stands for "your team" whereas <strong>theirs</strong> could be seen as "the React Native team".</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="why-introduce-a-new-global-package">Why introduce a new global package?<a class="hash-link" href="#why-introduce-a-new-global-package" title="Direct link to heading">​</a></h2><p>React Native comes with a global CLI (the <a href="https://www.npmjs.com/package/react-native-cli" target="_blank" rel="noopener noreferrer">react-native-cli</a> package) which delegates commands to the local CLI embedded in the <code>node_modules/react-native/local-cli</code> directory.</p><p>As we mentioned above, the process has to be started from your current React Native version. If we had embedded the implementation in the local-cli, you wouldn't be able to enjoy this feature when using old versions of React Native. For example, you wouldn't be able to upgrade from 0.29.2 to 0.38.0 if this new upgrade code was only released in 0.38.0.</p><p>Upgrading based on Git is a big improvement in developer experience and it is important to make it available to everyone. By using a separate package <a href="https://www.npmjs.com/package/react-native-git-upgrade" target="_blank" rel="noopener noreferrer">react-native-git-upgrade</a> installed globally you can use this new code today no matter what version of React Native your project is using.</p><p>One more reason is the recent <a href="https://twitter.com/martinkonicek/status/800730190141857793" target="_blank" rel="noopener noreferrer">Yeoman wipeout</a> by Martin Konicek. We didn't want to get these Yeoman dependencies back into the <code>react-native</code> package to be able to evaluate the old template in order to create the patch.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="try-it-out-and-provide-feedback">Try it out and provide feedback<a class="hash-link" href="#try-it-out-and-provide-feedback" title="Direct link to heading">​</a></h2><p>As a conclusion, I would say, enjoy the feature and feel free <a href="https://github.com/facebook/react-native/issues" target="_blank" rel="noopener noreferrer">to suggest improvements, report issues</a> and especially <a href="https://github.com/facebook/react-native/pulls" target="_blank" rel="noopener noreferrer">send pull requests</a>. Each environment is a bit different and each React Native project is different, and we need your feedback to make this work well for everyone.</p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="thank-you">Thank you!<a class="hash-link" href="#thank-you" title="Direct link to heading">​</a></h3><p>I would like to thank the awesome companies <a href="http://www.zenika.com" target="_blank" rel="noopener noreferrer">Zenika</a> and <a href="http://www.groupem6.fr/le-groupe_en/activites/diversifications/m6-web.html" target="_blank" rel="noopener noreferrer">M6 Web</a> without whom none of this would have been possible!</p>]]></content>
        <author>
            <name>Nicolas Cuillery</name>
            <uri>https://twitter.com/ncuillery</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Button, Faster Installs with Yarn, and a Public Roadmap]]></title>
        <id>/2016/11/08/introducing-button-yarn-and-a-public-roadmap</id>
        <link href="https://reactnative.dev/blog/2016/11/08/introducing-button-yarn-and-a-public-roadmap"/>
        <updated>2016-11-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We have heard from many people that there is so much work happening with React Native, it can be tough to keep track of what's going on. To help communicate what work is in progress, we are now publishing a roadmap for React Native. At a high level, this work can be broken down into three priorities:]]></summary>
        <content type="html"><![CDATA[<p>We have heard from many people that there is so much work happening with React Native, it can be tough to keep track of what's going on. To help communicate what work is in progress, we are now publishing a <a href="https://github.com/facebook/react-native/wiki/Roadmap" target="_blank" rel="noopener noreferrer">roadmap for React Native</a>. At a high level, this work can be broken down into three priorities:</p><ul><li><strong>Core Libraries</strong>. Adding more functionality to the most useful components and APIs.</li><li><strong>Stability</strong>. Improve the underlying infrastructure to reduce bugs and improve code quality.</li><li><strong>Developer Experience</strong>. Help React Native developers move faster</li></ul><p>If you have suggestions for features that you think would be valuable on the roadmap, check out <a href="https://react-native.canny.io/feature-requests" target="_blank" rel="noopener noreferrer">Canny</a>, where you can suggest new features and discuss existing proposals.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="whats-new-in-react-native">What's new in React Native<a class="hash-link" href="#whats-new-in-react-native" title="Direct link to heading">​</a></h2><p><a href="https://github.com/facebook/react-native/releases/tag/v0.37.0" target="_blank" rel="noopener noreferrer">Version 0.37 of React Native</a>, released today, introduces a new core component to make it really easy to add a touchable Button to any app. We're also introducing support for the new <a href="https://yarnpkg.com/" target="_blank" rel="noopener noreferrer">Yarn</a> package manager, which should speed up the whole process of updating your app's dependencies.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="introducing-button">Introducing Button<a class="hash-link" href="#introducing-button" title="Direct link to heading">​</a></h2><p>Today we're introducing a basic <code>&lt;Button /&gt;</code> component that looks great on every platform. This addresses one of the most common pieces of feedback we get: React Native is one of the only mobile development toolkits without a button ready to use out of the box.</p><p><img loading="lazy" alt="Simple Button on Android, iOS" src="/assets/images/button-android-ios-98b790d121cd61296c5a6cb9fc07b785.png" width="1288" height="250" class="img_SS3x"></p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Button</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">onPress</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">onPressMe</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">title</span><span class="token tag attr-value punctuation attr-equals" style="color:#657b83">=</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag attr-value" style="color:#8dc891">Press Me</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">accessibilityLabel</span><span class="token tag attr-value punctuation attr-equals" style="color:#657b83">=</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag attr-value" style="color:#8dc891">Learn more about this Simple Button</span><span class="token tag attr-value punctuation" style="color:#657b83">"</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e"></span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Experienced React Native developers know how to make a button: use TouchableOpacity for the default look on iOS, TouchableNativeFeedback for the ripple effect on Android, then apply a few styles. Custom buttons aren't particularly hard to build or install, but we aim to make React Native radically easy to learn. With the addition of a basic button into core, newcomers will be able to develop something awesome in their first day, rather than spending that time formatting a Button and learning about Touchable nuances.</p><p>Button is meant to work great and look native on every platform, so it won't support all the bells and whistles that custom buttons do. It is a great starting point, but is not meant to replace all your existing buttons. To learn more, check out the <a href="/docs/button">new Button documentation</a>, complete with a runnable example!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="speed-up-react-native-init-using-yarn">Speed up <code>react-native init</code> using Yarn<a class="hash-link" href="#speed-up-react-native-init-using-yarn" title="Direct link to heading">​</a></h2><p>You can now use <a href="https://yarnpkg.com/" target="_blank" rel="noopener noreferrer">Yarn</a>, the new package manager for JavaScript, to speed up <code>react-native init</code> significantly. To see the speedup please <a href="https://yarnpkg.com/en/docs/install" target="_blank" rel="noopener noreferrer">install yarn</a> and upgrade your <code>react-native-cli</code> to 1.2.0:</p><div class="language-sh codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-sh codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ npm install -g react-native-cli</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You should now see “Using yarn” when setting up new apps:</p><p><img loading="lazy" alt="Using yarn" src="/assets/images/yarn-rncli-d93f59d7944c402a86c49acbd5b91ad5.png" width="1740" height="246" class="img_SS3x"></p><p>In simple local testing <code>react-native init</code> finished in <strong>about 1 minute on a good network</strong> (vs around 3 minutes when using npm 3.10.8). Installing yarn is optional but highly recommended.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="thank-you">Thank you!<a class="hash-link" href="#thank-you" title="Direct link to heading">​</a></h2><p>We'd like to thank everyone who contributed to this release. The full <a href="https://github.com/facebook/react-native/releases/tag/v0.37.0" target="_blank" rel="noopener noreferrer">release notes</a> are now available on GitHub. With over two dozen bug fixes and new features, React Native just keeps getting better thanks to you.</p>]]></content>
        <author>
            <name>Héctor Ramos</name>
            <uri>https://twitter.com/hectorramos</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[0.36: Headless JS, the Keyboard API, & more]]></title>
        <id>/2016/10/25/0.36-headless-js-the-keyboard-api-and-more</id>
        <link href="https://reactnative.dev/blog/2016/10/25/0.36-headless-js-the-keyboard-api-and-more"/>
        <updated>2016-10-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we are releasing React Native 0.36. Read on to learn more about what's new.]]></summary>
        <content type="html"><![CDATA[<p>Today we are releasing <a href="https://github.com/facebook/react-native/releases/tag/v0.36.0" target="_blank" rel="noopener noreferrer">React Native 0.36</a>. Read on to learn more about what's new.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="headless-js">Headless JS<a class="hash-link" href="#headless-js" title="Direct link to heading">​</a></h2><p>Headless JS is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music. It is only available on Android, for now.</p><p>To get started, define your async task in a dedicated file (e.g. <code>SomeTaskName.js</code>):</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method-variable function-variable method function property-access" style="color:#79b6f2">exports</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">async</span><span class="token plain"> </span><span class="token parameter">taskData</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token comment" style="color:#93a1a1">// Perform your task here.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Next, register your task in on <code>AppRegistry</code>:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token maybe-class-name">AppRegistry</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">registerHeadlessTask</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'SomeTaskName'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'SomeTaskName'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Using Headless JS does require some native Java code to be written in order to allow you to start up the service when needed. Take a look at our new <a href="/docs/headless-js-android">Headless JS docs</a> to learn more!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="the-keyboard-api">The Keyboard API<a class="hash-link" href="#the-keyboard-api" title="Direct link to heading">​</a></h2><p>Working with the on-screen keyboard is now easier with <a href="/docs/keyboard"><code>Keyboard</code></a>. You can now listen for native keyboard events and react to them. For example, to dismiss the active keyboard, simply call <code>Keyboard.dismiss()</code>:</p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports maybe-class-name">Keyboard</span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'react-native'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// Hide that keyboard!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">Keyboard</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">dismiss</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="animated-division">Animated Division<a class="hash-link" href="#animated-division" title="Direct link to heading">​</a></h2><p>Combining two animated values via addition, multiplication, and modulo are already supported by React Native. With version 0.36, combining two <a href="/docs/animated#divide">animated values via division</a> is now possible. There are some cases where an animated value needs to invert another animated value for calculation. An example is inverting a scale (2x --&gt; 0.5x):</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> a </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access maybe-class-name" style="color:#79b6f2">Value</span><span class="token punctuation" style="color:#657b83">(</span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> b </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">divide</span><span class="token punctuation" style="color:#657b83">(</span><span class="token number" style="color:#5a9bcf">1</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> a</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token maybe-class-name">Animated</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">spring</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">toValue</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token number" style="color:#5a9bcf">2</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">start</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><code>b</code> will then follow <code>a</code>'s spring animation and produce the value of <code>1 / a</code>.</p><p>The basic usage is like this:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Animated.View</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">transform</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">scale</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> a</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text">  </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Animated.Image</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">transform</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">scale</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> b</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Animated.View</span><span class="token tag punctuation" style="color:#657b83">&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>In this example, the inner image won't get stretched at all because the parent's scaling gets cancelled out. If you'd like to learn more, check out the <a href="/docs/animations">Animations guide</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="dark-status-bars">Dark Status Bars<a class="hash-link" href="#dark-status-bars" title="Direct link to heading">​</a></h2><p>A new <code>barStyle</code> value has been added to <code>StatusBar</code>: <code>dark-content</code>. With this addition, you can now use <a href="/docs/statusbar#barstyle"><code>barStyle</code></a> on both Android and iOS. The behavior will now be the following:</p><ul><li><code>default</code>: Use the platform default (light on iOS, dark on Android).</li><li><code>light-content</code>: Use a light status bar with black text and icons.</li><li><code>dark-content</code>: Use a dark status bar with white text and icons.</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="and-more">...and more<a class="hash-link" href="#and-more" title="Direct link to heading">​</a></h2><p>The above is just a sample of what has changed in 0.36. Check out the <a href="https://github.com/facebook/react-native/releases/tag/v0.36.0" target="_blank" rel="noopener noreferrer">release notes on GitHub</a> to see the full list of new features, bug fixes, and breaking changes.</p><p>You can upgrade to 0.36 by running the following commands in a terminal:</p><div class="language-bash codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-bash codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ </span><span class="token function" style="color:#79b6f2">npm</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">install</span><span class="token plain"> --save react-native@0.36</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">$ react-native upgrade</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content>
        <author>
            <name>Héctor Ramos</name>
            <uri>https://twitter.com/hectorramos</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Expo Talks: Adam on Unraveling Navigation]]></title>
        <id>/2016/09/08/exponent-talks-unraveling-navigation</id>
        <link href="https://reactnative.dev/blog/2016/09/08/exponent-talks-unraveling-navigation"/>
        <updated>2016-09-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Adam Miskiewicz from Expo talks about mobile navigation and the ex-navigation React Native library at Expo's office hours last week.]]></summary>
        <content type="html"><![CDATA[<p><a href="https://twitter.com/skevy" target="_blank" rel="noopener noreferrer">Adam Miskiewicz</a> from <a href="https://expo.io/" target="_blank" rel="noopener noreferrer">Expo</a> talks about mobile navigation and the <a href="https://github.com/exponent/ex-navigation" target="_blank" rel="noopener noreferrer"><code>ex-navigation</code></a> React Native library at Expo's office hours last week.</p>]]></content>
        <author>
            <name>Héctor Ramos</name>
            <uri>https://twitter.com/hectorramos</uri>
        </author>
        <category label="videos" term="videos"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Right-to-Left Layout Support For React Native Apps]]></title>
        <id>/2016/08/19/right-to-left-support-for-react-native-apps</id>
        <link href="https://reactnative.dev/blog/2016/08/19/right-to-left-support-for-react-native-apps"/>
        <updated>2016-08-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[After launching an app to the app stores, internationalization is the next step to further your audience reach. Over 20 countries and numerous people around the world use Right-to-Left (RTL) languages. Thus, making your app support RTL for them is necessary.]]></summary>
        <content type="html"><![CDATA[<p>After launching an app to the app stores, internationalization is the next step to further your audience reach. Over 20 countries and numerous people around the world use Right-to-Left (RTL) languages. Thus, making your app support RTL for them is necessary.</p><p>We're glad to announce that React Native has been improved to support RTL layouts. This is now available in the <a href="https://github.com/facebook/react-native" target="_blank" rel="noopener noreferrer">react-native</a> master branch today, and will be available in the next RC: <a href="https://github.com/facebook/react-native/releases" target="_blank" rel="noopener noreferrer"><code>v0.33.0-rc</code></a>.</p><p>This involved changing <a href="https://github.com/facebook/css-layout" target="_blank" rel="noopener noreferrer">css-layout</a>, the core layout engine used by RN, and RN core implementation, as well as specific OSS JS components to support RTL.</p><p>To battle test the RTL support in production, the latest version of the <strong>Facebook Ads Manager</strong> app (the first cross-platform 100% RN app) is now available in Arabic and Hebrew with RTL layouts for both <a href="https://itunes.apple.com/app/id964397083" target="_blank" rel="noopener noreferrer">iOS</a> and <a href="https://play.google.com/store/apps/details?id=com.facebook.adsmanager" target="_blank" rel="noopener noreferrer">Android</a>. Here is how it looks like in those RTL languages:</p><img loading="lazy" src="/blog/assets/rtl-ama-ios-arabic.png" width="280" style="margin:10px" class="img_SS3x"><img loading="lazy" src="/blog/assets/rtl-ama-android-hebrew.png" width="280" style="margin:10px" class="img_SS3x"><h2 class="anchor anchorWithStickyNavbar_JmGV" id="overview-changes-in-rn-for-rtl-support">Overview Changes in RN for RTL support<a class="hash-link" href="#overview-changes-in-rn-for-rtl-support" title="Direct link to heading">​</a></h2><p><a href="https://github.com/facebook/css-layout" target="_blank" rel="noopener noreferrer">css-layout</a> already has a concept of <code>start</code> and <code>end</code> for the layout. In the Left-to-Right (LTR) layout, <code>start</code> means <code>left</code>, and <code>end</code> means <code>right</code>. But in RTL, <code>start</code> means <code>right</code>, and <code>end</code> means <code>left</code>. This means we can make RN depend on the <code>start</code> and <code>end</code> calculation to compute the correct layout, which includes <code>position</code>, <code>padding</code>, and <code>margin</code>.</p><p>In addition, <a href="https://github.com/facebook/css-layout" target="_blank" rel="noopener noreferrer">css-layout</a> already makes each component's direction inherits from its parent. This means, we simply need to set the direction of the root component to RTL, and the entire app will flip.</p><p>The diagram below describes the changes at high level:</p><p><img loading="lazy" src="/assets/images/rtl-rn-core-updates-a7f3c54c3cd829c53a6da1d69bb8bf3c.png" width="1076" height="642" class="img_SS3x"></p><p>These include:</p><ul><li><a href="https://github.com/facebook/css-layout/commit/46c842c71a1232c3c78c4215275d104a389a9a0f" target="_blank" rel="noopener noreferrer">css-layout RTL support for absolute positioning</a></li><li>mapping <code>left</code> and <code>right</code> to <code>start</code> and <code>end</code> in RN core implementation for shadow nodes</li><li>and exposing a <a href="https://github.com/facebook/react-native/blob/f0fb228ec76ed49e6ed6d786d888e8113b8959a2/Libraries/Utilities/I18nManager.js" target="_blank" rel="noopener noreferrer">bridged utility module</a> to help control the RTL layout</li></ul><p>With this update, when you allow RTL layout for your app:</p><ul><li>every component layout will flip horizontally</li><li>some gestures and animations will automatically have RTL layout, if you are using RTL-ready OSS components</li><li>minimal additional effort may be needed to make your app fully RTL-ready</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="making-an-app-rtl-ready">Making an App RTL-ready<a class="hash-link" href="#making-an-app-rtl-ready" title="Direct link to heading">​</a></h2><ol><li><p>To support RTL, you should first add the RTL language bundles to your app.</p><ul><li>See the general guides from <a href="https://developer.apple.com/library/ios/documentation/MacOSX/Conceptual/BPInternational/LocalizingYourApp/LocalizingYourApp.html#//apple_ref/doc/uid/10000171i-CH5-SW1" target="_blank" rel="noopener noreferrer">iOS</a> and <a href="https://developer.android.com/training/basics/supporting-devices/languages.html" target="_blank" rel="noopener noreferrer">Android</a>.</li></ul></li><li><p>Allow RTL layout for your app by calling the <code>allowRTL()</code> function at the beginning of native code. We provided this utility to only apply to an RTL layout when your app is ready. Here is an example:</p><p>iOS:</p><div class="language-objc codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-objc codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// in AppDelegate.m</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token punctuation" style="color:#657b83">[</span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain">RCTI18nUtil sharedInstance</span><span class="token punctuation" style="color:#657b83">]</span><span class="token plain"> allowRTL</span><span class="token punctuation" style="color:#657b83">:</span><span class="token plain">YES</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Android:</p><div class="language-java codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-java codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// in MainActivity.java</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        </span><span class="token class-name" style="color:#fac863">I18nUtil</span><span class="token plain"> sharedI18nUtilInstance </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">I18nUtil</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">getInstance</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        sharedI18nUtilInstance</span><span class="token punctuation" style="color:#657b83">.</span><span class="token function" style="color:#79b6f2">allowRTL</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li><li><p>For Android, you need add <code>android:supportsRtl="true"</code> to the <a href="http://developer.android.com/guide/topics/manifest/application-element.html" target="_blank" rel="noopener noreferrer"><code>&lt;application&gt;</code></a> element in <code>AndroidManifest.xml</code> file.</p></li></ol><p>Now, when you recompile your app and change the device language to an RTL language (e.g. Arabic or Hebrew), your app layout should change to RTL automatically.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="writing-rtl-ready-components">Writing RTL-ready Components<a class="hash-link" href="#writing-rtl-ready-components" title="Direct link to heading">​</a></h2><p>In general, most components are already RTL-ready, for example:</p><ul><li>Left-to-Right Layout</li></ul><img loading="lazy" src="/blog/assets/rtl-demo-listitem-ltr.png" width="300" class="img_SS3x"><ul><li>Right-to-Left Layout</li></ul><img loading="lazy" src="/blog/assets/rtl-demo-listitem-rtl.png" width="300" class="img_SS3x"><p>However, there are several cases to be aware of, for which you will need the <a href="https://github.com/facebook/react-native/blob/f0fb228ec76ed49e6ed6d786d888e8113b8959a2/Libraries/Utilities/I18nManager.js" target="_blank" rel="noopener noreferrer"><code>I18nManager</code></a>. In <a href="https://github.com/facebook/react-native/blob/f0fb228ec76ed49e6ed6d786d888e8113b8959a2/Libraries/Utilities/I18nManager.js" target="_blank" rel="noopener noreferrer"><code>I18nManager</code></a>, there is a constant <code>isRTL</code> to tell if layout of app is RTL or not, so that you can make the necessary changes according to the layout.</p><h4 class="anchor anchorWithStickyNavbar_JmGV" id="icons-with-directional-meaning">Icons with Directional Meaning<a class="hash-link" href="#icons-with-directional-meaning" title="Direct link to heading">​</a></h4><p>If your component has icons or images, they will be displayed the same way in LTR and RTL layout, because RN will not flip your source image. Therefore, you should flip them according to the layout style.</p><ul><li>Left-to-Right Layout</li></ul><img loading="lazy" src="/blog/assets/rtl-demo-icon-ltr.png" width="300" class="img_SS3x"><ul><li>Right-to-Left Layout</li></ul><img loading="lazy" src="/blog/assets/rtl-demo-icon-rtl.png" width="300" class="img_SS3x"><p>Here are two ways to flip the icon according to the direction:</p><ul><li><p>Adding a <code>transform</code> style to the image component:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Image</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">source</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript spread operator" style="color:#fc929e">...</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e">  </span><span class="token tag attr-name" style="color:#c5a5c5">style</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">transform</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript punctuation" style="color:#657b83">[</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript literal-property property" style="color:#2aa198">scaleX</span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript maybe-class-name" style="color:#fc929e">I18nManager</span><span class="token tag script language-javascript punctuation" style="color:#657b83">.</span><span class="token tag script language-javascript property-access" style="color:#fc929e">isRTL</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript operator" style="color:#fc929e">?</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript operator" style="color:#fc929e">-</span><span class="token tag script language-javascript number" style="color:#5a9bcf">1</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript operator" style="color:#fc929e">:</span><span class="token tag script language-javascript" style="color:#fc929e"> </span><span class="token tag script language-javascript number" style="color:#5a9bcf">1</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">]</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token tag" style="color:#fc929e"></span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li><li><p>Or, changing the image source according to the direction:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">let</span><span class="token plain"> imageSource </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'./back.png'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword control-flow" style="color:#c5a5c5">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token maybe-class-name">I18nManager</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">isRTL</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  imageSource </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'./forward.png'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#657b83">&lt;</span><span class="token tag class-name" style="color:#fac863">Image</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag attr-name" style="color:#c5a5c5">source</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#657b83">=</span><span class="token tag script language-javascript punctuation" style="color:#657b83">{</span><span class="token tag script language-javascript" style="color:#fc929e">imageSource</span><span class="token tag script language-javascript punctuation" style="color:#657b83">}</span><span class="token tag" style="color:#fc929e"> </span><span class="token tag punctuation" style="color:#657b83">/&gt;</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li></ul><h4 class="anchor anchorWithStickyNavbar_JmGV" id="gestures-and-animations">Gestures and Animations<a class="hash-link" href="#gestures-and-animations" title="Direct link to heading">​</a></h4><p>In Android and iOS development, when you change to RTL layout, the gestures and animations are the opposite of LTR layout. Currently, in RN, gestures and animations are not supported on RN core code level, but on components level. The good news is, some of these components already support RTL today, such as <a href="https://github.com/facebook/react-native/blob/38a6eec0db85a5204e85a9a92b4dee2db9641671/Libraries/Experimental/SwipeableRow/SwipeableRow.js" target="_blank" rel="noopener noreferrer"><code>SwipeableRow</code></a> and <a href="https://github.com/facebook/react-native/tree/master/Libraries/NavigationExperimental" target="_blank" rel="noopener noreferrer"><code>NavigationExperimental</code></a>. However, other components with gestures will need to support RTL manually.</p><p>A good example to illustrate gesture RTL support is <a href="https://github.com/facebook/react-native/blob/38a6eec0db85a5204e85a9a92b4dee2db9641671/Libraries/Experimental/SwipeableRow/SwipeableRow.js" target="_blank" rel="noopener noreferrer"><code>SwipeableRow</code></a>.</p><p align="center"><img loading="lazy" src="/blog/assets/rtl-demo-swipe-ltr.png" width="280" style="margin:10px" class="img_SS3x"><img loading="lazy" src="/blog/assets/rtl-demo-swipe-rtl.png" width="280" style="margin:10px" class="img_SS3x"></p><h5 class="anchor anchorWithStickyNavbar_JmGV" id="gestures-example">Gestures Example<a class="hash-link" href="#gestures-example" title="Direct link to heading">​</a></h5><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// SwipeableRow.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token function" style="color:#79b6f2">_isSwipingExcessivelyRightFromClosedPosition</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">gestureState</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token known-class-name class-name" style="color:#fac863">Object</span><span class="token punctuation" style="color:#657b83">)</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> boolean </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token comment" style="color:#93a1a1">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> gestureStateDx </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token constant" style="color:#5a9bcf">IS_RTL</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">?</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">gestureState</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">dx</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> gestureState</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">dx</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">_isSwipingRightFromClosed</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">gestureState</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">&amp;&amp;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    gestureStateDx </span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"> </span><span class="token constant" style="color:#5a9bcf">RIGHT_SWIPE_THRESHOLD</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h5 class="anchor anchorWithStickyNavbar_JmGV" id="animation-example">Animation Example<a class="hash-link" href="#animation-example" title="Direct link to heading">​</a></h5><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// SwipeableRow.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token function" style="color:#79b6f2">_animateBounceBack</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">duration</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#657b83">)</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">void</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token comment" style="color:#93a1a1">// ...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> swipeBounceBackDistance </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token constant" style="color:#5a9bcf">IS_RTL</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">?</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token operator" style="color:#fc929e">-</span><span class="token constant" style="color:#5a9bcf">RIGHT_SWIPE_BOUNCE_BACK_DISTANCE</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token constant" style="color:#5a9bcf">RIGHT_SWIPE_BOUNCE_BACK_DISTANCE</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">_animateTo</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token operator" style="color:#fc929e">-</span><span class="token plain">swipeBounceBackDistance</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    duration</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">_animateToClosedPositionDuringBounce</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">,</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="maintaining-your-rtl-ready-app">Maintaining Your RTL-ready App<a class="hash-link" href="#maintaining-your-rtl-ready-app" title="Direct link to heading">​</a></h2><p>Even after the initial RTL-compatible app release, you will likely need to iterate on new features. To improve development efficiency, <a href="https://github.com/facebook/react-native/blob/f0fb228ec76ed49e6ed6d786d888e8113b8959a2/Libraries/Utilities/I18nManager.js" target="_blank" rel="noopener noreferrer"><code>I18nManager</code></a> provides the <code>forceRTL()</code> function for faster RTL testing without changing the test device language. You might want to provide a simple switch for this in your app. Here's an example from the RTL example in the RNTester:</p><p align="center"><img loading="lazy" src="/blog/assets/rtl-demo-forcertl.png" width="300" class="img_SS3x"></p><div class="language-js codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-js codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">RNTesterBlock</span><span class="token plain"> title</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token string" style="color:#8dc891">'Quickly Test RTL Layout'</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">View</span><span class="token plain"> style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">flexDirectionRow</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">Text</span><span class="token plain"> style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">switchRowTextView</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain">forceRTL</span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">Text</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">View</span><span class="token plain"> style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">switchRowSwitchView</span><span class="token punctuation" style="color:#657b83">}</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">Switch</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        onValueChange</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">_onDirectionChange</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        style</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain">styles</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">rightAlignStyle</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        value</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">isRTL</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token operator" style="color:#fc929e">/</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">View</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">View</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token operator" style="color:#fc929e">&lt;</span><span class="token operator" style="color:#fc929e">/</span><span class="token maybe-class-name">RNTesterBlock</span><span class="token operator" style="color:#fc929e">&gt;</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token function-variable function" style="color:#79b6f2">_onDirectionChange</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token maybe-class-name">I18nManager</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">forceRTL</span><span class="token punctuation" style="color:#657b83">(</span><span class="token operator" style="color:#fc929e">!</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">isRTL</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">setState</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">{</span><span class="token literal-property property" style="color:#2aa198">isRTL</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">!</span><span class="token keyword" style="color:#c5a5c5">this</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">state</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">isRTL</span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token maybe-class-name">Alert</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">alert</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string" style="color:#8dc891">'Reload this page'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token string" style="color:#8dc891">'Please reload this page to change the UI direction! '</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string" style="color:#8dc891">'All examples in this app will be affected. '</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">+</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token string" style="color:#8dc891">'Check them out to see what they look like in RTL layout.'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>When working on a new feature, you can easily toggle this button and reload the app to see RTL layout. The benefit is you won't need to change the language setting to test, however some text alignment won't change, as explained in the next section. Therefore, it's always a good idea to test your app in the RTL language before launching.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="limitations-and-future-plan">Limitations and Future Plan<a class="hash-link" href="#limitations-and-future-plan" title="Direct link to heading">​</a></h2><p>The RTL support should cover most of the UX in your app; however, there are some limitations for now:</p><ul><li>Text alignment behaviors differ in Android and iOS<ul><li>In iOS, the default text alignment depends on the active language bundle, they are consistently on one side. In Android, the default text alignment depends on the language of the text content, i.e. English will be left-aligned and Arabic will be right-aligned.</li><li>In theory, this should be made consistent across platform, but some people may prefer one behavior to another when using an app. More user experience research may be needed to find out the best practice for text alignment.</li></ul></li></ul><ul><li><p>There is no "true" left/right</p><p>As discussed before, we map the <code>left</code>/<code>right</code> styles from the JS side to <code>start</code>/<code>end</code>, all <code>left</code> in code for RTL layout becomes "right" on screen, and <code>right</code> in code becomes "left" on screen. This is convenient because you don't need to change your product code too much, but it means there is no way to specify "true left" or "true right" in the code. In the future, allowing a component to control its direction regardless of the language may be necessary.</p></li><li><p>Make RTL support for gestures and animations more developer friendly</p><p>Currently, there is still some programming effort required to make gestures and animations RTL compatible. In the future, it would be ideal to find a way to make gestures and animations RTL support more developer friendly.</p></li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="try-it-out">Try it Out!<a class="hash-link" href="#try-it-out" title="Direct link to heading">​</a></h2><p>Check out the <a href="https://github.com/facebook/react-native/blob/master/packages/rn-tester/js/examples/RTL/RTLExample.js" target="_blank" rel="noopener noreferrer"><code>RTLExample</code></a> in the <code>RNTester</code> to understand more about RTL support, and let us know how it works for you!</p><p>Finally, thank you for reading! We hope that the RTL support for React Native helps you grow your apps for international audience!</p>]]></content>
        <author>
            <name>Mengjue (Mandy) Wang</name>
            <uri>https://github.com/MengjueW</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[San Francisco Meetup Recap]]></title>
        <id>/2016/08/12/react-native-meetup-san-francisco</id>
        <link href="https://reactnative.dev/blog/2016/08/12/react-native-meetup-san-francisco"/>
        <updated>2016-08-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Last week I had the opportunity to attend the React Native Meetup at Zynga’s San Francisco office. With around 200 people in attendance, it served as a great place to meet other developers near me that are also interested in React Native.]]></summary>
        <content type="html"><![CDATA[<p>Last week I had the opportunity to attend the <a href="http://www.meetup.com/React-Native-San-Francisco/photos/27168649/#452793854" target="_blank" rel="noopener noreferrer">React Native Meetup</a> at Zynga’s San Francisco office. With around 200 people in attendance, it served as a great place to meet other developers near me that are also interested in React Native.</p><p><img loading="lazy" src="/assets/images/rnmsf-august-2016-hero-141e9a4052f9d7629686335b3d519bb9.jpg" width="1200" height="630" class="img_SS3x"></p><p>I was particularly interested in learning more about how React and React Native are used at companies like Zynga, Netflix, and Airbnb. The agenda for the night would be as follows:</p><ul><li>Rapid Prototyping in React</li><li>Designing APIs for React Native</li><li>Bridging the Gap: Using React Native in Existing Codebases</li></ul><p>But first, the event started off with a quick introduction and a brief recap of recent news:</p><ul><li>Did you know that React Native is now the <a href="https://twitter.com/jamespearce/status/759637111880359937" target="_blank" rel="noopener noreferrer">top Java repository on GitHub</a>?</li><li><a href="https://github.com/rnpm/rnpm" target="_blank" rel="noopener noreferrer">rnpm</a> is now part of React Native core! You can now use <code>react-native link</code> in place of <code>rnpm link</code> to <a href="/docs/linking-libraries-ios">install libraries with native dependencies</a>.</li><li>The React Native Meetup community is growing fast! There are now over 4,800 developers across a variety of React Native meetup groups all over the globe.</li></ul><p>If <a href="http://www.meetup.com/find/?allMeetups=false&amp;keywords=react+native&amp;radius=Infinity&amp;userFreeform=San+Francisco%2C+CA&amp;mcId=z94105&amp;mcName=San+Francisco%2C+CA&amp;sort=recommended&amp;eventFilter=mysugg" target="_blank" rel="noopener noreferrer">one of these meetups</a> is held near you, I highly recommend attending!</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="rapid-prototyping-in-react-at-zynga">Rapid Prototyping in React at Zynga<a class="hash-link" href="#rapid-prototyping-in-react-at-zynga" title="Direct link to heading">​</a></h2><p>The first round of news was followed by a quick introduction by Zynga, our hosts for the evening. Abhishek Chadha talked about how they use React to quickly prototype new experiences on mobile, demoing a quick prototype of a Draw Something-like app. They use a similar approach as React Native, providing access to native APIs via a bridge. This was demonstrated when Abhishek used the device's camera to snap a photo of the audience and then drew a hat on someone's head.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="designing-apis-for-react-native-at-netflix">Designing APIs for React Native at Netflix<a class="hash-link" href="#designing-apis-for-react-native-at-netflix" title="Direct link to heading">​</a></h2><p>Up next, the first featured talk of the evening. <a href="https://twitter.com/clarler" target="_blank" rel="noopener noreferrer">Clarence Leung</a>, Senior Software Engineer at Netflix, presented his talk on Designing APIs for React Native. First he noted the two main types of libraries one may work on: components such as tab bars and date pickers, and libraries that provide access to native services such as the camera roll or in-app payments. There are two ways one may approach when building a library for use in React Native:</p><ul><li>Provide platform-specific components</li><li>A cross-platform library with a similar API for both Android and iOS</li></ul><p>Each approach has its own considerations, and it’s up to you to determine what works best for your needs.</p><p><strong>Approach #1</strong></p><p>As an example of platform-specific components, Clarence talked about the DatePickerIOS and DatePickerAndroid from core React Native. On iOS, date pickers are rendered as part of the UI and can be easily embedded in an existing view, while date pickers on Android are presented modally. It makes sense to provide separate components in this case.</p><p><strong>Approach #2</strong></p><p>Photo pickers, on the other hand, are treated similarly on Android and iOS. There are some slight differences — Android does not group photos into folders like iOS does with Selfies, for example — but those are easily handled using <code>if</code> statements and the <code>Platform</code> component.</p><p>Regardless of which approach you settle on, it’s a good idea to minimize the API surface and build app-specific libraries. For example, iOS’s In-App Purchase framework supports one-time, consumable purchases, as well as renewable subscriptions. If your app will only need to support consumable purchases, you may get away with dropping support for subscriptions in your cross-platform library.</p><p><img loading="lazy" src="/assets/images/rnmsf-august-2016-netflix-c3a98ad2c4990dde5f32a78a953b6b02.jpg" width="650" height="407" class="img_SS3x"></p><p>There was a brief Q&amp;A session at the end of Clarence’s talk. One of the interesting tid bits that came out of it was that around 80% of the React Native code written for these libraries at Netflix is shared across both Android and iOS.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="bridging-the-gap-using-react-native-in-existing-codebases">Bridging the Gap, Using React Native in Existing Codebases<a class="hash-link" href="#bridging-the-gap-using-react-native-in-existing-codebases" title="Direct link to heading">​</a></h2><p>The final talk of the night was by <a href="https://twitter.com/intelligibabble" target="_blank" rel="noopener noreferrer">Leland Richardson</a> from Airbnb. The talk was focused on the use of React Native in existing codebases. I already know how easy it is to write a new app from scratch using React Native, so I was very interested to hear about Airbnb’s experience adopting React Native in their existing native apps.</p><p>Leland started off by talking about greenfield apps versus brownfield apps. Greenfield means to start a project without the need to consider any prior work. This is in contrast to brownfield projects where you need to take into account the existing project’s requirements, development processes, and all of the teams various needs.</p><p>When you’re working on a greenfield app, the React Native CLI sets up a single repository for both Android and iOS and everything just works. The first challenge against using React Native at Airbnb was the fact that the Android and iOS app each had their own repository. Multi-repo companies have some hurdles to get past before they can adopt React Native.</p><p>To get around this, Airbnb first set up a new repo for the React Native codebase. They used their continuous integration servers to mirror the Android and iOS repos into this new repo. After tests are run and the bundle is built, the build artifacts are synced back to the Android and iOS repos. This allows the mobile engineers to work on native code without altering their development environment. Mobile engineers don't need to install npm, run the packager, or remember to build the JavaScript bundle. The engineers writing actual React Native code do not have to worry about syncing their code across Android and iOS, as they work on the React Native repository directly.</p><p>This does come with some drawbacks, mainly they could not ship atomic updates. Changes that require a combination of native and JavaScript code would require three separate pull requests, all of which had to be carefully landed. In order to avoid conflicts, CI will fail to land changes back to the Android and iOS repos if master has changed since the build started. This would cause long delays during high commit frequency days (such as when new releases are cut).</p><p>Airbnb has since moved to a mono repo approach. Fortunately this was already under consideration, and once the Android and iOS teams became comfortable with using React Native they were happy to accelerate the move towards the mono repo.</p><p>This has solved most of the issues they had with the split repo approach. Leland did note that this does cause a higher strain on the version control servers, which may be an issue for smaller companies.</p><p><img loading="lazy" src="/assets/images/rnmsf-august-2016-airbnb-82bbdf39f62d23c89a97181202f24104.jpg" width="650" height="472" class="img_SS3x"></p><h3 class="anchor anchorWithStickyNavbar_JmGV" id="the-navigation-problem">The Navigation Problem<a class="hash-link" href="#the-navigation-problem" title="Direct link to heading">​</a></h3><p>The second half of Leland's talk focused on a topic that is dear to me: the Navigation problem in React Native. He talked about the abundance of navigation libraries in React Native, both first party and third party. NavigationExperimental was mentioned as something that seemed promising, but ended up not being well suited for their use case.</p><p>In fact, none of the existing navigation libraries seem to work well for brownfield apps. A brownfield app requires that the navigation state be fully owned by the native app. For example, if a user’s session expires while a React Native view is being presented, the native app should be able to take over and present a login screen as needed.</p><p>Airbnb also wanted to avoid replacing native navigation bars with JavaScript versions as part of a transition, as the effect could be jarring. Initially they limited themselves to modally presented views, but this obviously presented a problem when it came to adopting React Native more widely within their apps.</p><p>They decided that they needed their own library. The library is called <code>airbnb-navigation</code>. The library has not yet being open sourced as it is strongly tied to Airbnb’s codebase, but it is something they’d like to release by the end of the year.</p><p>I won’t go into much detail into the library’s API, but here are some of the key takeaways:</p><ul><li>One must preregister scenes ahead of time</li><li>Each scene is displayed within its own <code>RCTRootView</code>. They are presented natively on each platform (e.g. <code>UINavigationController</code>s are used on iOS).</li><li>The main <code>ScrollView</code> in a scene should be wrapped in a <code>ScrollScene</code> component. Doing so allows you to take advantage of native behaviors such as tapping on the status bar to scroll to the top on iOS.</li><li>Transitions between scenes are handled natively, no need to worry about performance.</li><li>The Android back button is automatically supported.</li><li>They can take advantage of View Controller based navigation bar styling via a Navigator.Config UI-less component.</li></ul><p>There’s also some considerations to keep in mind:</p><ul><li>The navigation bar is not easily customized in JavaScript, as it is a native component. This is intentional, as using native navigation bars is a hard requirement for this type of library.</li><li>ScreenProps must be serialized/de-serialized whenever they're sent through the bridge, so care must be taken if sending too much data here.</li><li>Navigation state is owned by the native app (also a hard requirement for the library), so things like Redux cannot manipulate navigation state.</li></ul><p>Leland's talk was also followed by a Q&amp;A session. Overall, Airbnb is satisfied with React Native. They’re interested in using Code Push to fix any issues without going through the App Store, and their engineers love Live Reload, as they don't have to wait for the native app to be rebuilt after every minor change.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="closing-remarks">Closing Remarks<a class="hash-link" href="#closing-remarks" title="Direct link to heading">​</a></h2><p>The event ended with some additional React Native news:</p><ul><li>Deco announced their <a href="https://www.decosoftware.com/showcase" target="_blank" rel="noopener noreferrer">React Native Showcase</a>, and invited everyone to add their app to the list.</li><li>The recent <a href="/blog/2016/07/06/toward-better-documentation">documentation overhaul</a> got a shoutout!</li><li>Devin Abbott, one of the creators of Deco IDE, will be teaching an introductory <a href="https://www.decosoftware.com/course" target="_blank" rel="noopener noreferrer">React Native course</a>.</li></ul><p><img loading="lazy" src="/assets/images/rnmsf-august-2016-docs-bb75ef99473c1d947a3c4020cd1101bc.jpg" width="650" height="415" class="img_SS3x"></p><p>Meetups provide a good opportunity to meet and learn from other developers in the community. I'm looking forward to attending more React Native meetups in the future. If you make it up to one of these, please look out for me and let me know how we can make React Native work better for you!</p>]]></content>
        <author>
            <name>Héctor Ramos</name>
            <uri>https://twitter.com/hectorramos</uri>
        </author>
        <category label="events" term="events"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Toward Better Documentation]]></title>
        <id>/2016/07/06/toward-better-documentation</id>
        <link href="https://reactnative.dev/blog/2016/07/06/toward-better-documentation"/>
        <updated>2016-07-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Part of having a great developer experience is having great documentation. A lot goes into creating good docs - the ideal documentation is concise, helpful, accurate, complete, and delightful. Recently we've been working hard to make the docs better based on your feedback, and we wanted to share some of the improvements we've made.]]></summary>
        <content type="html"><![CDATA[<p>Part of having a great developer experience is having great documentation. A lot goes into creating good docs - the ideal documentation is concise, helpful, accurate, complete, and delightful. Recently we've been working hard to make the docs better based on your feedback, and we wanted to share some of the improvements we've made.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="inline-examples">Inline Examples<a class="hash-link" href="#inline-examples" title="Direct link to heading">​</a></h2><p>When you learn a new library, a new programming language, or a new framework, there's a beautiful moment when you first write a bit of code, try it out, see if it works... and it <em>does</em> work. You created something real. We wanted to put that visceral experience right into our docs. Like this:</p><div class="language-ReactNativeWebPlayer codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-ReactNativeWebPlayer codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token plain">import React, { Component } from 'react';</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">import { AppRegistry, Text, View } from 'react-native';</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">class ScratchPad extends Component {</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  render() {</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    return (</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      &lt;View style={{flex: 1}}&gt;</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        &lt;Text style={{fontSize: 30, flex: 1, textAlign: 'center'}}&gt;</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          Isn't this cool?</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        &lt;/Text&gt;</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        &lt;Text style={{fontSize: 100, flex: 1, textAlign: 'center'}}&gt;</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">          👍</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">        &lt;/Text&gt;</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      &lt;/View&gt;</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    );</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">}</span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">AppRegistry.registerComponent('ScratchPad', () =&gt; ScratchPad);</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We think these inline examples, using the <a href="https://github.com/dabbott/react-native-web-player" target="_blank" rel="noopener noreferrer"><code>react-native-web-player</code></a> module with help from <a href="https://twitter.com/devinaabbott" target="_blank" rel="noopener noreferrer">Devin Abbott</a>, are a great way to learn the basics of React Native, and we have updated our <a href="/docs/tutorial">tutorial for new React Native developers</a> to use these wherever possible. Check it out - if you have ever been curious to see what would happen if you modified just one little bit of sample code, this is a really nice way to poke around. Also, if you're building developer tools and you want to show a live React Native sample on your own site, <a href="https://github.com/dabbott/react-native-web-player" target="_blank" rel="noopener noreferrer"><code>react-native-web-player</code></a> can make that straightforward.</p><p>The core simulation engine is provided by <a href="https://twitter.com/necolas" target="_blank" rel="noopener noreferrer">Nicolas Gallagher</a>'s <a href="https://github.com/necolas/react-native-web" target="_blank" rel="noopener noreferrer"><code>react-native-web</code></a> project, which provides a way to display React Native components like <code>Text</code> and <code>View</code> on the web. Check out <a href="https://github.com/necolas/react-native-web" target="_blank" rel="noopener noreferrer"><code>react-native-web</code></a> if you're interested in building mobile and web experiences that share a large chunk of the codebase.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="better-guides">Better Guides<a class="hash-link" href="#better-guides" title="Direct link to heading">​</a></h2><p>In some parts of React Native, there are multiple ways to do things, and we've heard feedback that we could provide better guidance.</p><p>We have a new <a href="/docs/navigation">guide to Navigation</a> that compares the different approaches and advises on what you should use - <code>Navigator</code>, <code>NavigatorIOS</code>, <code>NavigationExperimental</code>. In the medium term, we're working towards improving and consolidating those interfaces. In the short term, we hope that a better guide will make your life easier.</p><p>We also have a new <a href="/docs/handling-touches">guide to handling touches</a> that explains some of the basics of making button-like interfaces, and a brief summary of the different ways to handle touch events.</p><p>Another area we worked on is Flexbox. This includes tutorials on how to <a href="/docs/flexbox">handle layout with Flexbox</a> and how to control <a href="/docs/height-and-width">the size of components</a>. It also includes an unsexy but hopefully-useful <a href="/docs/layout-props">list of all the props that control layout in React Native</a>.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="getting-started">Getting Started<a class="hash-link" href="#getting-started" title="Direct link to heading">​</a></h2><p>When you start getting a React Native development environment set up on your machine, you do have to do a bunch of installing and configuring things. It's hard to make installation a really fun and exciting experience, but we can at least make it as quick and painless as possible.</p><p>We built a <a href="/docs/next/getting-started">new Getting Started workflow</a> that lets you select your development operating system and your mobile operating system up front, to provide one concise place with all the setup instructions. We also went through the installation process to make sure everything worked and to make sure that every decision point had a clear recommendation. After testing it out on our innocent coworkers, we're pretty sure this is an improvement.</p><p>We also worked on the <a href="/docs/integration-with-existing-apps">guide to integrating React Native into an existing app</a>. Many of the largest apps that use React Native, like the Facebook app itself, actually build part of the app in React Native, and part of it using regular development tools. We hope this guide makes it easier for more people to build apps this way.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="we-need-your-help">We Need Your Help<a class="hash-link" href="#we-need-your-help" title="Direct link to heading">​</a></h2><p>Your feedback lets us know what we should prioritize. I know some people will read this blog post and think "Better docs? Pffft. The documentation for X is still garbage!". That's great - we need that energy. The best way to give us feedback depends on the sort of feedback.</p><p>If you find a mistake in the documentation, like inaccurate descriptions or code that doesn't actually work, <a href="https://github.com/facebook/react-native/issues" target="_blank" rel="noopener noreferrer">file an issue</a>. Tag it with "Documentation", so that it's easier to route it to the right people.</p><p>If there isn't a specific mistake, but something in the documentation is fundamentally confusing, it's not a great fit for a GitHub issue. Instead, post on <a href="https://react-native.canny.io/feature-requests" target="_blank" rel="noopener noreferrer">Canny</a> about the area of the docs that could use help. This helps us prioritize when we are doing more general work like guide-writing.</p><p>Thanks for reading this far, and thanks for using React Native!</p>]]></content>
        <author>
            <name>Kevin Lacker</name>
            <uri>https://twitter.com/lacker</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native: A year in review]]></title>
        <id>/2016/04/13/react-native-a-year-in-review</id>
        <link href="https://reactnative.dev/blog/2016/04/13/react-native-a-year-in-review"/>
        <updated>2016-04-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[It's been one year since we open-sourced React Native. What started as an idea with a handful of engineers is now a framework being used by product teams across Facebook and beyond. Today at F8 we announced that Microsoft is bringing React Native to the Windows ecosystem, giving developers the potential to build React Native on Windows PC, Phone, and Xbox. It will also provide open source tools and services such as a React Native extension for Visual Studio Code and CodePush to help developers create React Native apps on the Windows platform. In addition, Samsung is building React Native for its hybrid platform, which will empower developers to build apps for millions of SmartTVs and mobile and wearable devices. We also released the Facebook SDK for React Native, which makes it easier for developers to incorporate Facebook social features like Login, Sharing, App Analytics, and Graph APIs into their apps. In one year, React Native has changed the way developers build on every major platform.]]></summary>
        <content type="html"><![CDATA[<p>It's been one year since we open-sourced React Native. What started as an idea with a handful of engineers is now a framework being used by product teams across Facebook and beyond. Today at F8 we announced that Microsoft is bringing <a href="http://microsoft.github.io/code-push/articles/ReactNativeWindows.html" target="_blank" rel="noopener noreferrer">React Native to the Windows ecosystem</a>, giving developers the potential to build React Native on Windows PC, Phone, and Xbox. It will also provide open source tools and services such as a React Native extension for Visual Studio Code and CodePush to help developers create React Native apps on the Windows platform. In addition, <a href="https://www.tizen.org/blogs" target="_blank" rel="noopener noreferrer">Samsung</a> is building React Native for its hybrid platform, which will empower developers to build apps for millions of SmartTVs and mobile and wearable devices. We also released the <a href="https://github.com/facebook/react-native-fbsdk" target="_blank" rel="noopener noreferrer">Facebook SDK for React Native</a>, which makes it easier for developers to incorporate Facebook social features like Login, Sharing, App Analytics, and Graph APIs into their apps. In one year, React Native has changed the way developers build on every major platform.</p><p>It's been an epic ride — but we are only getting started. Here is a look back at how React Native has grown and evolved since we open-sourced it a year ago, some challenges we faced along the way, and what we expect as we look ahead to the future.</p><footer><a href="https://code.facebook.com/posts/597378980427792/react-native-a-year-in-review/" target="_blank" rel="noopener noreferrer" class="btn">Read more</a></footer><blockquote><p>This is an excerpt. Read the rest of the post on <a href="https://code.facebook.com/posts/597378980427792/react-native-a-year-in-review/" target="_blank" rel="noopener noreferrer">Facebook Code</a>.</p></blockquote>]]></content>
        <author>
            <name>Martin Konicek</name>
            <uri>https://github.com/mkonicek</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Dive into React Native Performance]]></title>
        <id>/2016/03/28/dive-into-react-native-performance</id>
        <link href="https://reactnative.dev/blog/2016/03/28/dive-into-react-native-performance"/>
        <updated>2016-03-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[React Native allows you to build Android and iOS apps in JavaScript using React and Relay's declarative programming model. This leads to more concise, easier-to-understand code; fast iteration without a compile cycle; and easy sharing of code across multiple platforms. You can ship faster and focus on details that really matter, making your app look and feel fantastic. Optimizing performance is a big part of this. Here is the story of how we made React Native app startup twice as fast.]]></summary>
        <content type="html"><![CDATA[<p>React Native allows you to build Android and iOS apps in JavaScript using React and Relay's declarative programming model. This leads to more concise, easier-to-understand code; fast iteration without a compile cycle; and easy sharing of code across multiple platforms. You can ship faster and focus on details that really matter, making your app look and feel fantastic. Optimizing performance is a big part of this. Here is the story of how we made React Native app startup twice as fast.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="why-the-hurry">Why the hurry?<a class="hash-link" href="#why-the-hurry" title="Direct link to heading">​</a></h2><p>With an app that runs faster, content loads quickly, which means people get more time to interact with it, and smooth animations make the app enjoyable to use. In emerging markets, where <a href="https://code.facebook.com/posts/952628711437136/classes-performance-and-network-segmentation-on-android/" target="_blank" rel="noopener noreferrer">2011 class phones</a> on <a href="https://newsroom.fb.com/news/2015/10/news-feed-fyi-building-for-all-connectivity/" target="_blank" rel="noopener noreferrer">2G networks</a> are the majority, a focus on performance can make the difference between an app that is usable and one that isn't.</p><p>Since releasing React Native on <a href="https://reactjs.org/blog/2015/03/26/introducing-react-native.html" target="_blank" rel="noopener noreferrer">iOS</a> and on <a href="https://code.facebook.com/posts/1189117404435352/react-native-for-android-how-we-built-the-first-cross-platform-react-native-app/" target="_blank" rel="noopener noreferrer">Android</a>, we have been improving list view scrolling performance, memory efficiency, UI responsiveness, and app startup time. Startup sets the first impression of an app and stresses all parts of the framework, so it is the most rewarding and challenging problem to tackle.</p><footer><a href="https://code.facebook.com/posts/895897210527114/dive-into-react-native-performance/" target="_blank" rel="noopener noreferrer" class="btn">Read more</a></footer><blockquote><p>This is an excerpt. Read the rest of the post on <a href="https://code.facebook.com/posts/895897210527114/dive-into-react-native-performance/" target="_blank" rel="noopener noreferrer">Facebook Code</a>.</p></blockquote>]]></content>
        <author>
            <name>Pieter De Baets</name>
            <uri>https://github.com/javache</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Hot Reloading]]></title>
        <id>/2016/03/24/introducing-hot-reloading</id>
        <link href="https://reactnative.dev/blog/2016/03/24/introducing-hot-reloading"/>
        <updated>2016-03-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[React Native's goal is to give you the best possible developer experience. A big part of it is the time it takes between you save a file and be able to see the changes. Our goal is to get this feedback loop to be under 1 second, even as your app grows.]]></summary>
        <content type="html"><![CDATA[<p>React Native's goal is to give you the best possible developer experience. A big part of it is the time it takes between you save a file and be able to see the changes. Our goal is to get this feedback loop to be under 1 second, even as your app grows.</p><p>We got close to this ideal via three main features:</p><ul><li>Use JavaScript as the language doesn't have a long compilation cycle time.</li><li>Implement a tool called Packager that transforms es6/flow/jsx files into normal JavaScript that the VM can understand. It was designed as a server that keeps intermediate state in memory to enable fast incremental changes and uses multiple cores.</li><li>Build a feature called Live Reload that reloads the app on save.</li></ul><p>At this point, the bottleneck for developers is no longer the time it takes to reload the app but losing the state of your app. A common scenario is to work on a feature that is multiple screens away from the launch screen. Every time you reload, you've got to click on the same path again and again to get back to your feature, making the cycle multiple-seconds long.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="hot-reloading">Hot Reloading<a class="hash-link" href="#hot-reloading" title="Direct link to heading">​</a></h2><p>The idea behind hot reloading is to keep the app running and to inject new versions of the files that you edited at runtime. This way, you don't lose any of your state which is especially useful if you are tweaking the UI.</p><p>A video is worth a thousand words. Check out the difference between Live Reload (current) and Hot Reload (new).</p><iframe width="100%" height="315" src="https://www.youtube.com/embed/2uQzVi-KFuc" frameborder="0"></iframe><p>If you look closely, you can notice that it is possible to recover from a red box and you can also start importing modules that were not previously there without having to do a full reload.</p><p><strong>Word of warning:</strong> because JavaScript is a very stateful language, hot reloading cannot be perfectly implemented. In practice, we found out that the current setup is working well for a large amount of usual use cases and a full reload is always available in case something gets messed up.</p><p>Hot reloading is available as of 0.22, you can enable it:</p><ul><li>Open the developer menu</li><li>Tap on "Enable Hot Reloading"</li></ul><h2 class="anchor anchorWithStickyNavbar_JmGV" id="implementation-in-a-nutshell">Implementation in a nutshell<a class="hash-link" href="#implementation-in-a-nutshell" title="Direct link to heading">​</a></h2><p>Now that we've seen why we want it and how to use it, the fun part begins: how it actually works.</p><p>Hot Reloading is built on top of a feature <a href="https://webpack.js.org/guides/hot-module-replacement/" target="_blank" rel="noopener noreferrer">Hot Module Replacement</a>, or HMR. It was first introduced by Webpack and we implemented it inside of React Native Packager. HMR makes the Packager watch for file changes and send HMR updates to a thin HMR runtime included on the app.</p><p>In a nutshell, the HMR update contains the new code of the JS modules that changed. When the runtime receives them, it replaces the old modules' code with the new one:</p><p><img loading="lazy" src="/assets/images/hmr-architecture-fc0ad839836fbf08ce9b0557be33c5ad.png" width="913" height="395" class="img_SS3x"></p><p>The HMR update contains a bit more than just the module's code we want to change because replacing it, it's not enough for the runtime to pick up the changes. The problem is that the module system may have already cached the <em>exports</em> of the module we want to update. For instance, say you have an app composed of these two modules:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// log.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">message</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> time </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'./time'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token template-string string" style="color:#8dc891">[</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">${</span><span class="token template-string interpolation function" style="color:#79b6f2">time</span><span class="token template-string interpolation punctuation" style="color:#657b83">(</span><span class="token template-string interpolation punctuation" style="color:#657b83">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">}</span><span class="token template-string string" style="color:#8dc891">] </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">${</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">}</span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> log</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// time.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">time</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">Date</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">getTime</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> time</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The module <code>log</code>, prints out the provided message including the current date provided by the module <code>time</code>.</p><p>When the app is bundled, React Native registers each module on the module system using the <code>__d</code> function. For this app, among many <code>__d</code> definitions, there will one for <code>log</code>:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token function" style="color:#79b6f2">__d</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'log'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token spread operator" style="color:#fc929e">...</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// module's code</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This invocation wraps each module's code into an anonymous function which we generally refer to as the factory function. The module system runtime keeps track of each module's factory function, whether it has already been executed, and the result of such execution (exports). When a module is required, the module system either provides the already cached exports or executes the module's factory function for the first time and saves the result.</p><p>So say you start your app and require <code>log</code>. At this point, neither <code>log</code> nor <code>time</code>'s factory functions have been executed so no exports have been cached. Then, the user modifies <code>time</code> to return the date in <code>MM/DD</code>:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// time.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">bar</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">var</span><span class="token plain"> date </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">new</span><span class="token plain"> </span><span class="token class-name" style="color:#fac863">Date</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">${</span><span class="token template-string interpolation">date</span><span class="token template-string interpolation punctuation" style="color:#657b83">.</span><span class="token template-string interpolation method function property-access" style="color:#79b6f2">getMonth</span><span class="token template-string interpolation punctuation" style="color:#657b83">(</span><span class="token template-string interpolation punctuation" style="color:#657b83">)</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation operator" style="color:#fc929e">+</span><span class="token template-string interpolation"> </span><span class="token template-string interpolation number" style="color:#5a9bcf">1</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">}</span><span class="token template-string string" style="color:#8dc891">/</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">${</span><span class="token template-string interpolation">date</span><span class="token template-string interpolation punctuation" style="color:#657b83">.</span><span class="token template-string interpolation method function property-access" style="color:#79b6f2">getDate</span><span class="token template-string interpolation punctuation" style="color:#657b83">(</span><span class="token template-string interpolation punctuation" style="color:#657b83">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">}</span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> bar</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The Packager will send time's new code to the runtime (step 1), and when <code>log</code> gets eventually required the exported function gets executed it will do so with <code>time</code>'s changes (step 2):</p><p><img loading="lazy" src="/assets/images/hmr-step-9d2dd4297f792827ffabc55bb1154b8a.png" width="914" height="225" class="img_SS3x"></p><p>Now say the code of <code>log</code> requires <code>time</code> as a top level require:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> time </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'./time'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// top level require</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token comment" style="color:#93a1a1">// log.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">message</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token template-string string" style="color:#8dc891">[</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">${</span><span class="token template-string interpolation function" style="color:#79b6f2">time</span><span class="token template-string interpolation punctuation" style="color:#657b83">(</span><span class="token template-string interpolation punctuation" style="color:#657b83">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">}</span><span class="token template-string string" style="color:#8dc891">] </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">${</span><span class="token template-string interpolation">message</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#657b83">}</span><span class="token template-string template-punctuation string" style="color:#8dc891">`</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> log</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>When <code>log</code> is required, the runtime will cache its exports and <code>time</code>'s one. (step 1). Then, when <code>time</code> is modified, the HMR process cannot simply finish after replacing <code>time</code>'s code. If it did, when <code>log</code> gets executed, it would do so with a cached copy of <code>time</code> (old code).</p><p>For <code>log</code> to pick up <code>time</code> changes, we'll need to clear its cached exports because one of the modules it depends on was hot swapped (step 3). Finally, when <code>log</code> gets required again, its factory function will get executed requiring <code>time</code> and getting its new code.</p><p><img loading="lazy" src="/assets/images/hmr-log-884dbcc7b040993d7d402bba105c537e.png" width="907" height="377" class="img_SS3x"></p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="hmr-api">HMR API<a class="hash-link" href="#hmr-api" title="Direct link to heading">​</a></h2><p>HMR in React Native extends the module system by introducing the <code>hot</code> object. This API is based on <a href="https://webpack.github.io/hot-module-replacement.md" target="_blank" rel="noopener noreferrer">Webpack</a>'s one. The <code>hot</code> object exposes a function called <code>accept</code> which allows you to define a callback that will be executed when the module needs to be hot swapped. For instance, if we would change <code>time</code>'s code as follows, every time we save time, we'll see “time changed” in the console:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// time.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">time</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token spread operator" style="color:#fc929e">...</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">// new code</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">hot</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">accept</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token console class-name" style="color:#fac863">console</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">log</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'time changed'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> time</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Note that only in rare cases you would need to use this API manually. Hot Reloading should work out of the box for the most common use cases.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="hmr-runtime">HMR Runtime<a class="hash-link" href="#hmr-runtime" title="Direct link to heading">​</a></h2><p>As we've seen before, sometimes it's not enough only accepting the HMR update because a module that uses the one being hot swapped may have been already executed and its imports cached. For instance, suppose the dependency tree for the movies app example had a top-level <code>MovieRouter</code> that depended on the <code>MovieSearch</code> and <code>MovieScreen</code> views, which depended on the <code>log</code> and <code>time</code> modules from the previous examples:</p><p><img loading="lazy" src="/assets/images/hmr-diamond-55c39ddebd4758c5434b39890281f69e.png" width="733" height="390" class="img_SS3x"></p><p>If the user accesses the movies' search view but not the other one, all the modules except for <code>MovieScreen</code> would have cached exports. If a change is made to module <code>time</code>, the runtime will have to clear the exports of <code>log</code> for it to pick up <code>time</code>'s changes. The process wouldn't finish there: the runtime will repeat this process recursively up until all the parents have been accepted. So, it'll grab the modules that depend on <code>log</code> and try to accept them. For <code>MovieScreen</code> it can bail, as it hasn't been required yet. For <code>MovieSearch</code>, it will have to clear its exports and process its parents recursively. Finally, it will do the same thing for <code>MovieRouter</code> and finish there as no modules depends on it.</p><p>In order to walk the dependency tree, the runtime receives the inverse dependency tree from the Packager on the HMR update. For this example the runtime will receive a JSON object like this one:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">modules</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token literal-property property" style="color:#2aa198">name</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'time'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token literal-property property" style="color:#2aa198">code</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token comment" style="color:#93a1a1">/* time's new code */</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token literal-property property" style="color:#2aa198">inverseDependencies</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">MovieRouter</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">MovieScreen</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token string" style="color:#8dc891">'MovieRouter'</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">MovieSearch</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token string" style="color:#8dc891">'MovieRouter'</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">log</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token string" style="color:#8dc891">'MovieScreen'</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'MovieSearch'</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token literal-property property" style="color:#2aa198">time</span><span class="token operator" style="color:#fc929e">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">[</span><span class="token string" style="color:#8dc891">'log'</span><span class="token punctuation" style="color:#657b83">]</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_JmGV" id="react-components">React Components<a class="hash-link" href="#react-components" title="Direct link to heading">​</a></h2><p>React components are a bit harder to get to work with Hot Reloading. The problem is that we can't simply replace the old code with the new one as we'd loose the component's state. For React web applications, <a href="https://twitter.com/dan_abramov" target="_blank" rel="noopener noreferrer">Dan Abramov</a> implemented a babel <a href="http://gaearon.github.io/react-hot-loader/" target="_blank" rel="noopener noreferrer">transform</a> that uses Webpack's HMR API to solve this issue. In a nutshell, his solution works by creating a proxy for every single React component on <em>transform time</em>. The proxies hold the component's state and delegate the lifecycle methods to the actual components, which are the ones we hot reload:</p><p><img loading="lazy" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAjAAAAChCAYAAADZVIWgAAAeTklEQVR4AezBgQAAAADDoPtTH2TVYgAAAAAAAAAA4OycAWQjzx/FIVgERREUQVAERVEUoQiCIgiCRRAERVAEQXEoiuJQFEURFEVRBEVQBD8URRAsgiI4BP0vPvfz/T+7m91mXXv9zWNcujc7OzPz5s2b72yyF6ZWmJphqmxcmoODgxemckz67jrh4FD64lwvUL9ihnuqYWqRdj+/CQ71ML2G6V3SIwR0yEbuLp8dHGp2TklahukCEf1bdOIlN51wOnH2HzDvCzjS+KKaWqZ+foq8R2H6J4L/42wmzQHjN8yjIN8MwiGk2+L6EsFK6U4d6MdruebgDMwPPv9OzTDdmv/76miHaZWkE/ydDg5j0ndGE35Pw3T/FTU1g4E5hv9Phv/FMLXh/8zx/8/zv0Tnj2N2gS0G9/RDpTsD4+BQWyOQU3apXxYI81uYJqITulANzDUHZ2Ae4MwJi//O32ZghP/PMfyvf85GxPG/T8cfJuTphWlfwoLDMM24dx6mc67bqM4tIbcp+Wa42Aoh5xXC3beGikbVcewriPMzIgq0xwT5ZZzxkc1AHToQ6416TMJ0EEHQK5PnhfssTkn+77aTr22fRxkB7XBhdYdEA4MwvwuHemaOXHK9yHFTYObTwAhqkTlzHcHbRxaPPp89DY2v4WuPZ9YT2nki86ogOhGgE0UR/lv0R3WibHVCzZHRiTujE1cJOrEk32SNTgQJOlFkPBZm/ncj+vsijU6QxtTxu2GH/u7Dq1XCAl9Hv1eM04h74jR1L4avFySLnj324bOf0cB0UhyD9SL4P0jDf+6bCP9LsgYOI/jv01e/6Ldr1jI9qhkZ/j9TfhT/h8L/muRTDUrif9u0fUZdc+f/HY0vZHTVSypa498lYvMbQ64FDOwxjX3jXZszrt3TwANLJjMYVTp2yXOtKC0ZjKYYHkuymemkFp0YIECeMWRTrndo0zn1OJGFJqD+HZ77zDOrZif6wmT0hawKB2dgCvBpZjkLtycIQZd8T1zvUuYQ7t1ECG3PPHtFXlsXFbARXI7DiPu8rNpidKKvOmGOn+Zh6lOvKfe9oBMN1Qnwzty+Rg/aWj7irTpxZ/pAdeLJ6MSca0XyFCgnMGPwwyzSVieWRieOzeK0Z3WC5H/HjQ6L98q07Z6+K0QczbzDsTr9H2A0ClGaanhcXrOrPyXfkHsalMNYpDYwbDIy6fkt7R/w7J6edhj+B9S1Acd+0X7lf83yn3w3hv+BtL9C+VPD/xH3ti3/uXdi+P+q/KfvFob/Z6aNtq/eKLMr/N/Pm/9jHpQWR1REoxO+ONQhfzc1zCwvru1YwTVkeowp/8CIY2AJZQTmVQZmJpOmLVGnjulci0sGwjMDo2HQXe7tJoU7HZyBITrgm9Q3UYeucHYunG3J/FKB3hfjsETU5lYwwYw8v7GNEPZy1IlDbRdoiXnwVUxpo4bjt7nWFwEfx5R/aIxXYHalVojn2udi0JpSlm/+tjin/4qy2FUidvn9736EJH16r/3Jv3qEOomIyCwMr0VT0xkYTMRPPqtm+xkMzBgepcWBjLf2QUs41Yk4jrqUyIce0RIliSz/iL9vWMO2Y9pTMGO14DlqLGsytzR6eQb/txL4vyP1z8b/HIXpLGYn5nH9QgxMSUmnYWiuDYVMapCK8i7OEmIqTsi3YwbmRhcUGZgRg1eTdCqCda19pfV3BsYh47eQ/olY5GcIr8UVHFXsqFAiVnPmyII8FkMRnC7GfHuNTsyz7L5jdqwFnn0pAl6O6K9G0jyLMUieCOVC56Icie2aPh/F6YSEvWuS+pIvi06MvznnmxHfSHpMNqaKjQyMzhWiBpkNzANjvxaysdDjHF27/ASz66fgf0/nlxzVzeGtomujUGo2QUV4fcXcVf6fyHy95rl/hP9X60LDdGghrnIivNdiYOIFIdbASB7JJ58VvtxPnRLrMebvuNQybR/nZmAc3BGSIp6zD1xXxM2FoYn6KHST8EREJgk/1ZAk6wS6ktA+ma+F9DoBZDco168/QSd8Z2D+xc2avtrNYB42MTAVE5F859/JBwzMpRiSKOwYHg8z8r/8QQPjJ5evJx7af4n8L/8N/G9LSFdRwLBMTLgUwRGws8rJwDRjdlan5lkXCc6ykkGYHtgJx+KTDIyDMzD6/pViKyI0WzZfa17pfBPxqKyZ/6oTzTX1nmqkNuUOFGQ2MO2kCAzPukx4KbOaQSfuOZ5OgDMwcPIXuupL6tMP5xGvECiqjGdmAyPvl83hiZqmLAbmWPmm4FkvSRFIsMjRwHRiIjDn5lk3Cd8u3s9gYEb05Zfiv2demComhMJO5IytHvNujJ+TgblUAslxzhN1ViN1x6AVMgjTmYbxgG++vfGZBsbBGZiehHx1IT4yAjahjC35rNxmIWG+rNeJecJvQvVEJxpqjPQdupwMjPZTQ/rjUd+BM2K8zKgTgxidaP/fD5k5A9MVrVY8y5co5JhD3lNJNjBHutk2fVqVY0Z9x6Sf0sDoy/alBEM8EJ63Yt6N6eVkYG50fsn6fK/v04EbTKaXwcD0RYO+Bv+Z9CvEqUMFayZs9mQ6oIBxCOgsj38DBtjLw8BQn66U/xRBwivu2aIMG6VJJUwQ8o32H9DGOtcmH4zAzOnX7U0Hx8EZGPg9Nxz14Fcgv80yEG7vmm8qqCFZki4y/Arvivp1U+jE1OoEeWckLw8DIzpRM/1hBX2FYVGdGGTRCebyQnTiiGuTD+xAH41OlL4R359j2q9m15eF8QRzXIVLc4nAvBpN3TE/nVEl3cLnsZkzK/p5y/Ah0DUn5fw8iuO/qYsX8Y21BtcP4c6c+mxsYHhuj347pI+mZh4ekudO+C9HS+sNDPcGtKEmazPPzMT/B/qingf/a3S4/sz5ue64eNiD5H2AVGBjA3NF495JdzxXnV9g8ryJeUklTGDffCNEn5nVwLQhDTvQzeDgDIwxI0/C0ZHh6D680+hlP+b450p2VGlwqHUwJiiNTjyKWG9qYFQnHlUnaHcg9R18UCf2VCdpY+kDBqaNuWRsvgWqsjjGHjGJ6RuYvnhHi3eFJ6qpXcby3UQjfohGd6TcV/p6ir6nNjBgX/lP+T9j+D+SvBzbgs0NzD1cS+J/gzmi/C+kNTCiQRNt0wf5f2zGpp0L+3C3e1TUS5OXf/OADl4hZfkVOS/dBCVIummbimLogINDbhzdyuEF/ukG7zlUM+gEcypXqE6U/kKd8JxO/AuPcSxn0FSPMd1eo8V7jH8C/sfeHdsqDENRAH0lBSWlS4ZgDwZgAAagZAAGYZAMQskaNE9KaJwmVmT5HIkule+1ef8bQZf9f+r/fuoDTCtAyb/E7tEv5wQjywEGAwyM89+b7+IzbwcDDBhg2MYxD6VzAC088nWKjg1+TsCt19/QAgAAAAAAAAAA8ivGK69rzF6Nnn2vPHtp9GyJ2bTPs0v5S7irAIBPIA8A8IaJPAAAAwy4+nX1i+7rPgYY9AR5WGvkgTKgJ/LAWstDGZQBsG+hn+7beJQAHOKg+zYegHMUDDCAN0zkYa0xwPxhCrBvXf2i+7qvDDYnegK6jzIgD/QEdB9lQB7oiatfdF/3sTnRE+RhrZEHyoCeIA9rjTxQhir0RB5Ya3kogzIA9i0YYPB9EoBzFH7snQOULDkYhce2n23btm3btm3bb2x7+uxgjWfbxtruvf85mfWzpqvvPecbTyrpSlK3/j+ppoGxAAVBXdAFDAAzwAIzM7O9NjY2QVZWVon4/IGtre2H+PwJvr/1KKytrW8/6ncWFhY3pQwBf/c+fhYLAnGsHWABmKKO3wHUVPWiKIqigaEoIzYwJZVBmQNjEmZpaXnS3Nz8Ab7Xw5TccXV1PZ0vX74DpUuXzqxRo0ZKy5Yt4/v06RMyYsQI3wkTJuxevXr12mzS09NnPYr33ntvxqN+l5ycPPfv5YwZM2aflN+zZ8/w5s2bx1atWlVXokSJ9Fy5ch10cnI6izrek/qhnndQ58P42leZqw7aNDcUJw2K54OvNUUDYwH6iFkBt+3t7c8VLlw4vXHjxiHjx4/ftWfPnmUHDhyYqtfrh+d0xBRt3759JczOrjp16kTkzZs3HabrAtp1XZmaDtxTTxn+uKWY+mXfp/hWAm3AyUKFCgWtXLly1c2bN8eJEdAaFy9enAgtd3BwkOjMRVCTg5Mywkm8IKgK2oAhYAFYAXxBIMgSTE1NL4npfwbOq/8VfBVLVPkDQAtQkeaBfZ9iZ3hpwkT16fLly6fLRd5YaNOmzWY0/SgHJ6XRSTwv6ACmYP3YHkQg38Gasrv4Xo/v70vK1cfH50NJwTZo0CC8WbNm4QMGDNgxdOjQvdkpW0nhPkvaNyYmZr7834oVK9YPHz58v5TXpEmTqHr16kXJcXC8AzjuRaR6P5V6YD3bNaxvy7Szs9uF7yeANsADUE8t9n2KneEXTG4/tGvXLu67774bqWXj8umnn47p3LnzTrT3gryWGhmcFCfxkjACc2EQdGJQYA4+K1CgwKG6deu+JWvTFi9evEkMSU4ZhzLPiOGZN2/eFlnTVrt27Uykek+g3l/B1Nx0c3NL8/DwmPqktWtM/bLvU+z7V0FRR0fHKNypPShatOhHuHsKCg0NXWjohkUmyoCAgCXdu3cPzZ079yHZ9YRQ906014cGxsDFSdwF43WFXPA9PT0vI9qRKobgxIkTkw15zEqEZ+bMmdsQuUl3cXG57ezsfAkbBpajvTa8qLLvUzwfj2uQDWghYWdwGjt6vsbd0JlKlSqlIHIRJBOk3DmJMchpkRUxXDLxtW3bNqhkyZJpEiaX+iNkfRSmZS3a1RBYACUaGIMVJ40eiFZcat26dVi2YdEqkp5CCuoojNoXMGyNgcmLwnHLCybPh3E0yAbUBRPAFqyXSYMZuKxy2LdgEo54e3unwzDEVK9e3R+Rjg29evVau2jRosXQEoStx8sE9KyGRwyJTqebFh0dPVHKgXGaL2V36tRpU5UqVXyLFCkSi7vOLOyWOqZy+7+oRYSJYAMYA6oCC/AI0cAYrDhpPFy4cOFMY1q31r59+1WYf44BkxdEQ+OWF0yK26ivvsAD7RqCLmAMWAJ8QSjIAu+Bq4pfgP6/PPLnP/ztf7MUgar8BWAE6ADqPkOeXCsGhqJ+AN/kypUrMC4uboSWjUtwcPAkrOeRCOrJR4w3jluKooHhiTSgPfUUJyEPMAd8hKiCREN1ZcuW3Y9I5ap169bNM7TUkjxnas2aNUslyop2BGLtSybadU/dvEwADjQwFEUDw8GsrXZT7LsOoAWYAvaAj8AXMAA/yltyYIH+J4jW6CTVix0/QS1bttwj25xnzZq1QbY+y4Mf/74l+kUWzf+9nI0bN66W8qdPn75FjteiRQvfOnXqBBcrViwe26oz5JlMUj/U9RfU9VNlVv5g73wgI03vOL5399qd686Rc1OdtsONmmpo6CIYTCsapO3S0G1tSQkNVi22pBq1augirWBLWsGWwSElCEKDlEF6DbZnS5xRuevopXcpaaXtnEvbOaa/Pd/j5/Hm3cltdvJk8/nyZWee93km+76/3zOf9/nzzpKAZSxl4S4AgxAAIwEwCA1C7VNqL2euCAamBDh1QULDvKGH1v3RPZDu7dRpXdmOfT+r3BbOv+Xaek1Qsq7PWzTXBSjX9XeVs9aqATDEPgJgMgTAsKf+KRUAw3lk6heAQY8R+wBM1Vw55qPOx0/zXJKcCIDhyxBxzRAA09VQcb/aMdefHoBBCIDh/03sI7QZ+bBs2RyqdwTAlOUk/HuOAJiijgdgEADDeXzsfhQBMDAEATasUZNDc8e8Z55UWc+5ofdumPfd+x3zjMqa7v2mA52mRnIO1P5VAOaJCgEwlcHPrbOIl9hHXI/B/oeagpNEXhCgpI3AjOj1tNslcVfwkzYCk+gBVqvmIb13UzBTAWCeiBAAo4dS9iflcxOAyRKxj7gepQj/Q/e1TbLsnklROgJgito+6TWhY8opADOusvD/vW2eB2COErLtvr/T6GAM2jxjnVBD7ld1ACZ6MWWB2EYdSnByINDY0YjKSMYamBGN0qyZW+ZuBsDcUlk78KH5FQDmKKHnkqT73HPJ3pEQQyd0w7ylttbdzr85857c1Ht55eR9Hb/pbkSm9d6Bji+6G5MN1/4YAIMQABNjmzl1WAtqryMgCQFmTMCyrA60pnpZANNRvdBX6MSOEnrxpULnp4uNg1SIoROaVF5NKZcW3LRszbwpT+v4NY16XtXxd5WzVeXhqm5GpgU719XerI6f003HOACDEAATU5sNdXofKh+sc+m5juue+UF4J5gBMGMqC2FlyTxFJ4ayAObBW51eJBBTiixn6wKOXJCHlZQppET5VjV77SvH06aQdsx3UnJ2E4DhwWkIgImpzXXztiCmoo7r0AFJx7ys8jmVjan8unkvAJhNDT1fc4uEW6o/rMeRdxmBQf0ATCrEsIh3xNwRhCwLRIay1sCozpTye005mAYwRXNP7dadV5X7AAxfmAiAiabNojq7PXWKm36+W9CyozUreY3C7MsrApENV2dSwLKl13lBS9u1P842atQvwKRCDLuQyvo166Z7BEItDWCUu4fK00WBzG4awKjdnurXQ5NvMQmAQQBM9AJgAJgQYs45wNSCm4whjaI2UgCmKiCpBWveekcATE6wM5MygjNJvkUmAAYBMAAMih9gQog5xwBzR22U3ChnyzzvAGZdo6vVYB1b4hbx3nAA0zYXVN7Q67LKSxqFXSHfIhQAg/gpAQAGxQ8wIcScU4DJqy85dFOzG24dzLQApadjl3XslnnPLchdcqM0XR1fVZ1Vvdd2009F1sDQzyKuRx8iwAAYACYSiGlH2l5FU0mVjN8eS/R6WMcW3LRTKZiGKgc7m0ph+wAM/SwavACYGATAbH3ik5/u4kd75Mro+4KVGCCmTc4CMFyzkxfipwR2dYd0nlQ0t85gMLT15YtPyB5i+CkBAAbFHfuhENuoZzQHvqgh4KdZw+bb7qmi2QJggJg4BcBw/hACYKSCvti3NCKzqp0KU+aqys/aCEtNcDZvXnO/7XJLiwzPnAAYIAaA4fwhBMBk71CY0O+Y3BPUHLgdC03zskZs6gKCafc7KVVz2fmjKgnaqan9SX3erD5/SdszN/X3dfWQvKbKbqleztyXABggJvKpX6Z9ARh+SgABMMdQzu1amAoAomHeEDQ8MLflXXMvw91HlLed76v9dX2eB6jr+ru0a2KAAmCAmMHnLdO+2QJg+MJEAAxiDQwQE2mcMO2L6COzhQgGBMAAMZHHCdO+iD4yW4hgQAAMEBN1nDDti/jOQuypRwAM/uZ3vvu6vuDjjxPE9eBcI64HAmBwfeGXrWeeeeafmgo5E3GCuB6ca8T1QAAM8PJXO+ejUcYJ4npwrhE/JeCFABh88wc/fkPwMszUL3mLiP3oxTZqBMDgG9//0ZvPPvvsm4IXRN4iFLcAGMSD7PDUzPf+YvDyJz2TBNGJIxS3ABgEwOCvf2vqbYOX1wUvTP3SiSNiP14BMAiAwX/480Hva9/49jtJkvxeD4Qjb+MW14NzjQAYxBoY4KX6pS/vP1l4IW8RfSRCBAPXY/fFlwod/Gh/cfwrnb7g5eLFVT2xlrxFiNhHBAPXA52uDGKOBJhXW3/rfe7zX/iX4CUhThAi9hF76klOFC3AeHi5lMv9SvBCnJC3KN5zjbgeiGAAYH772hu9lz/z2XcvPf/8L8wXBuXjxwkibznXiOuBCAYARvDyqdLL7z1/+fLPzBcG6OPHCSJvOdeInxJAJCcAs9p87QN4eeGFF35ovjBo9z/1i8hblj0gtlEjrgcAI3h5sfDx/3wILxiTtyhqATAIATC/Xn/1A3gpFApT5gtmjOlHUbwCYBBCFy9e+t/HLl/uxgAvJz/1i+hH+SkBBMBsqc3z5BUzesp18VKuUyqVvmq+cMo+kbxFAAznGgEwBFeb84foxBEi9hEAA8AgRJwgROwjAAaAQcQcQsQ+erq0fI6DC4BBxBzr1shbYp/4J/YBGM4fIuYYeUbEPueQE0MwIETMATCI2Occpqp65hKZYEBo+fzFHACDiH2+s0hkggEhcpZziACYbAEwBANCxC8Ag4h9AIZEJgkQqhK/9HtRidgHYEhkOkOEmLak30PEPueQRB42NwiGsyREzHHTgYh94h+AGTP3SKhBCxFzdOCI2Cf+ARgABiFiLorzh4h9ziE/JTBsXjDPmFv690NVzK+Yd/SY5xuuTk3HjZub5h0dW3THlF39NbXvASYx3zY/0OcumQuuvGGe1Gc31TYJNVghYu6aucKN2zkUsT9hrnEO4w6uMXNHoDFvvin42DM3BCnTel1XnWnVaZmn5F3zhsqH9HrNPKE2DwKAWVP9azpm3bxtzqm8Z9433xXcDD4YECLm2sp3AOa8idhvno11mwBMz5OmgOG+2eu6+dCcV4fWC7bR3VT5Q80IWHKufM4BTE3/rrjyvKBoxgHMYpTBgBAAA8AgAMaLnxI4VYDxsLGtqZ26810dV3MA4+Xfu6eL73XFlc8JduqB2260pac2AwEwiMepKzcqyptb5ry7Obij0dSrKXWGdDOyYJ7VtK1XVXVvm8spAFNUvQXdtORdWU15fk1tDAMwT0DE/oRif0axXnLLHubckohcSp2ayuvmEbNX2dUfTQGYnNpV7uhz9dn6jFHF/gTbqAcLMGHdZggYcrkPgGmovlfZldfNB0e0PxkJwGyaEYq1D+iZW3LbnBN0HOomYMFNwfo6TcV2w7zn6j7UDXNXNyCLKjtweTiq1+vK1fv6/KLL+y19rqaHAZiTFbGvGN5S/O4Iuq8q9pcFNduK87yr09TxDd2gdxzEjOr1unKnrThuqLygNrfV/oqOr7rvv5bqPFAbAMwpAcyGLpBXQXdu+T4Apq5A8ZpQuY7VdJST4GU4CoCJXwiAWXOvR/TeRMp7NVdn5YjyvOBkNshHn4cPgrvuRBCz5ACmEyy4B2DQe+bXzT8X1FZOAGB23fdHIpiZd8fk1eacq9N2dXKK99uu3OdGydxxAHNX8OK/sxYFLf777+rpzxoAMNO6Ext3AbKsoMn1ATAV1Z9xwbTlyocUPItqW7sdfAAAMIjHqWeoF+wMnFVOjXmrzXpGTvXcsb2UKaV91SmqfC5ov+FuVhq6+TmO/mFun6C75jYeiN/p87j/Kna65n/r3/uK3+QjAswrPgddbI85rykeU9ezuFmGnOpPBuWrrk5Ln+nbn1W9oj67E8EaGABGuqOA21XHuOvu5DIBxgFJR/U65ntBeS1ou6vPlE4dYEpmhGLtgML8qGd8eS88EmCUvxmLeEdVvhu27wFGHuT5Y+o3/th/V7HTMf/d/BNz8THiIISRcbXfTvFmHwBTdnkghfEs6Er/jJJypH3K/cfmeQSYnC5gmoZ0UUc/JGUpH9bJeG9M7ycp5YnaHtNneZVVn0W86NECYObUwYbSiErfIzAhuO8FIzDjKX1EkgEw5Bmx/775N+HC1hMEmKrf1RrGfp8jMF0tkfBacXV2dKxXzn1HxQAwPIn3TAqAQQDMlZRh8BHzoY7LBhitCQg66YmgTitYJ5Dorm8DgCH2M3TSDyFN2x20FyyczQs67vUBMA+1rjhO3N984OosqT1/Uz2vY3IADAADwKCPLgDGT/s2tOhwX5108kiAMQl+uoKUpZRdSFW93jLPux1HVwYBMEz9EvsZMDIpWN9QbG5rurPUJ8BUBEFbAqEdOdyFtKPyFeXKVAQjMFHE/jIAA8AgYu6Yz4EJVTXfdo8kSLLraHpI0i7AObkc7hrRsTfV/s2gbk3mxu0JiNjPfsS/4nVWsTljHsquY+8JvqWCq19NieecgKWu/Bj+f3t3bCQoCAZglEIsxD4ohEIsy4BCbMSc5J/RUUTei00WPjjm3JXmOzDZv1l+GAcYNGf8jKH2jaEDzC1iAM05wKD9mKsEBCEGfE7dmjWG2te/78DMxFUC6NcBBh04wFjIFgHo176H9h1gLGSLAFcJ6Ne+p33z5gAjCFcJYAMyfl79an8srhKIHRNeLlYtKGzi/tcU7evfD2Jxgk3cOkP7+jeB5gOdaM5VAuZO+64S6EFYYBP3u39o3xjiAINO/N6adat9/WsfMaAT84GxHoOrBLA48eoX61b72rfw2BNgEwftW3gA9lFwgAH+8Dl17KPaxwEG35PAuvXqF+1rXwwWJ+gEtI8YzAc6Ae0jBswHOsGrX+3jKgEsTnRiPjDW5gMxoBPMh7HGfCAGdIL5MNZ8aT5KcOlTeeHZLXg2P/Ts2rxK6/Hs0vw5Wk3g1a9NHO1rHwCbOGgfAJs4aB/w6terX7Sv/WsAAAAAAAAAAAAAAAAATktKP02n3o/iAAAAAElFTkSuQmCC" width="560" height="161" class="img_SS3x"></p><p>Besides creating the proxy component, the transform also defines the <code>accept</code> function with a piece of code to force React to re-render the component. This way, we can hot reload rendering code without losing any of the app's state.</p><p>The default <a href="https://github.com/facebook/react-native/blob/master/packager/transformer.js#L92-L95" target="_blank" rel="noopener noreferrer">transformer</a> that comes with React Native uses the <code>babel-preset-react-native</code>, which is <a href="https://github.com/facebook/react-native/blob/master/babel-preset/configs/hmr.js#L24-L31" target="_blank" rel="noopener noreferrer">configured</a> to use <code>react-transform</code> the same way you'd use it on a React web project that uses Webpack.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="redux-stores">Redux Stores<a class="hash-link" href="#redux-stores" title="Direct link to heading">​</a></h2><p>To enable Hot Reloading on <a href="http://redux.js.org/" target="_blank" rel="noopener noreferrer">Redux</a> stores you will just need to use the HMR API similarly to what you'd do on a web project that uses Webpack:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token comment" style="color:#93a1a1">// configureStore.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#657b83">{</span><span class="token imports"> createStore</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> applyMiddleware</span><span class="token imports punctuation" style="color:#657b83">,</span><span class="token imports"> compose </span><span class="token imports punctuation" style="color:#657b83">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'redux'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports">thunk</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'redux-thunk'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">import</span><span class="token plain"> </span><span class="token imports">reducer</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">from</span><span class="token plain"> </span><span class="token string" style="color:#8dc891">'../reducers'</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token keyword module" style="color:#c5a5c5">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#c5a5c5">default</span><span class="token plain"> </span><span class="token keyword" style="color:#c5a5c5">function</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">configureStore</span><span class="token punctuation" style="color:#657b83">(</span><span class="token parameter">initialState</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> store </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">createStore</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    reducer</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    initialState</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token function" style="color:#79b6f2">applyMiddleware</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">thunk</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">hot</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    module</span><span class="token punctuation" style="color:#657b83">.</span><span class="token property-access">hot</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">accept</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">(</span><span class="token punctuation" style="color:#657b83">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#fc929e">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#657b83">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      </span><span class="token keyword" style="color:#c5a5c5">const</span><span class="token plain"> nextRootReducer </span><span class="token operator" style="color:#fc929e">=</span><span class="token plain"> </span><span class="token function" style="color:#79b6f2">require</span><span class="token punctuation" style="color:#657b83">(</span><span class="token string" style="color:#8dc891">'../reducers/index'</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">.</span><span class="token keyword module" style="color:#c5a5c5">default</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">      store</span><span class="token punctuation" style="color:#657b83">.</span><span class="token method function property-access" style="color:#79b6f2">replaceReducer</span><span class="token punctuation" style="color:#657b83">(</span><span class="token plain">nextRootReducer</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">    </span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">)</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#c5a5c5">return</span><span class="token plain"> store</span><span class="token punctuation" style="color:#657b83">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#FFFFFF"><span class="token plain"></span><span class="token punctuation" style="color:#657b83">}</span><span class="token punctuation" style="color:#657b83">;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>When you change a reducer, the code to accept that reducer will be sent to the client. Then the client will realize that the reducer doesn't know how to accept itself, so it will look for all the modules that refer it and try to accept them. Eventually, the flow will get to the single store, the <code>configureStore</code> module, which will accept the HMR update.</p><h2 class="anchor anchorWithStickyNavbar_JmGV" id="conclusion">Conclusion<a class="hash-link" href="#conclusion" title="Direct link to heading">​</a></h2><p>If you are interested in helping making hot reloading better, I encourage you to read <a href="https://medium.com/@dan_abramov/hot-reloading-in-react-1140438583bf#.jmivpvmz4" target="_blank" rel="noopener noreferrer">Dan Abramov's post around the future of hot reloading</a> and to contribute. For example, Johny Days is going to <a href="https://github.com/facebook/react-native/pull/6179" target="_blank" rel="noopener noreferrer">make it work with multiple connected clients</a>. We're relying on you all to maintain and improve this feature.</p><p>With React Native, we have the opportunity to rethink the way we build apps in order to make it a great developer experience. Hot reloading is only one piece of the puzzle, what other crazy hacks can we do to make it better?</p>]]></content>
        <author>
            <name>Martín Bigio</name>
            <uri>https://twitter.com/martinbigio</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[Making React Native apps accessible]]></title>
        <id>/2015/11/23/making-react-native-apps-accessible</id>
        <link href="https://reactnative.dev/blog/2015/11/23/making-react-native-apps-accessible"/>
        <updated>2015-11-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[With the recent launch of React on web and React Native on mobile, we've provided a new front-end framework for developers to build products. One key aspect of building a robust product is ensuring that anyone can use it, including people who have vision loss or other disabilities. The Accessibility API for React and React Native enables you to make any React-powered experience usable by someone who may use assistive technology, like a screen reader for the blind and visually impaired.]]></summary>
        <content type="html"><![CDATA[<p>With the recent launch of React on web and React Native on mobile, we've provided a new front-end framework for developers to build products. One key aspect of building a robust product is ensuring that anyone can use it, including people who have vision loss or other disabilities. The Accessibility API for React and React Native enables you to make any React-powered experience usable by someone who may use assistive technology, like a screen reader for the blind and visually impaired.</p><p>For this post, we're going to focus on React Native apps. We've designed the React Accessibility API to look and feel similar to the Android and iOS APIs. If you've developed accessible applications for Android, iOS, or the web before, you should feel comfortable with the framework and nomenclature of the React AX API. For instance, you can make a UI element <em>accessible</em> (therefore exposed to assistive technology) and use <em>accessibilityLabel</em> to provide a string description for the element:</p><div class="language-jsx codeBlockContainer_mQmQ theme-code-block" style="--prism-color:#FFFFFF;--prism-background-color:#282C34"><div class="codeBlockContent_D5yF"><pre tabindex="0" class="prism-code language-jsx codeBlock_RMoD thin-scrollbar"><code class="codeBlockLines_AclH"><span class="token-line" style="color:#FFFFFF"><span class="token operator" style="color:#fc929e">&lt;</span><span class="token maybe-class-name">View</span><span class="token plain"> accessible</span><span class="token operator" style="color:#fc929e">=</span><span class="token punctuation" style="color:#657b83">{</span><span class="token boolean" style="color:#ff8b50">true</span><span class="token punctuation" style="color:#657b83">}</span><span class="token plain"> accessibilityLabel</span><span class="token operator" style="color:#fc929e">=</span><span class="token plain">”This is simple view”</span><span class="token operator" style="color:#fc929e">&gt;</span><br></span></code></pre><div class="buttonGroup_aaMX"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_z5j7" aria-hidden="true"><svg class="copyButtonIcon_FoOz" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_L0B6" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Let's walk through a slightly more involved application of the React AX API by looking at one of Facebook's own React-powered products: the <strong>Ads Manager app</strong>.</p><footer><a href="https://code.facebook.com/posts/435862739941212/making-react-native-apps-accessible/" target="_blank" rel="noopener noreferrer" class="btn">Read more</a></footer><blockquote><p>This is an excerpt. Read the rest of the post on <a href="https://code.facebook.com/posts/435862739941212/making-react-native-apps-accessible/" target="_blank" rel="noopener noreferrer">Facebook Code</a>.</p></blockquote>]]></content>
        <author>
            <name>Georgiy Kassabli</name>
            <uri>https://www.facebook.com/georgiy.kassabli</uri>
        </author>
        <category label="engineering" term="engineering"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native for Android: How we built the first cross-platform React Native app]]></title>
        <id>/2015/09/14/react-native-for-android</id>
        <link href="https://reactnative.dev/blog/2015/09/14/react-native-for-android"/>
        <updated>2015-09-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Earlier this year, we introduced React Native for iOS. React Native brings what developers are used to from React on the web — declarative self-contained UI components and fast development cycles — to the mobile platform, while retaining the speed, fidelity, and feel of native applications. Today, we're happy to release React Native for Android.]]></summary>
        <content type="html"><![CDATA[<p>Earlier this year, we introduced <a href="https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/" target="_blank" rel="noopener noreferrer">React Native for iOS</a>. React Native brings what developers are used to from React on the web — declarative self-contained UI components and fast development cycles — to the mobile platform, while retaining the speed, fidelity, and feel of native applications. Today, we're happy to release React Native for Android.</p><p>At Facebook we've been using React Native in production for over a year now. Almost exactly a year ago, our team set out to develop the <a href="https://www.facebook.com/business/news/ads-manager-app" target="_blank" rel="noopener noreferrer">Ads Manager app</a>. Our goal was to create a new app to let the millions of people who advertise on Facebook manage their accounts and create new ads on the go. It ended up being not only Facebook's first fully React Native app but also the first cross-platform one. In this post, we'd like to share with you how we built this app, how React Native enabled us to move faster, and the lessons we learned.</p><footer><a href="https://code.facebook.com/posts/1189117404435352/react-native-for-android-how-we-built-the-first-cross-platform-react-native-app/" target="_blank" rel="noopener noreferrer" class="btn">Read more</a></footer><blockquote><p>This is an excerpt. Read the rest of the post on <a href="https://code.facebook.com/posts/1189117404435352/react-native-for-android-how-we-built-the-first-cross-platform-react-native-app/" target="_blank" rel="noopener noreferrer">Facebook Code</a>.</p></blockquote>]]></content>
        <author>
            <name>Daniel Witte</name>
            <uri>https://www.facebook.com/drwitte</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[React Native: Bringing modern web techniques to mobile]]></title>
        <id>/2015/03/26/react-native-bringing-modern-web-techniques-to-mobile</id>
        <link href="https://reactnative.dev/blog/2015/03/26/react-native-bringing-modern-web-techniques-to-mobile"/>
        <updated>2015-03-26T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We introduced React to the world two years ago, and since then it's seen impressive growth, both inside and outside of Facebook. Today, even though no one is forced to use it, new web projects at Facebook are commonly built using React in one form or another, and it's being broadly adopted across the industry. Engineers are choosing to use React every day because it enables them to spend more time focusing on their products and less time fighting with their framework. It wasn't until we'd been building with React for a while, though, that we started to understand what makes it so powerful.]]></summary>
        <content type="html"><![CDATA[<p>We introduced <a href="https://code.facebook.com/projects/176988925806765/react/" target="_blank" rel="noopener noreferrer">React</a> to the world two years ago, and since then it's seen impressive growth, both inside and outside of Facebook. Today, even though no one is forced to use it, new web projects at Facebook are commonly built using React in one form or another, and it's being broadly adopted across the industry. Engineers are choosing to use React every day because it enables them to spend more time focusing on their products and less time fighting with their framework. It wasn't until we'd been building with React for a while, though, that we started to understand what makes it so powerful.</p><p>React forces us to break our applications down into discrete components, each representing a single view. These components make it easier to iterate on our products, since we don't need to keep the entire system in our head in order to make changes to one part of it. More important, though, React wraps the DOM's mutative, imperative API with a declarative one, which raises the level of abstraction and simplifies the programming model. What we've found is that when we build with React, our code is a lot more predictable. This predictability makes it so we can iterate more quickly with confidence, and our applications are a lot more reliable as a result. Additionally, it's not only easier to scale our applications when they're built with React, but we've found it's also easier to scale the size of our teams themselves.</p><p>Together with the rapid iteration cycle of the web, we've been able to build some awesome products with React, including many components of Facebook.com. Additionally, we've built amazing frameworks in JavaScript on top of React, like <a href="https://reactjs.org/blog/2015/02/20/introducing-relay-and-graphql.html" target="_blank" rel="noopener noreferrer">Relay</a>, which allows us to greatly simplify our data fetching at scale. Of course, web is only part of the story. Facebook also has widely used Android and iOS apps, which are built on top of disjointed, proprietary technology stacks. Having to build our apps on top of multiple platforms has bifurcated our engineering organization, but that's only one of the things that makes native mobile application development hard.</p><footer><a href="https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/" target="_blank" rel="noopener noreferrer" class="btn">Read more</a></footer><blockquote><p>This is an excerpt. Read the rest of the post on <a href="https://code.facebook.com/posts/1014532261909640/react-native-bringing-modern-web-techniques-to-mobile/" target="_blank" rel="noopener noreferrer">Facebook Code</a>.</p></blockquote>]]></content>
        <author>
            <name>Tom Occhino</name>
            <uri>https://github.com/tomocchino</uri>
        </author>
        <category label="announcement" term="announcement"/>
    </entry>
</feed>