this repo has no description
at main 77 kB view raw
1<!doctype html><html lang=en dir=ltr class="docs-wrapper plugin-docs plugin-id-default docs-version-0.79 docs-doc-page docs-doc-id-communication-ios" data-has-hydrated=false><meta charset=UTF-8><meta name=generator content="Docusaurus v3.8.0"><title data-rh=true>Communication between native and React Native · React Native</title><meta data-rh=true name=viewport content="width=device-width, initial-scale=1.0"><meta data-rh=true property=og:url content=https://reactnative.dev/docs/communication-ios><meta data-rh=true property=og:locale content=en><meta data-rh=true name=docusaurus_locale content=en><meta data-rh=true name=docsearch:language content=en><meta data-rh=true property=og:image content=https://reactnative.dev/img/logo-share.png><meta data-rh=true name=twitter:card content=summary_large_image><meta data-rh=true name=twitter:image content=https://reactnative.dev/img/logo-share.png><meta data-rh=true name=twitter:site content=@reactnative><meta data-rh=true name=docusaurus_version content=0.79><meta data-rh=true name=docusaurus_tag content=docs-default-0.79><meta data-rh=true name=docsearch:version content=0.79><meta data-rh=true name=docsearch:docusaurus_tag content=docs-default-0.79><meta data-rh=true property=og:title content="Communication between native and React Native · React Native"><meta data-rh=true name=description content="In Integrating with Existing Apps guide and Native UI Components guide we learn how to embed React Native in a native component and vice versa. When we mix native and React Native components, we'll eventually find a need to communicate between these two worlds. Some ways to achieve that have been already mentioned in other guides. This article summarizes available techniques."><meta data-rh=true property=og:description content="In Integrating with Existing Apps guide and Native UI Components guide we learn how to embed React Native in a native component and vice versa. When we mix native and React Native components, we'll eventually find a need to communicate between these two worlds. Some ways to achieve that have been already mentioned in other guides. This article summarizes available techniques."><link data-rh=true rel=icon href=/img/favicon.ico><link data-rh=true rel=canonical href=https://reactnative.dev/docs/communication-ios><link data-rh=true rel=alternate href=https://reactnative.dev/docs/communication-ios hreflang=en><link data-rh=true rel=alternate href=https://reactnative.dev/docs/communication-ios hreflang=x-default><link data-rh=true rel=preconnect href=https://8TDSE0OHGQ-dsn.algolia.net crossorigin=anonymous><link rel=alternate type=application/rss+xml href=/blog/rss.xml title="React Native RSS Feed"><link rel=alternate type=application/atom+xml href=/blog/atom.xml title="React Native Atom Feed"><link rel=alternate type=application/json href=/blog/feed.json title="React Native JSON Feed"><link rel=preconnect href=https://www.google-analytics.com><script>window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)},ga.l=+new Date,ga("create","UA-41298772-2","auto"),ga("send","pageview")</script><script async src=https://www.google-analytics.com/analytics.js></script><link rel=preconnect href=https://www.google-analytics.com><link rel=preconnect href=https://www.googletagmanager.com><script async src="https://www.googletagmanager.com/gtag/js?id=G-58L13S6BDP"></script><script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-58L13S6BDP",{})</script><link rel=search type=application/opensearchdescription+xml title="React Native" href=/opensearch.xml><link rel=icon href=/img/pwa/manifest-icon-512.png><link rel=manifest href=/manifest.json><meta name=theme-color content=#20232a><meta name=apple-mobile-web-app-capable content=yes><meta name=apple-mobile-web-app-status-bar-style content=#20232a><link rel=apple-touch-icon href=/img/pwa/manifest-icon-512.png><link rel=mask-icon href=/img/pwa/manifest-icon-512.png color=#06bcee><meta name=msapplication-TileImage href=/img/pwa/manifest-icon-512.png><meta name=msapplication-TileColor content=#20232a><script src=https://cdn.jsdelivr.net/npm/focus-visible@5.2.0/dist/focus-visible.min.js defer></script><script src=https://widget.surveymonkey.com/collect/website/js/tRaiETqnLgj758hTBazgd8ryO5qrZo8Exadq9qmt1wtm4_2FdZGEAKHDFEt_2BBlwwM4.js defer></script><script src=https://snack.expo.dev/embed.js defer></script><script src=https://platform.twitter.com/widgets.js async></script><link rel=stylesheet href=/assets/css/styles.883cb042.css><script src=/assets/js/runtime~main.8ac1e6f0.js defer></script><script src=/assets/js/main.341783f5.js defer></script><body class=navigation-with-keyboard><svg xmlns=http://www.w3.org/2000/svg style="display: none;"><defs> 2<symbol id=theme-svg-external-link viewBox="0 0 24 24"><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol> 3</defs></svg> 4<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||(window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light")),document.documentElement.setAttribute("data-theme-choice",t||"system")}(),function(){try{for(var[t,e]of new URLSearchParams(window.location.search).entries())if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}(),document.documentElement.setAttribute("data-announcement-bar-initially-dismissed",function(){try{return"true"===localStorage.getItem("docusaurus.announcement.dismiss")}catch(t){}return!1}())</script><div id=__docusaurus><div role=region aria-label="Skip to main content"><a class=skipToContent_oPtH href=#__docusaurus_skipToContent_fallback>Skip to main content</a></div><div class="theme-announcement-bar announcementBar_zJRd" style=background-color:#20232a;color:#fff role=banner><div class="content_bSb_ announcementBarContent_t7IR">Join us for React Conf on Oct 7-8. <a target=_blank rel="noopener noreferrer" href=https://conf.react.dev>Learn more</a>.</div></div><nav aria-label=Main class="theme-layout-navbar navbar navbar--fixed-top navbar--dark"><div class=navbar__inner><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded=false class="navbar__toggle clean-btn" type=button><svg width=30 height=30 viewBox="0 0 30 30" aria-hidden=true><path stroke=currentColor stroke-linecap=round stroke-miterlimit=10 stroke-width=2 d="M4 7h22M4 15h22M4 23h22"/></svg></button><a class=navbar__brand href=/><div class=navbar__logo><img src=/img/header_logo.svg alt="React Native" class="themedComponent_siVc themedComponent--light_hHel"><img src=/img/header_logo.svg alt="React Native" class="themedComponent_siVc themedComponent--dark_yETr"></div><b class="navbar__title text--truncate">React Native</b></a><div class="navbar__item dropdown dropdown--hoverable"><a class=navbar__link aria-haspopup=true aria-expanded=false role=button href=/docs/communication-ios>0.79</a><ul class=dropdown__menu><li><a class=dropdown__link href=/docs/next/communication-ios>Next</a><li><a aria-current=page class="dropdown__link dropdown__link--active" href=/docs/communication-ios>0.79</a><li><a class=dropdown__link href=/docs/0.78/communication-ios>0.78</a><li><a class=dropdown__link href=/docs/0.77/communication-ios>0.77</a><li><a class=dropdown__link href=/docs/0.76/communication-ios>0.76</a><li><a class=dropdown__link href=/docs/0.75/communication-ios>0.75</a><li><a class=dropdown__link href=/docs/0.74/communication-ios>0.74</a><li><a class=dropdown__link href=/docs/0.73/communication-ios>0.73</a><li><a class=dropdown__link href=/docs/0.72/communication-ios>0.72</a><li><a class=dropdown__link href=/docs/0.71/communication-ios>0.71</a><li><a class=dropdown__link href=/docs/0.70/communication-ios>0.70</a><li><a class=dropdown__link href=/versions>All versions</a></ul></div></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a href=# aria-haspopup=true aria-expanded=false role=button class=navbar__link>Development</a><ul class=dropdown__menu><li><a aria-current=page class="dropdown__link dropdown__link--active" href=/docs/getting-started>Guides</a><li><a class=dropdown__link href=/docs/components-and-apis>Components</a><li><a class=dropdown__link href=/docs/accessibilityinfo>APIs</a><li><a class=dropdown__link href=/architecture/overview>Architecture</a></ul></div><a class="navbar__item navbar__link" href=/contributing/overview>Contributing</a><a class="navbar__item navbar__link" href=/community/overview>Community</a><a class="navbar__item navbar__link" href=/showcase>Showcase</a><a class="navbar__item navbar__link" href=/blog>Blog</a><a href=https://github.com/facebook/react-native target=_blank rel="noopener noreferrer" class="navbar__item navbar__link navbar-github-link" aria-label="GitHub repository"></a><div class="toggle_ki11 colorModeToggle_Hewu"><button class="clean-btn toggleButton_MMFG toggleButtonDisabled_Uw7m darkNavbarColorModeToggle_m8pZ" type=button disabled title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_k9hJ lightToggleIcon_lgto"><path fill=currentColor d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"/></svg><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_k9hJ darkToggleIcon_U96C"><path fill=currentColor d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"/></svg><svg viewBox="0 0 24 24" width=24 height=24 aria-hidden=true class="toggleIcon_k9hJ systemToggleIcon_E5c0"><path fill=currentColor d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"/></svg></button></div><div class=navbarSearchContainer_bzqh><button type=button class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class=DocSearch-Button-Container><svg width=20 height=20 class=DocSearch-Search-Icon viewBox="0 0 20 20" aria-hidden=true><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke=currentColor fill=none fill-rule=evenodd stroke-linecap=round stroke-linejoin=round /></svg><span class=DocSearch-Button-Placeholder>Search</span></span><span class=DocSearch-Button-Keys></span></button></div></div></div><div role=presentation class=navbar-sidebar__backdrop></div></nav><div id=__docusaurus_skipToContent_fallback class="theme-layout-main main-wrapper mainWrapper_MB5r"><div class=docsWrapper__sE8><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_iEvu" type=button></button><div class=docRoot_DfVB><aside class="theme-doc-sidebar-container docSidebarContainer_c7NB"><div class=sidebarViewport_KYo0><div class=sidebar_CUen><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_jmj1 menuWithAnnouncementBar_YufC"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/getting-started>The Basics</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/environment-setup>Environment setup</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/running-on-device>Workflow</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/style>UI & Interaction</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/debugging>Debugging</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/testing-overview>Testing</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/performance>Performance</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/javascript-environment>JavaScript Runtime</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/the-new-architecture/what-is-codegen>Codegen</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/native-platform>Native Development</a></div><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" role=button aria-expanded=true href=/docs/headless-js-android>Android and iOS guides</a></div><ul class=menu__list><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item"><div class=menu__list-item-collapsible><a class=menu__link tabindex=0>Android</a></div><ul class=menu__list><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/headless-js-android>Headless JS</a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/signed-apk-android>Publishing to Google Play Store</a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/communication-android>Communication between native and React Native</a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/react-native-gradle-plugin>React Native Gradle Plugin</a></ul><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item"><div class=menu__list-item-collapsible><a class="menu__link menu__link--active" tabindex=0>iOS</a></div><ul class=menu__list><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/linking-libraries-ios>Linking Libraries</a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/running-on-simulator-ios>Running On Simulator</a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link menu__link--active" aria-current=page tabindex=0 href=/docs/communication-ios>Communication between native and React Native</a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/app-extensions>App Extensions</a><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class=menu__link tabindex=0 href=/docs/publishing-to-app-store>Publishing to Apple App Store</a></ul></ul><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class=menu__list-item-collapsible><a class="menu__link menu__link--sublist menu__link--sublist-caret" role=button aria-expanded=false href=/docs/legacy/native-modules-intro>Legacy Architecture</a></div></ul></nav></div></div></aside><main class=docMainContainer_a9sJ><div class="container padding-top--md padding-bottom--lg"><div class=row><div class="col docItemCol_Qr34"><div class=docItemContainer_tjFy><article><div class="tocCollapsible_wXna theme-doc-toc-mobile tocMobile_Ojys"><button type=button class="clean-btn tocCollapsibleButton_iI2p">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Communication between native and React Native</h1></header><p>In <a href=/docs/integration-with-existing-apps>Integrating with Existing Apps guide</a> and <a href=/docs/legacy/native-components-ios>Native UI Components guide</a> we learn how to embed React Native in a native component and vice versa. When we mix native and React Native components, we'll eventually find a need to communicate between these two worlds. Some ways to achieve that have been already mentioned in other guides. This article summarizes available techniques.</p> 5<h2 class="anchor anchorWithStickyNavbar_JmGV" id=introduction>Introduction<a href=#introduction class=hash-link aria-label="Direct link to Introduction" title="Direct link to Introduction"></a></h2> 6<p>React Native is inspired by React, so the basic idea of the information flow is similar. The flow in React is one-directional. We maintain a hierarchy of components, in which each component depends only on its parent and its own internal state. We do this with properties: data is passed from a parent to its children in a top-down manner. If an ancestor component relies on the state of its descendant, one should pass down a callback to be used by the descendant to update the ancestor.</p> 7<p>The same concept applies to React Native. As long as we are building our application purely within the framework, we can drive our app with properties and callbacks. But, when we mix React Native and native components, we need some specific, cross-language mechanisms that would allow us to pass information between them.</p> 8<h2 class="anchor anchorWithStickyNavbar_JmGV" id=properties>Properties<a href=#properties class=hash-link aria-label="Direct link to Properties" title="Direct link to Properties"></a></h2> 9<p>Properties are the most straightforward way of cross-component communication. So we need a way to pass properties both from native to React Native, and from React Native to native.</p> 10<h3 class="anchor anchorWithStickyNavbar_JmGV" id=passing-properties-from-native-to-react-native>Passing properties from native to React Native<a href=#passing-properties-from-native-to-react-native class=hash-link aria-label="Direct link to Passing properties from native to React Native" title="Direct link to Passing properties from native to React Native"></a></h3> 11<p>In order to embed a React Native view in a native component, we use <code>RCTRootView</code>. <code>RCTRootView</code> is a <code>UIView</code> that holds a React Native app. It also provides an interface between native side and the hosted app.</p> 12<p><code>RCTRootView</code> has an initializer that allows you to pass arbitrary properties down to the React Native app. The <code>initialProperties</code> parameter has to be an instance of <code>NSDictionary</code>. The dictionary is internally converted into a JSON object that the top-level JS component can reference.</p> 13<div class="language-objectivec codeBlockContainer_mQmQ theme-code-block" style=--prism-color:#FFFFFF;--prism-background-color:#282C34><div class=codeBlockTitle_kY6l>objectivec</div><div class=codeBlockContent_t_Hd><pre tabindex=0 class="prism-code language-objectivec codeBlock_RMoD thin-scrollbar" style=color:#FFFFFF;background-color:#282C34><code class=codeBlockLines_AclH><span class=token-line style=color:#FFFFFF><span class="token plain">NSArray </span><span class="token operator" style=color:#fc929e>*</span><span class="token plain">imageList </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 punctuation" style=color:#657b83>[</span><span class="token string" style=color:#8dc891>@"https://dummyimage.com/600x400/ffffff/000000.png"</span><span class="token punctuation" style=color:#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>@"https://dummyimage.com/600x400/000000/ffffff.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" style=display:inline-block></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain">NSDictionary </span><span class="token operator" style=color:#fc929e>*</span><span class="token plain">props </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 punctuation" style=color:#657b83>{</span><span class="token string" style=color:#8dc891>@"images"</span><span class="token plain"> </span><span class="token punctuation" style=color:#657b83>:</span><span class="token plain"> imageList</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">RCTRootView </span><span class="token operator" style=color:#fc929e>*</span><span class="token plain">rootView </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">RCTRootView alloc</span><span class="token punctuation" style=color:#657b83>]</span><span class="token plain"> initWithBridge</span><span class="token punctuation" style=color:#657b83>:</span><span class="token plain">bridge</span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> moduleName</span><span class="token punctuation" style=color:#657b83>:</span><span class="token string" style=color:#8dc891>@"ImageBrowserApp"</span><span class="token plain"></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> initialProperties</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><br></span></code></pre></div></div> 14<div class="language-tsx codeBlockContainer_mQmQ theme-code-block" style=--prism-color:#FFFFFF;--prism-background-color:#282C34><div class=codeBlockTitle_kY6l>tsx</div><div class=codeBlockContent_t_Hd><pre tabindex=0 class="prism-code language-tsx codeBlock_RMoD thin-scrollbar" style=color:#FFFFFF;background-color:#282C34><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 imports maybe-class-name">React</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'</span><span class="token punctuation" style=color:#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 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">Image</span><span class="token imports 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>default</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>ImageBrowserApp</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 property-access maybe-class-name">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 function" style=color:#79b6f2>renderImage</span><span class="token punctuation" style=color:#657b83>(</span><span class="token plain">imgURI</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 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 punctuation" style=color:#657b83>{</span><span class="token tag script language-javascript" style=color:#fc929e>uri</span><span class="token tag script language-javascript operator" style=color:#fc929e>:</span><span class="token tag script language-javascript" style=color:#fc929e> imgURI</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>/></span><span class="token punctuation" style=color:#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 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 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>></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">images</span><span class="token punctuation" style=color:#657b83>.</span><span class="token method function property-access" style=color:#79b6f2>map</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">renderImage</span><span class="token punctuation" style=color:#657b83>)</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>View</span><span class="token tag 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></div> 15<p><code>RCTRootView</code> also provides a read-write property <code>appProperties</code>. After <code>appProperties</code> is set, the React Native app is re-rendered with new properties. The update is only performed when the new updated properties differ from the previous ones.</p> 16<div class="language-objectivec codeBlockContainer_mQmQ theme-code-block" style=--prism-color:#FFFFFF;--prism-background-color:#282C34><div class=codeBlockTitle_kY6l>objectivec</div><div class=codeBlockContent_t_Hd><pre tabindex=0 class="prism-code language-objectivec codeBlock_RMoD thin-scrollbar" style=color:#FFFFFF;background-color:#282C34><code class=codeBlockLines_AclH><span class=token-line style=color:#FFFFFF><span class="token plain">NSArray </span><span class="token operator" style=color:#fc929e>*</span><span class="token plain">imageList </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 punctuation" style=color:#657b83>[</span><span class="token string" style=color:#8dc891>@"https://dummyimage.com/600x400/ff0000/000000.png"</span><span class="token punctuation" style=color:#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>@"https://dummyimage.com/600x400/ffffff/ff0000.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" style=display:inline-block></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain">rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">appProperties </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 punctuation" style=color:#657b83>{</span><span class="token string" style=color:#8dc891>@"images"</span><span class="token plain"> </span><span class="token punctuation" style=color:#657b83>:</span><span class="token plain"> imageList</span><span class="token punctuation" style=color:#657b83>}</span><span class="token punctuation" style=color:#657b83>;</span><br></span></code></pre></div></div> 17<p>It is fine to update properties anytime. However, updates have to be performed on the main thread. You use the getter on any thread.</p> 18<div class="theme-admonition theme-admonition-note admonition_WCGJ alert alert--secondary"><div class=admonitionHeading_GCBg><span class=admonitionIcon_L39b><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"/></svg></span>note</div><div class=admonitionContent_pbrs><p>Currently, there is a known issue where setting appProperties during the bridge startup, the change can be lost. See <a href=https://github.com/facebook/react-native/issues/20115 target=_blank rel="noopener noreferrer">https://github.com/facebook/react-native/issues/20115</a> for more information.</div></div> 19<p>There is no way to update only a few properties at a time. We suggest that you build it into your own wrapper instead.</p> 20<h3 class="anchor anchorWithStickyNavbar_JmGV" id=passing-properties-from-react-native-to-native>Passing properties from React Native to native<a href=#passing-properties-from-react-native-to-native class=hash-link aria-label="Direct link to Passing properties from React Native to native" title="Direct link to Passing properties from React Native to native"></a></h3> 21<p>The problem exposing properties of native components is covered in detail in <a href=/docs/legacy/native-components-ios#properties>this article</a>. In short, export properties with <code>RCT_CUSTOM_VIEW_PROPERTY</code> macro in your custom native component, then use them in React Native as if the component was an ordinary React Native component.</p> 22<h3 class="anchor anchorWithStickyNavbar_JmGV" id=limits-of-properties>Limits of properties<a href=#limits-of-properties class=hash-link aria-label="Direct link to Limits of properties" title="Direct link to Limits of properties"></a></h3> 23<p>The main drawback of cross-language properties is that they do not support callbacks, which would allow us to handle bottom-up data bindings. Imagine you have a small RN view that you want to be removed from the native parent view as a result of a JS action. There is no way to do that with props, as the information would need to go bottom-up.</p> 24<p>Although we have a flavor of cross-language callbacks (<a href=/docs/legacy/native-modules-ios#callbacks>described here</a>), these callbacks are not always the thing we need. The main problem is that they are not intended to be passed as properties. Rather, this mechanism allows us to trigger a native action from JS, and handle the result of that action in JS.</p> 25<h2 class="anchor anchorWithStickyNavbar_JmGV" id=other-ways-of-cross-language-interaction-events-and-native-modules>Other ways of cross-language interaction (events and native modules)<a href=#other-ways-of-cross-language-interaction-events-and-native-modules class=hash-link aria-label="Direct link to Other ways of cross-language interaction (events and native modules)" title="Direct link to Other ways of cross-language interaction (events and native modules)"></a></h2> 26<p>As stated in the previous chapter, using properties comes with some limitations. Sometimes properties are not enough to drive the logic of our app and we need a solution that gives more flexibility. This chapter covers other communication techniques available in React Native. They can be used for internal communication (between JS and native layers in RN) as well as for external communication (between RN and the 'pure native' part of your app).</p> 27<p>React Native enables you to perform cross-language function calls. You can execute custom native code from JS and vice versa. Unfortunately, depending on the side we are working on, we achieve the same goal in different ways. For native - we use events mechanism to schedule an execution of a handler function in JS, while for React Native we directly call methods exported by native modules.</p> 28<h3 class="anchor anchorWithStickyNavbar_JmGV" id=calling-react-native-functions-from-native-events>Calling React Native functions from native (events)<a href=#calling-react-native-functions-from-native-events class=hash-link aria-label="Direct link to Calling React Native functions from native (events)" title="Direct link to Calling React Native functions from native (events)"></a></h3> 29<p>Events are described in detail in <a href=/docs/legacy/native-components-ios#events>this article</a>. Note that using events gives us no guarantees about execution time, as the event is handled on a separate thread.</p> 30<p>Events are powerful, because they allow us to change React Native components without needing a reference to them. However, there are some pitfalls that you can fall into while using them:</p> 31<ul> 32<li>As events can be sent from anywhere, they can introduce spaghetti-style dependencies into your project.</li> 33<li>Events share namespace, which means that you may encounter some name collisions. Collisions will not be detected statically, which makes them hard to debug.</li> 34<li>If you use several instances of the same React Native component and you want to distinguish them from the perspective of your event, you'll likely need to introduce identifiers and pass them along with events (you can use the native view's <code>reactTag</code> as an identifier).</li> 35</ul> 36<p>The common pattern we use when embedding native in React Native is to make the native component's RCTViewManager a delegate for the views, sending events back to JavaScript via the bridge. This keeps related event calls in one place.</p> 37<h3 class="anchor anchorWithStickyNavbar_JmGV" id=calling-native-functions-from-react-native-native-modules>Calling native functions from React Native (native modules)<a href=#calling-native-functions-from-react-native-native-modules class=hash-link aria-label="Direct link to Calling native functions from React Native (native modules)" title="Direct link to Calling native functions from React Native (native modules)"></a></h3> 38<p>Native modules are Objective-C classes that are available in JS. Typically one instance of each module is created per JS bridge. They can export arbitrary functions and constants to React Native. They have been covered in detail in <a href=/docs/legacy/native-modules-ios#content>this article</a>.</p> 39<p>The fact that native modules are singletons limits the mechanism in the context of embedding. Let's say we have a React Native component embedded in a native view and we want to update the native, parent view. Using the native module mechanism, we would export a function that not only takes expected arguments, but also an identifier of the parent native view. The identifier would be used to retrieve a reference to the parent view to update. That said, we would need to keep a mapping from identifiers to native views in the module.</p> 40<p>Although this solution is complex, it is used in <code>RCTUIManager</code>, which is an internal React Native class that manages all React Native views.</p> 41<p>Native modules can also be used to expose existing native libraries to JS. The <a href=https://github.com/michalchudziak/react-native-geolocation target=_blank rel="noopener noreferrer">Geolocation library</a> is a living example of the idea.</p> 42<div class="theme-admonition theme-admonition-caution admonition_WCGJ alert alert--warning"><div class=admonitionHeading_GCBg><span class=admonitionIcon_L39b><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"/></svg></span>caution</div><div class=admonitionContent_pbrs><p>All native modules share the same namespace. Watch out for name collisions when creating new ones.</div></div> 43<h2 class="anchor anchorWithStickyNavbar_JmGV" id=layout-computation-flow>Layout computation flow<a href=#layout-computation-flow class=hash-link aria-label="Direct link to Layout computation flow" title="Direct link to Layout computation flow"></a></h2> 44<p>When integrating native and React Native, we also need a way to consolidate two different layout systems. This section covers common layout problems and provides a brief description of mechanisms to address them.</p> 45<h3 class="anchor anchorWithStickyNavbar_JmGV" id=layout-of-a-native-component-embedded-in-react-native>Layout of a native component embedded in React Native<a href=#layout-of-a-native-component-embedded-in-react-native class=hash-link aria-label="Direct link to Layout of a native component embedded in React Native" title="Direct link to Layout of a native component embedded in React Native"></a></h3> 46<p>This case is covered in <a href=/docs/legacy/native-components-ios#styles>this article</a>. To summarize, since all our native react views are subclasses of <code>UIView</code>, most style and size attributes will work like you would expect out of the box.</p> 47<h3 class="anchor anchorWithStickyNavbar_JmGV" id=layout-of-a-react-native-component-embedded-in-native>Layout of a React Native component embedded in native<a href=#layout-of-a-react-native-component-embedded-in-native class=hash-link aria-label="Direct link to Layout of a React Native component embedded in native" title="Direct link to Layout of a React Native component embedded in native"></a></h3> 48<h4 class="anchor anchorWithStickyNavbar_JmGV" id=react-native-content-with-fixed-size>React Native content with fixed size<a href=#react-native-content-with-fixed-size class=hash-link aria-label="Direct link to React Native content with fixed size" title="Direct link to React Native content with fixed size"></a></h4> 49<p>The general scenario is when we have a React Native app with a fixed size, which is known to the native side. In particular, a full-screen React Native view falls into this case. If we want a smaller root view, we can explicitly set RCTRootView's frame.</p> 50<p>For instance, to make an RN app 200 (logical) pixels high, and the hosting view's width wide, we could do:</p> 51<div class="language-objectivec codeBlockContainer_mQmQ theme-code-block" style=--prism-color:#FFFFFF;--prism-background-color:#282C34><div class=codeBlockTitle_kY6l>SomeViewController.m</div><div class=codeBlockContent_t_Hd><pre tabindex=0 class="prism-code language-objectivec codeBlock_RMoD thin-scrollbar" style=color:#FFFFFF;background-color:#282C34><code class=codeBlockLines_AclH><span class=token-line style=color:#FFFFFF><span class="token operator" style=color:#fc929e>-</span><span class="token plain"> </span><span class="token punctuation" style=color:#657b83>(</span><span class="token keyword" style=color:#c5a5c5>void</span><span class="token punctuation" style=color:#657b83>)</span><span class="token plain">viewDidLoad</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 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"> RCTRootView </span><span class="token operator" style=color:#fc929e>*</span><span class="token plain">rootView </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">RCTRootView alloc</span><span class="token punctuation" style=color:#657b83>]</span><span class="token plain"> initWithBridge</span><span class="token punctuation" style=color:#657b83>:</span><span class="token plain">bridge</span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> moduleName</span><span class="token punctuation" style=color:#657b83>:</span><span class="token plain">appName</span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> initialProperties</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"> rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">frame </span><span class="token operator" style=color:#fc929e>=</span><span class="token plain"> </span><span class="token function" style=color:#79b6f2>CGRectMake</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 keyword" style=color:#c5a5c5>self</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">width</span><span class="token punctuation" style=color:#657b83>,</span><span class="token plain"> </span><span class="token number" style=color:#5a9bcf>200</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" style=color:#c5a5c5>self</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">view addSubview</span><span class="token punctuation" style=color:#657b83>:</span><span class="token plain">rootView</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><br></span></code></pre></div></div> 52<p>When we have a fixed size root view, we need to respect its bounds on the JS side. In other words, we need to ensure that the React Native content can be contained within the fixed-size root view. The easiest way to ensure this is to use Flexbox layout. If you use absolute positioning, and React components are visible outside the root view's bounds, you'll get overlap with native views, causing some features to behave unexpectedly. For instance, 'TouchableHighlight' will not highlight your touches outside the root view's bounds.</p> 53<p>It's totally fine to update root view's size dynamically by re-setting its frame property. React Native will take care of the content's layout.</p> 54<h4 class="anchor anchorWithStickyNavbar_JmGV" id=react-native-content-with-flexible-size>React Native content with flexible size<a href=#react-native-content-with-flexible-size class=hash-link aria-label="Direct link to React Native content with flexible size" title="Direct link to React Native content with flexible size"></a></h4> 55<p>In some cases we'd like to render content of initially unknown size. Let's say the size will be defined dynamically in JS. We have two solutions to this problem.</p> 56<ol> 57<li>You can wrap your React Native view in a <code>ScrollView</code> component. This guarantees that your content will always be available and it won't overlap with native views.</li> 58<li>React Native allows you to determine, in JS, the size of the RN app and provide it to the owner of the hosting <code>RCTRootView</code>. The owner is then responsible for re-laying out the subviews and keeping the UI consistent. We achieve this with <code>RCTRootView</code>'s flexibility modes.</li> 59</ol> 60<p><code>RCTRootView</code> supports 4 different size flexibility modes:</p> 61<div class="language-objectivec codeBlockContainer_mQmQ theme-code-block" style=--prism-color:#FFFFFF;--prism-background-color:#282C34><div class=codeBlockTitle_kY6l>RCTRootView.h</div><div class=codeBlockContent_t_Hd><pre tabindex=0 class="prism-code language-objectivec codeBlock_RMoD thin-scrollbar" style=color:#FFFFFF;background-color:#282C34><code class=codeBlockLines_AclH><span class=token-line style=color:#FFFFFF><span class="token keyword" style=color:#c5a5c5>typedef</span><span class="token plain"> </span><span class="token function" style=color:#79b6f2>NS_ENUM</span><span class="token punctuation" style=color:#657b83>(</span><span class="token plain">NSInteger</span><span class="token punctuation" style=color:#657b83>,</span><span class="token plain"> RCTRootViewSizeFlexibility</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"> RCTRootViewSizeFlexibilityNone </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"> RCTRootViewSizeFlexibilityWidth</span><span class="token punctuation" style=color:#657b83>,</span><span class="token plain"></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> RCTRootViewSizeFlexibilityHeight</span><span class="token punctuation" style=color:#657b83>,</span><span class="token plain"></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> RCTRootViewSizeFlexibilityWidthAndHeight</span><span class="token punctuation" style=color:#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></div> 62<p><code>RCTRootViewSizeFlexibilityNone</code> is the default value, which makes a root view's size fixed (but it still can be updated with <code>setFrame:</code>). The other three modes allow us to track React Native content's size updates. For instance, setting mode to <code>RCTRootViewSizeFlexibilityHeight</code> will cause React Native to measure the content's height and pass that information back to <code>RCTRootView</code>'s delegate. An arbitrary action can be performed within the delegate, including setting the root view's frame, so the content fits. The delegate is called only when the size of the content has changed.</p> 63<div class="theme-admonition theme-admonition-caution admonition_WCGJ alert alert--warning"><div class=admonitionHeading_GCBg><span class=admonitionIcon_L39b><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"/></svg></span>caution</div><div class=admonitionContent_pbrs><p>Making a dimension flexible in both JS and native leads to undefined behavior. For example - don't make a top-level React component's width flexible (with <code>flexbox</code>) while you're using <code>RCTRootViewSizeFlexibilityWidth</code> on the hosting <code>RCTRootView</code>.</div></div> 64<p>Let's look at an example.</p> 65<div class="language-objectivec codeBlockContainer_mQmQ theme-code-block" style=--prism-color:#FFFFFF;--prism-background-color:#282C34><div class=codeBlockTitle_kY6l>FlexibleSizeExampleView.m</div><div class=codeBlockContent_t_Hd><pre tabindex=0 class="prism-code language-objectivec codeBlock_RMoD thin-scrollbar" style=color:#FFFFFF;background-color:#282C34><code class=codeBlockLines_AclH><span class=token-line style=color:#FFFFFF><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">instancetype</span><span class="token punctuation" style=color:#657b83>)</span><span class="token plain">initWithFrame</span><span class="token punctuation" style=color:#657b83>:</span><span class="token punctuation" style=color:#657b83>(</span><span class="token plain">CGRect</span><span class="token punctuation" style=color:#657b83>)</span><span class="token plain">frame</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 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"> _rootView </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">RCTRootView alloc</span><span class="token punctuation" style=color:#657b83>]</span><span class="token plain"> initWithBridge</span><span class="token punctuation" style=color:#657b83>:</span><span class="token plain">bridge</span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> moduleName</span><span class="token punctuation" style=color:#657b83>:</span><span class="token string" style=color:#8dc891>@"FlexibilityExampleApp"</span><span class="token plain"></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> initialProperties</span><span class="token punctuation" style=color:#657b83>:</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 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"> _rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">delegate </span><span class="token operator" style=color:#fc929e>=</span><span class="token plain"> </span><span class="token keyword" style=color:#c5a5c5>self</span><span class="token punctuation" style=color:#657b83>;</span><span class="token plain"></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> _rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">sizeFlexibility </span><span class="token operator" style=color:#fc929e>=</span><span class="token plain"> RCTRootViewSizeFlexibilityHeight</span><span class="token punctuation" style=color:#657b83>;</span><span class="token plain"></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> _rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">frame </span><span class="token operator" style=color:#fc929e>=</span><span class="token plain"> </span><span class="token function" style=color:#79b6f2>CGRectMake</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 keyword" style=color:#c5a5c5>self</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">frame</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">size</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">width</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 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 macro property directive-hash" style=color:#2aa198>#</span><span class="token macro property directive keyword" style=color:#c5a5c5>pragma</span><span class="token macro property" style=color:#2aa198> </span><span class="token macro property expression" style=color:#2aa198>mark </span><span class="token macro property expression operator" style=color:#fc929e>-</span><span class="token macro property expression" style=color:#2aa198> RCTRootViewDelegate</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"> </span><span class="token punctuation" style=color:#657b83>(</span><span class="token keyword" style=color:#c5a5c5>void</span><span class="token punctuation" style=color:#657b83>)</span><span class="token plain">rootViewDidChangeIntrinsicSize</span><span class="token punctuation" style=color:#657b83>:</span><span class="token punctuation" style=color:#657b83>(</span><span class="token plain">RCTRootView </span><span class="token operator" style=color:#fc929e>*</span><span class="token punctuation" style=color:#657b83>)</span><span class="token plain">rootView</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"> CGRect newFrame </span><span class="token operator" style=color:#fc929e>=</span><span class="token plain"> rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">frame</span><span class="token punctuation" style=color:#657b83>;</span><span class="token plain"></span><br></span><span class=token-line style=color:#FFFFFF><span class="token plain"> newFrame</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">size </span><span class="token operator" style=color:#fc929e>=</span><span class="token plain"> rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">intrinsicContentSize</span><span class="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"> rootView</span><span class="token punctuation" style=color:#657b83>.</span><span class="token plain">frame </span><span class="token operator" style=color:#fc929e>=</span><span class="token plain"> newFrame</span><span class="token punctuation" style=color:#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></div> 66<p>In the example we have a <code>FlexibleSizeExampleView</code> view that holds a root view. We create the root view, initialize it and set the delegate. The delegate will handle size updates. Then, we set the root view's size flexibility to <code>RCTRootViewSizeFlexibilityHeight</code>, which means that <code>rootViewDidChangeIntrinsicSize:</code> method will be called every time the React Native content changes its height. Finally, we set the root view's width and position. Note that we set there height as well, but it has no effect as we made the height RN-dependent.</p> 67<p>You can checkout full source code of the example <a href=https://github.com/facebook/react-native/blob/main/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.mm target=_blank rel="noopener noreferrer">here</a>.</p> 68<p>It's fine to change root view's size flexibility mode dynamically. Changing flexibility mode of a root view will schedule a layout recalculation and the delegate <code>rootViewDidChangeIntrinsicSize:</code> method will be called once the content size is known.</p> 69<div class="theme-admonition theme-admonition-note admonition_WCGJ alert alert--secondary"><div class=admonitionHeading_GCBg><span class=admonitionIcon_L39b><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"/></svg></span>note</div><div class=admonitionContent_pbrs><p>React Native layout calculation is performed on a separate thread, while native UI view updates are done on the main thread. 70This may cause temporary UI inconsistencies between native and React Native. This is a known problem and our team is working on synchronizing UI updates coming from different sources.</div></div> 71<div class="theme-admonition theme-admonition-note admonition_WCGJ alert alert--secondary"><div class=admonitionHeading_GCBg><span class=admonitionIcon_L39b><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"/></svg></span>note</div><div class=admonitionContent_pbrs><p>React Native does not perform any layout calculations until the root view becomes a subview of some other views. 72If you want to hide React Native view until its dimensions are known, add the root view as a subview and make it initially hidden (use <code>UIView</code>'s <code>hidden</code> property). Then change its visibility in the delegate method.</div></div></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class=editButtons_t0bR><a href=https://github.com/facebook/react-native-website/edit/main/docs/communication-ios.md target=_blank rel="noopener noreferrer" class=theme-edit-this-page><svg fill=currentColor height=20 width=20 viewBox="0 0 40 40" class=iconEdit_bHB7 aria-hidden=true><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"/></g></svg>Edit page for next release</a><a href=https://github.com/facebook/react-native-website/edit/main/website/versioned_docs/version-0.79/communication-ios.md target=_blank rel="noopener noreferrer" class=theme-edit-this-page><svg fill=currentColor height=20 width=20 viewBox="0 0 40 40" class=iconEdit_bHB7 aria-hidden=true><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"/></g></svg>Edit page for current release</a></div><div class=lastUpdated_VsjB><span class=theme-last-updated>Last updated<!-- --> on <b><time datetime=2025-04-14T14:14:17.000Z itemprop=dateModified>Apr 14, 2025</time></b></span></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href=/docs/running-on-simulator-ios><div class=pagination-nav__sublabel>Previous</div><div class=pagination-nav__label>Running On Simulator</div></a><a class="pagination-nav__link pagination-nav__link--next" href=/docs/app-extensions><div class=pagination-nav__sublabel>Next</div><div class=pagination-nav__label>App Extensions</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_XG6w thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href=#introduction class="table-of-contents__link toc-highlight">Introduction</a><li><a href=#properties class="table-of-contents__link toc-highlight">Properties</a><ul><li><a href=#passing-properties-from-native-to-react-native class="table-of-contents__link toc-highlight">Passing properties from native to React Native</a><li><a href=#passing-properties-from-react-native-to-native class="table-of-contents__link toc-highlight">Passing properties from React Native to native</a><li><a href=#limits-of-properties class="table-of-contents__link toc-highlight">Limits of properties</a></ul><li><a href=#other-ways-of-cross-language-interaction-events-and-native-modules class="table-of-contents__link toc-highlight">Other ways of cross-language interaction (events and native modules)</a><ul><li><a href=#calling-react-native-functions-from-native-events class="table-of-contents__link toc-highlight">Calling React Native functions from native (events)</a><li><a href=#calling-native-functions-from-react-native-native-modules class="table-of-contents__link toc-highlight">Calling native functions from React Native (native modules)</a></ul><li><a href=#layout-computation-flow class="table-of-contents__link toc-highlight">Layout computation flow</a><ul><li><a href=#layout-of-a-native-component-embedded-in-react-native class="table-of-contents__link toc-highlight">Layout of a native component embedded in React Native</a><li><a href=#layout-of-a-react-native-component-embedded-in-native class="table-of-contents__link toc-highlight">Layout of a React Native component embedded in native</a></ul></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Develop</div><ul class="footer__items clean-list"><li class=footer__item><a class=footer__link-item href=/docs/getting-started>Guides</a><li class=footer__item><a class=footer__link-item href=/docs/components-and-apis>Components</a><li class=footer__item><a class=footer__link-item href=/docs/accessibilityinfo>APIs</a><li class=footer__item><a class=footer__link-item href=/architecture/overview>Architecture</a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Participate</div><ul class="footer__items clean-list"><li class=footer__item><a class=footer__link-item href=/showcase>Showcase</a><li class=footer__item><a class=footer__link-item href=/contributing/overview>Contributing</a><li class=footer__item><a class=footer__link-item href=/community/overview>Community</a><li class=footer__item><a href=https://reactnative.directory/ target=_blank rel="noopener noreferrer" class=footer__link-item>Directory<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a><li class=footer__item><a href=https://stackoverflow.com/questions/tagged/react-native target=_blank rel="noopener noreferrer" class=footer__link-item>Stack Overflow<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Find us</div><ul class="footer__items clean-list"><li class=footer__item><a class=footer__link-item href=/blog>Blog</a><li class=footer__item><a href=https://x.com/reactnative target=_blank rel="noopener noreferrer" class=footer__link-item>X<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a><li class=footer__item><a href=https://bsky.app/profile/reactnative.dev target=_blank rel="noopener noreferrer" class=footer__link-item>Bluesky<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a><li class=footer__item><a href=https://github.com/facebook/react-native target=_blank rel="noopener noreferrer" class=footer__link-item>GitHub<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a></ul></div><div class="theme-layout-footer-column col footer__col"><div class=footer__title>Explore More</div><ul class="footer__items clean-list"><li class=footer__item><a href=https://react.dev/ target=_blank rel="noopener noreferrer" class=footer__link-item>ReactJS<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a><li class=footer__item><a href=https://opensource.fb.com/legal/privacy/ target=_blank rel="noopener noreferrer" class=footer__link-item>Privacy Policy<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a><li class=footer__item><a href=https://opensource.fb.com/legal/terms/ target=_blank rel="noopener noreferrer" class=footer__link-item>Terms of Service<svg width=13.5 height=13.5 aria-hidden=true viewBox="0 0 24 24" class=iconExternalLink_2l9O><path fill=currentColor d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></svg></a></ul></div></div><div class="footer__bottom text--center"><div class=margin-bottom--sm><a href=https://opensource.fb.com/ rel="noopener noreferrer" class=footerLogoLink_tutC><img src=/img/oss_logo.svg alt="Meta Open Source Logo" class="footer__logo themedComponent_siVc themedComponent--light_hHel"><img src=/img/oss_logo.svg alt="Meta Open Source Logo" class="footer__logo themedComponent_siVc themedComponent--dark_yETr"></a></div><div class=footer__copyright>Copyright © 2025 Meta Platforms, Inc.</div></div></div></footer></div>