{"id":"l-rn-1-1","courseId":"react-native-apps","lang":"en","kind":"intro","summary":"Explain how a React Native app turns your components into real iOS and Android views, and what the New Architecture changed about that path.","html":"<p>Open the Notes app on your phone and drag your finger down a long list. The bounce at the top, the way text selection handles appear, the scroll that keeps coasting after you let go: all of that is the operating system’s own code. React Native’s promise is that your app gets the same behaviour, because it uses the same views.</p>\n<p>This course builds <strong>Trailhead</strong>, a hiking log. By the end you’ll have a list of past hikes, trail detail screens, a form to log a new hike, GPS tracking, photos, reminders, offline storage, and a build that runs on a real phone. Each lesson adds one piece.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">Native views, described by React</h2>\n<p>On the web, React turns your components into DOM nodes and the browser paints them. React Native swaps the bottom layer. You write components with <code dir=\"ltr\">&lt;View&gt;</code>, <code dir=\"ltr\">&lt;Text&gt;</code> and <code dir=\"ltr\">&lt;Image&gt;</code>; React works out what changed; React Native’s renderer then creates or updates <strong>native views</strong>: a <code dir=\"ltr\">UIView</code> on iOS, an <code dir=\"ltr\">android.view.View</code> on Android.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"tsx\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">src/app/index.tsx</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"Copy code\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>Copy</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { Text, View } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'react-native'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">export</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> default</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> Home</span><span style=\"color:#953800;--shiki-dark:#FFA657\">() </span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> style</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">={</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{ flex: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, justifyContent: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'center'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, alignItems: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'center'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">}</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      &#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">>Trailhead&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">Text</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    &#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">View</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  );</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n<p>No HTML, no CSS file, no DOM. The <code dir=\"ltr\">style</code> object looks like CSS, and that is on purpose, but it’s a JavaScript object that React Native’s layout engine (Yoga) reads to place native views.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 250\" role=\"img\" aria-labelledby=\"l-rn-1-1-t1\"><defs><marker id=\"arrow-l-rn-1-1-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-rn-1-1-t1\">Your React components run in Hermes on the JS thread; React computes changes; the Fabric renderer uses JSI to create native views, which the UI thread draws on iOS and Android.</title>\n  <rect class=\"d-box-primary\" x=\"20\" y=\"30\" width=\"190\" height=\"80\" rx=\"12\"/>\n  <text class=\"d-label-strong\" x=\"115\" y=\"62\" text-anchor=\"middle\">Your components</text>\n  <text class=\"d-label-muted\" x=\"115\" y=\"88\" text-anchor=\"middle\">JS thread · Hermes</text>\n  <path class=\"d-arrow\" d=\"M210 70 L270 70\" marker-end=\"url(#arrow-l-rn-1-1-1)\"/>\n  <rect class=\"d-box-accent\" x=\"275\" y=\"30\" width=\"170\" height=\"80\" rx=\"12\"/>\n  <text class=\"d-label-strong\" x=\"360\" y=\"62\" text-anchor=\"middle\">Fabric renderer</text>\n  <text class=\"d-label-muted\" x=\"360\" y=\"88\" text-anchor=\"middle\">C++ via JSI</text>\n  <path class=\"d-arrow\" d=\"M445 70 L505 70\" marker-end=\"url(#arrow-l-rn-1-1-1)\"/>\n  <rect class=\"d-box-success\" x=\"510\" y=\"30\" width=\"150\" height=\"80\" rx=\"12\"/>\n  <text class=\"d-label-strong\" x=\"585\" y=\"62\" text-anchor=\"middle\">Native views</text>\n  <text class=\"d-label-muted\" x=\"585\" y=\"88\" text-anchor=\"middle\">UI thread</text>\n  <rect class=\"d-box\" x=\"450\" y=\"160\" width=\"100\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"500\" y=\"190\" text-anchor=\"middle\">iOS</text>\n  <rect class=\"d-box\" x=\"570\" y=\"160\" width=\"100\" height=\"50\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"620\" y=\"190\" text-anchor=\"middle\">Android</text>\n  <path class=\"d-line\" d=\"M585 110 L500 160\"/>\n  <path class=\"d-line\" d=\"M585 110 L620 160\"/>\n  <text class=\"d-label-muted\" x=\"115\" y=\"150\" text-anchor=\"middle\">touch events flow back</text>\n  <path class=\"d-arrow d-dashed\" d=\"M510 100 L210 135\" marker-end=\"url(#arrow-l-rn-1-1-1)\"/>\n</svg><figcaption>From your component to pixels</figcaption></figure>\n<h2 id=\"sec-2\" tabindex=\"-1\">Two threads you’ll care about</h2>\n<p>Your JavaScript runs in <strong>Hermes</strong>, a JavaScript engine built for React Native, on its own thread. The platform’s <strong>UI thread</strong> draws views and receives touches. Keeping them apart is why a native scroll can stay smooth while your code works, and also why a long synchronous loop in JavaScript makes buttons feel dead: the touch arrives, but nobody is free to handle it.</p>\n<p>You’ll return to this in the performance lesson. For now, remember the rule of thumb: keep the JS thread free during gestures and animations.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">The New Architecture, briefly</h2>\n<p>For years, JavaScript and native code talked through a “bridge” that serialized messages to JSON and sent them in batches. The <strong>New Architecture</strong> replaced it:</p>\n<ul>\n<li><strong>JSI</strong> lets JavaScript call C++ directly and hold references to native objects.</li>\n<li><strong>Fabric</strong> is the new renderer, written in C++ and shared by both platforms.</li>\n<li><strong>TurboModules</strong> are native modules (camera, storage, sensors) loaded lazily, when first used.</li>\n</ul>\n<p>It became the default in React Native 0.76 and the only option from 0.82. You won’t configure any of it; Expo projects use it out of the box. It matters when you pick libraries: anything you install must support it, and maintained libraries do.</p>\n<aside class=\"callout callout-why\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><circle cx=\"12\" cy=\"12\" r=\"6\"/><circle cx=\"12\" cy=\"12\" r=\"2\"/></svg><span><span class=\"callout-kind\">Why this matters</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>Why this matters</span></p>\n<p>When you read a 2021 blog post that talks about “the bridge” or “bridge traffic”, it describes an architecture your app no longer has. Check the date before you copy a performance tip.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">What transfers from React, and what doesn’t</h2>\n<p>Components, props, state, hooks, context, keys: all the same. React 19 features work too. What changes is everything around React: the primitives (<code dir=\"ltr\">View</code> instead of <code dir=\"ltr\">div</code>), styling (no cascade, column-first flexbox), navigation (stacks and tabs instead of URLs in a bar), device APIs (permissions that users can refuse) and shipping (store review instead of a deploy).</p>\n<p>Next you’ll create the Trailhead project with Expo and get it running on your own phone.</p>\n","toc":[{"id":"sec-1","text":"Native views, described by React","level":2},{"id":"sec-2","text":"Two threads you’ll care about","level":2},{"id":"sec-3","text":"The New Architecture, briefly","level":2},{"id":"sec-4","text":"What transfers from React, and what doesn’t","level":2}],"takeaways":["React Native renders real platform views such as UIView on iOS and android.view.View on Android; there is no browser and no DOM.","Your JavaScript runs in the Hermes engine on its own thread, while the platform’s UI thread draws pixels and receives touches.","The New Architecture (JSI, the Fabric renderer and TurboModules) is the only architecture since React Native 0.82.","React knowledge transfers directly; what changes is the set of primitives, styling, navigation and how you ship."],"further":[{"title":"Core Components and Native Components","url":"https://reactnative.dev/docs/intro-react-native-components"},{"title":"About the New Architecture","url":"https://reactnative.dev/architecture/landing-page"}],"quiz":[{"q":"<p>A teammate says “React Native is a WebView with a nicer API.” What’s the most accurate correction?</p>","options":[{"text":"It renders HTML, but compiles it to native code ahead of time.","why":"There’s no HTML at any stage. You write React components like <code dir=\"ltr\">&lt;View&gt;</code> and <code dir=\"ltr\">&lt;Text&gt;</code>, never <code dir=\"ltr\">&lt;div&gt;</code>."},{"text":"Your components become real platform views; JavaScript describes the UI and native code draws it.","why":"Correct. React Native’s renderer creates and updates native views, which is why scrolling and text input feel like any other app."},{"text":"It uses a WebView on Android and native views on iOS.","why":"Both platforms get native views. Android is not a second-class target with a browser fallback."}],"answer":1},{"q":"<p>Trailhead runs a heavy loop in JavaScript for two seconds. What does the user most likely notice?</p>","options":[{"text":"Nothing, because JavaScript runs on the UI thread and has priority.","why":"JavaScript does not run on the UI thread. That separation is the reason it can fall behind without the OS noticing."},{"text":"The app crashes immediately with an out-of-memory error.","why":"A long loop blocks, it doesn’t allocate unbounded memory. You’d see a freeze, not a crash."},{"text":"Taps and JS-driven updates stall until the loop finishes, even though the OS keeps the app alive.","why":"Correct. The JS thread is busy, so it can’t respond to events or schedule renders. Native-driven work like a ScrollView’s own scrolling may still move."}],"answer":2},{"q":"<p>What does JSI, part of the New Architecture, give you?</p>","options":[{"text":"Direct calls between JavaScript and C++ without serializing every message to JSON.","why":"Correct. The old bridge batched JSON messages asynchronously; JSI lets JS hold references to native objects and call them directly."},{"text":"A way to write UI in Swift and Kotlin instead of JSX.","why":"You still write UI in React. JSI is plumbing underneath, and you rarely touch it yourself."},{"text":"A JavaScript engine that replaces Hermes.","why":"Hermes is still the engine. JSI is the interface engines expose to native code, not an engine."}],"answer":0}],"exercise":{"kind":"choice","multiple":true,"options":["native-views","js-thread","css-file","bridge-json","react-skills"],"correct":["native-views","js-thread","react-skills"],"title":"What's really happening on the phone?","prompt":"<p>Trailhead’s first screen shows a list of hikes and a big <strong>Log a hike</strong> button. Select <strong>every</strong> statement that is true about how that screen runs on a phone today.</p>\n","hints":["Think about what draws the pixels and where your code runs.","Remember which architecture React Native has used exclusively since 0.82.","Three statements are true."],"explanation":"<p>The list and button are real native views created by the Fabric renderer, and your JavaScript runs in Hermes on its own thread, separate from the UI thread that draws and receives touches. Your React knowledge carries over unchanged. There is no CSS file or cascade: styles are JavaScript objects. And the JSON-batching bridge belongs to the old architecture; JSI replaced it.</p>\n","checkLabels":{},"optionText":{"native-views":{"text":"The button is a real platform view, the same kind of view a Swift or Kotlin app would use.","why":"True. React Native’s renderer creates native views, not HTML elements in a WebView."},"js-thread":{"text":"If the JavaScript thread is busy with a long loop, the button stops responding to taps until it finishes.","why":"True. The touch reaches the UI thread, but the JS handler can’t run until the JS thread is free."},"css-file":{"text":"The button’s colors come from a CSS file that cascades into child components.","why":"False. Styles are plain JavaScript objects passed to each component; there’s no stylesheet cascade."},"bridge-json":{"text":"Every button press is serialized to JSON and sent over the bridge in a batch.","why":"False. That describes the legacy architecture. With the New Architecture, JSI lets JavaScript and native code call each other directly."},"react-skills":{"text":"The screen uses the same components, props, state and hooks you already know from React.","why":"True. React itself is identical; only the primitives and the platform around it change."}}},"words":525,"readMinutes":3}