1"use strict";(self.webpackChunkreact_native_website=self.webpackChunkreact_native_website||[]).push([["12995"],{87852(e,t,a){a.r(t),a.d(t,{metadata:()=>n,default:()=>d,frontMatter:()=>i,contentTitle:()=>s,toc:()=>c,assets:()=>l});var n=JSON.parse('{"id":"roottag","title":"RootTag","description":"RootTag is an opaque identifier assigned to the native root view of your React Native surface \u2014 i.e. the ReactRootView or RCTRootView instance for Android or iOS respectively. In short, it is a surface identifier.","source":"@site/versioned_docs/version-0.87/roottag.md","sourceDirName":".","slug":"/roottag","permalink":"/docs/roottag","draft":false,"unlisted":false,"editUrl":"[{\\"label\\":\\"Edit page for next release\\",\\"href\\":\\"https://github.com/facebook/react-native-website/edit/main/docs/roottag.md\\"},{\\"label\\":\\"Edit page for current release\\",\\"href\\":\\"https://github.com/facebook/react-native-website/edit/main/website/versioned_docs/version-0.87/roottag.md\\"}]","tags":[],"version":"0.87","lastUpdatedAt":1786551066000,"frontMatter":{"id":"roottag","title":"RootTag"},"sidebar":"api","previous":{"title":"ReactNativeVersion","permalink":"/docs/reactnativeversion"},"next":{"title":"Share","permalink":"/docs/share"}}'),o=a(62540),r=a(43023);a(77779),a(98263),a(38469);let i={id:"roottag",title:"RootTag"},s,l={},c=[{value:"When to use a RootTag?",id:"when-to-use-a-roottag",level:2},{value:"How to access the RootTag... if you need it",id:"how-to-access-the-roottag-if-you-need-it",level:2},{value:"Breaking Change in 0.65",id:"breaking-change-in-065",level:3},{value:"Breaking Change in 0.66",id:"breaking-change-in-066",level:3},{value:"Future Plans",id:"future-plans",level:2}];function u(e){let t={a:"a",code:"code",h2:"h2",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"RootTag"})," is an opaque identifier assigned to the native root view of your React Native surface \u2014 i.e. the ",(0,o.jsx)(t.code,{children:"ReactRootView"})," or ",(0,o.jsx)(t.code,{children:"RCTRootView"})," instance for Android or iOS respectively. In short, it is a surface identifier."]}),"\n",(0,o.jsx)(t.h2,{id:"when-to-use-a-roottag",children:"When to use a RootTag?"}),"\n",(0,o.jsxs)(t.p,{children:["For most React Native developers, you likely won\u2019t need to deal with ",(0,o.jsx)(t.code,{children:"RootTag"}),"s."]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"RootTag"}),"s are useful for when an app renders ",(0,o.jsx)(t.strong,{children:"multiple React Native root views"})," and you need to handle native API calls differently depending on the surface. An example of this is when an app is using native navigation and each screen is a separate React Native root view."]}),"\n",(0,o.jsxs)(t.p,{children:["In native navigation, every React Native root view is rendered in a platform\u2019s navigation view (e.g., ",(0,o.jsx)(t.code,{children:"Activity"})," for Android, ",(0,o.jsx)(t.code,{children:"UINavigationViewController"})," for iOS). By this, you are able to leverage the navigation paradigms of the platform such as native look and feel and navigation transitions. The functionality to interact with the native navigation APIs can be exposed to React Native via a ",(0,o.jsx)(t.a,{href:"https://reactnative.dev/docs/next/native-modules-intro",children:"native module"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["For example, to update the title bar of a screen, you would call the navigation module\u2019s API ",(0,o.jsx)(t.code,{children:'setTitle("Updated Title")'}),", but it would need to know which screen in the stack to update. A ",(0,o.jsx)(t.code,{children:"RootTag"})," is necessary here to identify the root view and its hosting container."]}),"\n",(0,o.jsxs)(t.p,{children:["Another use case for ",(0,o.jsx)(t.code,{children:"RootTag"})," is when your app needs to attribute a certain JavaScript call to native based on its originating root view. A ",(0,o.jsx)(t.code,{children:"RootTag"})," is necessary to differentiate the source of the call from different surfaces."]}),"\n",(0,o.jsx)(t.h2,{id:"how-to-access-the-roottag-if-you-need-it",children:"How to access the RootTag... if you need it"}),"\n",(0,o.jsxs)(t.p,{children:["In versions 0.65 and below, RootTag is accessed via a ",(0,o.jsx)(t.a,{href:"https://github.com/facebook/react-native/blob/v0.64.1/Libraries/ReactNative/AppContainer.js#L56",children:"legacy context"}),". To prepare React Native for Concurrent features coming in React 18 and beyond, we are migrating to the latest ",(0,o.jsx)(t.a,{href:"https://react.dev/reference/react/createContext",children:"Context API"})," via ",(0,o.jsx)(t.code,{children:"RootTagContext"})," in 0.66. Version 0.65 supports both the legacy context and the recommended ",(0,o.jsx)(t.code,{children:"RootTagContext"})," to allow developers time to migrate their call-sites. See the breaking changes summary."]}),"\n",(0,o.jsxs)(t.p,{children:["How to access ",(0,o.jsx)(t.code,{children:"RootTag"})," via the ",(0,o.jsx)(t.code,{children:"RootTagContext"}),"."]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-js",metastring:'title="JavaScript"',children:"import {RootTagContext} from 'react-native';\nimport NativeAnalytics from 'native-analytics';\nimport NativeNavigation from 'native-navigation';\n\nfunction ScreenA() {\n const rootTag = useContext(RootTagContext);\n\n const updateTitle = title => {\n NativeNavigation.setTitle(rootTag, title);\n };\n\n const handleOneEvent = () => {\n NativeAnalytics.logEvent(rootTag, 'one_event');\n };\n\n // ...\n}\n\nclass ScreenB extends React.Component {\n static contextType: typeof RootTagContext = RootTag
1Context;\n\n updateTitle(title) {\n NativeNavigation.setTitle(this.context, title);\n }\n\n handleOneEvent() {\n NativeAnalytics.logEvent(this.context, 'one_event');\n }\n\n // ...\n}\n"})}),"\n",(0,o.jsxs)(t.p,{children:["Learn more about the Context API for ",(0,o.jsx)(t.a,{href:"https://react.dev/reference/react/Component#static-contexttype",children:"classes"})," and ",(0,o.jsx)(t.a,{href:"https://react.dev/reference/react/useContext",children:"hooks"})," from the React docs."]}),"\n",(0,o.jsx)(t.h3,{id:"breaking-change-in-065",children:"Breaking Change in 0.65"}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.code,{children:"RootTagContext"})," was formerly named ",(0,o.jsx)(t.code,{children:"unstable_RootTagContext"})," and changed to ",(0,o.jsx)(t.code,{children:"RootTagContext"})," in 0.65. Please update any usages of ",(0,o.jsx)(t.code,{children:"unstable_RootTagContext"})," in your codebase."]}),"\n",(0,o.jsx)(t.h3,{id:"breaking-change-in-066",children:"Breaking Change in 0.66"}),"\n",(0,o.jsxs)(t.p,{children:["The legacy context access to ",(0,o.jsx)(t.code,{children:"RootTag"})," will be removed and replaced by ",(0,o.jsx)(t.code,{children:"RootTagContext"}),". Beginning in 0.65, we encourage developers to proactively migrate ",(0,o.jsx)(t.code,{children:"RootTag"})," accesses to ",(0,o.jsx)(t.code,{children:"RootTagContext"}),"."]}),"\n",(0,o.jsx)(t.h2,{id:"future-plans",children:"Future Plans"}),"\n",(0,o.jsxs)(t.p,{children:["With the new React Native architecture progressing, there will be future iterations to ",(0,o.jsx)(t.code,{children:"RootTag"}),", with the intention to keep the ",(0,o.jsx)(t.code,{children:"RootTag"})," type opaque and prevent thrash in React Native codebases. Please do not rely on the fact that RootTag currently aliases to a number! If your app relies on RootTags, keep an eye on our version change logs, which you can find ",(0,o.jsx)(t.a,{href:"https://github.com/facebook/react-native/blob/main/CHANGELOG.md",children:"here"}),"."]})]})}function d(e={}){let{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(u,{...e})}):u(e)}},98263(e,t,a){a.d(t,{A:()=>s});var n=a(62540);a(63696);var o=a(11750),r=a(23865);function i({children:e,className:t,hidden:a}){return(0,n.jsx)("div",{role:"tabpanel",className:(0,o.A)("tabItem_wHwb",t),hidden:a,children:e})}function s({children:e,className:t,value:a}){let{selectedValue:o,lazy:l}=(0,r.uc)(),c=a===o;return!c&&l?null:(0,n.jsx)(i,{className:t,hidden:!c,children:e})}},77779(e,t,a){a.d(t,{A:()=>h});var n=a(62540);a(63696);var o=a(11750),r=a(46065),i=a(23865),s=a(45194),l=a(83029);function c({className:e}){let{selectedValue:t,selectValue:a,tabValues:r,block:l}=(0,i.uc)(),u=[],{blockElementScrollPositionUntilNextRender:d}=(0,s.a_)(),h=e=>{let n=e.currentTarget,o=r[u.indexOf(n)].value;o!==t&&(d(n),a(o))},v=e=>{let t=null;switch(e.key){case"Enter":h(e);break;case"ArrowRight":{let a=u.indexOf(e.currentTarget)+1;t=u[a]??u[0];break}case"ArrowLeft":{let a=u.indexOf(e.currentTarget)-1;t=u[a]??u[u.length-1]}}t?.focus()};return(0,n.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,o.A)("tabs",{"tabs--block":l},e),children:r.map(({value:e,label:a,attributes:r})=>(0,n.jsx)("li",{role:"tab",tabIndex:t===e?0:-1,"aria-selected":t===e,ref:e=>{u.push(e)},onKeyDown:v,onClick:h,...r,className:(0,o.A)("tabs__item","tabItem_l0OV",r?.className,{"tabs__item--active":t===e}),children:a??e},e))})}function u({children:e}){return(0,n.jsx)("div",{className:"margin-top--md",children:e})}function d({className:e,children:t}){return(0,n.jsxs)("div",{className:(0,o.A)(r.G.tabs.container,"tabs-container","tabList_J5MA"),children:[(0,n.jsx)(c,{className:e}),(0,n.jsx)(u,{children:t})]})}function h(e){let t=(0,l.A)(),a=(0,i.OC)(e);return(0,n.jsx)(i.O_,{value:a,children:(0,n.jsx)(d,{className:e.className,children:(0,i.vT)(e.children)})},String(t))}},23865(e,t,a){a.d(t,{OC:()=>h,O_:()=>g,uc:()=>p,vT:()=>u});var n=a(62540),o=a(63696),r=a(49519),i=a(6743),s=a(88511),l=a(15396),c=a(89030);function u(e){return o.Children.toArray(e).filter(e=>"\n"!==e)}function d({value:e,tabValues:t}){return t.some(t=>t.value===e)}function h(e){let t,{defaultValue:a,queryString:n=!1,groupId:u}=e,h=function(e){let{values:t,children:a}=e;return(0,o.useMemo)(()=>{let e=t??o.Children.toArray(a).flatMap(e=>{if(!e)return[];if((0,o.isValidElement)(e)&&function(e){let{props:t}=e;return!!t&&"object"==typeof t&&"value"in t}(e))return[e];
1let t="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${t}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop. 2If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:t,attributes:a,default:n}})=>({value:e,label:t,attributes:a,default:n})),n=(0,l.XI)(e,(e,t)=>e.value===t.value);if(n.length>0)throw Error(`Docusaurus error: Duplicate values "${n.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[t,a])}(e),[v,p]=(0,o.useState)(()=>(function({defaultValue:e,tabValues:t}){if(0===t.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!d({value:e,tabValues:t}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${t.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let a=t.find(e=>e.default)??t[0];if(!a)throw Error("Unexpected error: 0 tabValues");return a.value})({defaultValue:a,tabValues:h})),[g,f]=function({queryString:e=!1,groupId:t}){let a=(0,r.W6)(),n=function({queryString:e=!1,groupId:t}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!t)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return t??null}({queryString:e,groupId:t});return[(0,s.aZ)(n),(0,o.useCallback)(e=>{if(!n)return;let t=new URLSearchParams(a.location.search);t.set(n,e),a.replace({...a.location,search:t.toString()})},[n,a])]}({queryString:n,groupId:u}),[b,x]=function({groupId:e}){let t=e?`docusaurus.tab.${e}`:null,[a,n]=(0,c.Dv)(t);return[a,(0,o.useCallback)(e=>{t&&n.set(e)},[t,n])]}({groupId:u}),m=d({value:t=g??b,tabValues:h})?t:null;return(0,i.A)(()=>{m&&p(m)},[m]),{selectedValue:v,selectValue:(0,o.useCallback)(e=>{if(!d({value:e,tabValues:h}))throw Error(`Can't select invalid tab value=${e}`);p(e),f(e),x(e)},[f,x,h]),tabValues:h,lazy:e.lazy??!1,block:e.block??!1}}let v=(0,o.createContext)(null);function p(){let e=o.useContext(v);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function g(e){return(0,n.jsx)(v.Provider,{value:e.value,children:e.children})}},38469(e,t,a){a.d(t,{A:()=>i});var n=a(93227);let o=!!n.A.canUseDOM&&navigator.platform.startsWith("Mac"),r=!!n.A.canUseDOM&&navigator.platform.startsWith("Win"),i={defaultGuide:"quickstart",defaultJsDebugger:"flipper",defaultOs:o?"macos":r?"windows":"linux",defaultPackageManager:"npm",defaultPlatform:o?"ios":"android",defaultSyntax:"functional",defaultAndroidLanguage:"java",defaultAppleLanguage:"objc",defaultJavaScriptSpecLanguages:"typescript",getDevNotesTabs:(e=["android","ios","web","windows"])=>[e.includes("android")?{label:"Android",value:"android"}:void 0,e.includes("ios")?{label:"iOS",value:"ios"}:void 0,e.includes("web")?{label:"Web",value:"web"}:void 0,e.includes("windows")?{label:"Windows",value:"windows"}:void 0].filter(Boolean),guides:[{label:"Expo Go Quickstart",value:"quickstart"},{label:"React Native CLI Quickstart",value:"native"}],oses:[{label:"macOS",value:"macos"},{label:"Windows",value:"windows"},{label:"Linux",value:"linux"}],packageManagers:[{label:"npm",value:"npm"},{label:"Yarn",value:"yarn"}],platforms:[{label:"Android",value:"android"},{label:"iOS",value:"ios"}],syntax:[{label:"Function Component",value:"functional"},{label:"Class Component",value:"classical"}],androidLanguages:[{label:"Java",value:"java"},{label:"Kotlin",value:"kotlin"}],appleLanguages:[{label:"ObjectiveC",value:"objc"},{label:"Swift",value:"swift"}],javaScriptSpecLanguages:[{label:"TypeScript",value:"typescript"},{label:"Flow",value:"flow"}],jsDebuggers:[{label:"Hermes Debugger / Expo",value:"hermes"},{label:"Flipper",value:"flipper"},{label:"New Debugger (Experimental)",value:"new-debugger"}],snackLanguages:[{label:"TypeScript",value:"typescript"},{label:"JavaScript",value:"javascript"}],defaultSnackLanguage:"typescript"}},43023(e,t,a){a.d(t,{R:()=>i,x:()=>s});var n=a(63696);let o={},r=n.createContext(o);function i(e){let t=n.useContext(r);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.