1"use strict";(self.webpackChunkreact_native_website=self.webpackChunkreact_native_website||[]).push([["15039"],{5956(e,a,t){t.r(a),t.d(a,{metadata:()=>n,default:()=>c,frontMatter:()=>o,contentTitle:()=>s,toc:()=>u,assets:()=>l});var n=JSON.parse('{"id":"other-debugging-methods","title":"Other Debugging Methods","description":"This page covers how to use legacy JavaScript debugging methods. If you are getting started with a new React Native or Expo app, we recommend using React Native DevTools.","source":"@site/versioned_docs/version-0.83/other-debugging-methods.md","sourceDirName":".","slug":"/other-debugging-methods","permalink":"/docs/0.83/other-debugging-methods","draft":false,"unlisted":false,"editUrl":"[{\\"label\\":\\"Edit page for next release\\",\\"href\\":\\"https://github.com/facebook/react-native-website/edit/main/docs/other-debugging-methods.md\\"},{\\"label\\":\\"Edit page for 0.83 release\\",\\"href\\":\\"https://github.com/facebook/react-native-website/edit/main/website/versioned_docs/version-0.83/other-debugging-methods.md\\"}]","tags":[],"version":"0.83","lastUpdatedAt":1776064644000,"frontMatter":{"id":"other-debugging-methods","title":"Other Debugging Methods"},"sidebar":"docs","previous":{"title":"Debugging Release Builds","permalink":"/docs/0.83/debugging-release-builds"},"next":{"title":"Testing","permalink":"/docs/0.83/testing-overview"}}'),r=t(62540),i=t(43023);t(77779),t(98263),t(38469);let o={id:"other-debugging-methods",title:"Other Debugging Methods"},s,l={},u=[{value:"Safari Developer Tools (direct JSC debugging)",id:"safari-developer-tools-direct-jsc-debugging",level:2},{value:"Remote JavaScript Debugging (removed)",id:"remote-javascript-debugging-removed",level:2}];function d(e){let a={a:"a",admonition:"admonition",h2:"h2",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(a.p,{children:["This page covers how to use legacy JavaScript debugging methods. If you are getting started with a new React Native or Expo app, we recommend using ",(0,r.jsx)(a.a,{href:"./react-native-devtools",children:"React Native DevTools"}),"."]}),"\n",(0,r.jsx)(a.h2,{id:"safari-developer-tools-direct-jsc-debugging",children:"Safari Developer Tools (direct JSC debugging)"}),"\n",(0,r.jsxs)(a.p,{children:["You can use Safari to debug the iOS version of your app when using ",(0,r.jsx)(a.a,{href:"https://trac.webkit.org/wiki/JavaScriptCore",children:"JavaScriptCore"})," (JSC) as your app's runtime."]}),"\n",(0,r.jsxs)(a.ol,{children:["\n",(0,r.jsxs)(a.li,{children:[(0,r.jsx)(a.strong,{children:"Physical devices only"}),': Open the Settings app, and navigate to Safari > Advanced, and make sure "Web Inspector" is turned on.']}),"\n",(0,r.jsx)(a.li,{children:'On your Mac, open Safari and enable the Develop menu. This can be found under Safari > Settings..., then the Advanced tab, then selecting "Show features for web developers".'}),"\n",(0,r.jsx)(a.li,{children:'Find your device under the Develop menu, and select the "JSContext" item from the submenu. This will open Safari\'s Web Inspector, which includes Console and Sources panels similar to Chrome DevTools.'}),"\n"]}),"\n",(0,r.jsx)(a.p,{children:(0,r.jsx)(a.img,{alt:"Opening Safari Web Inspector",src:t(96056).A+"",width:"1600",height:"730"})}),"\n",(0,r.jsx)(a.admonition,{type:"tip",children:(0,r.jsxs)(a.p,{children:["While source maps may not be enabled by default, you can follow ",(0,r.jsx)(a.a,{href:"https://blog.nparashuram.com/2019/10/debugging-react-native-ios-apps-with.html",children:"this guide"})," or ",(0,r.jsx)(a.a,{href:"https://www.youtube.com/watch?v=GrGqIIz51k4",children:"video"})," to enable them and set break points at the right places in the source code."]})}),"\n",(0,r.jsx)(a.admonition,{type:"tip",children:(0,r.jsx)(a.p,{children:'Every time the app is reloaded, a new JSContext is created. Choosing "Automatically Show Web Inspectors for JSContexts" saves you from having to select the latest JSContext manually.'})}),"\n",(0,r.jsx)(a.h2,{id:"remote-javascript-debugging-removed",children:"Remote JavaScript Debugging (removed)"}),"\n",(0,r.jsxs)(a.admonition,{title:"Important",type:"warning",children:[(0,r.jsxs)(a.p,{children:["Remote JavaScript Debugging has been removed as of React Native 0.79. See the original ",(0,r.jsx)(a.a,{href:"https://github.com/react-native-community/discussions-and-proposals/discussions/734",children:"deprecation announcement"}),"."]}),(0,r.jsxs)(a.p,{children:["If you are on an older version of React Native, please go to the docs ",(0,r.jsx)(a.a,{href:"/versions",children:"for your version"}),"."]})]}),"\n",(0,r.jsx)(a.p,{children:(0,r.jsx)(a.img,{alt:"The remote debugger window in Chrome",src:t(49744).A+"",width:"1600",height:"680"})})]})}function c(e={}){let{wrapper:a}={...(0,i.R)(),...e.components};return a?(0,r.jsx)(a,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},49744(e,a,t){t.d(a,{A:()=>n});let n=t.p+"assets/images/debugging-chrome-remote-debugger-ddf0ea5593f18b93a26ed3a8ea44e42e.jpg"},96056(e,a,t){t.d(a,{A:()=>n});let n=t.p+"assets/images/debugging-safari-developer-tools-5aefdee28e230260908d691621c4fa63.jpg"},98263(e,a,t){t.d(a,{A:()=>s});var n=t(62540);t(63696);var r=t(11750),i=t(23865);function o({children:e,className:a,hidden:t}){return(0,n.jsx)("div",{role:"tabpanel",className:(0,r.A)("tabItem_wHwb",a),hidden:t,children:e})}function s({children:e,className:a,value:t}){let{selectedValue:r,lazy:l}=(0,i.uc)(),u=t===r;return!u&&l?null:(0,n.jsx)(o,{className:a,hidden:!u,children:e})}},77779(e,a,t){t.d(a,{A:()=>g});var n=t(62540);t(63696);var r=t(11750),i=t(46065),o=t(23865),s=t(45194),l=t(83029);function u({className:e}){let{selectedValue:a,selectValue:t,tabValues:i,block:l}=(0,o.uc)(),d=[],{blockElementScrollPositionUntilNextRender:c}=(0,s.a_)(),g=e=>{let n=e.currentTarget,r=i[d.indexOf(n)].value;r!==a&&(c(n),t(r))}
1,h=e=>{let a=null;switch(e.key){case"Enter":g(e);break;case"ArrowRight":{let t=d.indexOf(e.currentTarget)+1;a=d[t]??d[0];break}case"ArrowLeft":{let t=d.indexOf(e.currentTarget)-1;a=d[t]??d[d.length-1]}}a?.focus()};return(0,n.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,r.A)("tabs",{"tabs--block":l},e),children:i.map(({value:e,label:t,attributes:i})=>(0,n.jsx)("li",{role:"tab",tabIndex:a===e?0:-1,"aria-selected":a===e,ref:e=>{d.push(e)},onKeyDown:h,onClick:g,...i,className:(0,r.A)("tabs__item","tabItem_l0OV",i?.className,{"tabs__item--active":a===e}),children:t??e},e))})}function d({children:e}){return(0,n.jsx)("div",{className:"margin-top--md",children:e})}function c({className:e,children:a}){return(0,n.jsxs)("div",{className:(0,r.A)(i.G.tabs.container,"tabs-container","tabList_J5MA"),children:[(0,n.jsx)(u,{className:e}),(0,n.jsx)(d,{children:a})]})}function g(e){let a=(0,l.A)(),t=(0,o.OC)(e);return(0,n.jsx)(o.O_,{value:t,children:(0,n.jsx)(c,{className:e.className,children:(0,o.vT)(e.children)})},String(a))}},23865(e,a,t){t.d(a,{OC:()=>g,O_:()=>v,uc:()=>p,vT:()=>d});var n=t(62540),r=t(63696),i=t(49519),o=t(6743),s=t(88511),l=t(15396),u=t(89030);function d(e){return r.Children.toArray(e).filter(e=>"\n"!==e)}function c({value:e,tabValues:a}){return a.some(a=>a.value===e)}function g(e){let a,{defaultValue:t,queryString:n=!1,groupId:d}=e,g=function(e){let{values:a,children:t}=e;return(0,r.useMemo)(()=>{let e=a??r.Children.toArray(t).flatMap(e=>{if(!e)return[];if((0,r.isValidElement)(e)&&function(e){let{props:a}=e;return!!a&&"object"==typeof a&&"value"in a}(e))return[e];let a="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${a}>: 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:a,attributes:t,default:n}})=>({value:e,label:a,attributes:t,default:n})),n=(0,l.XI)(e,(e,a)=>e.value===a.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},[a,t])}(e),[h,p]=(0,r.useState)(()=>(function({defaultValue:e,tabValues:a}){if(0===a.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!c({value:e,tabValues:a}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${a.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let t=a.find(e=>e.default)??a[0];if(!t)throw Error("Unexpected error: 0 tabValues");return t.value})({defaultValue:t,tabValues:g})),[v,b]=function({queryString:e=!1,groupId:a}){let t=(0,i.W6)(),n=function({queryString:e=!1,groupId:a}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!a)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 a??null}({queryString:e,groupId:a});return[(0,s.aZ)(n),(0,r.useCallback)(e=>{if(!n)return;let a=new URLSearchParams(t.location.search);a.set(n,e),t.replace({...t.location,search:a.toString()})},[n,t])]}({queryString:n,groupId:d}),[m,f]=function({groupId:e}){let a=e?`docusaurus.tab.${e}`:null,[t,n]=(0,u.Dv)(a);return[t,(0,r.useCallback)(e=>{a&&n.set(e)},[a,n])]}({groupId:d}),w=c({value:a=v??m,tabValues:g})?a:null;return(0,o.A)(()=>{w&&p(w)},[w]),{selectedValue:h,selectValue:(0,r.useCallback)(e=>{if(!c({value:e,tabValues:g}))throw Error(`Can't select invalid tab value=${e}`);p(e),b(e),f(e)},[b,f,g]),tabValues:g,lazy:e.lazy??!1,block:e.block??!1}}let h=(0,r.createContext)(null);function p(){let e=r.useContext(h);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function v(e){return(0,n.jsx)(h.Provider,{value:e.value,children:e.children})}},38469(e,a,t){t.d(a,{A:()=>o});var n=t(93227);let r=!!n.A.canUseDOM&&navigator.platform.startsWith("Mac"),i=!!n.A.canUseDOM&&navigator.platform.startsWith("Win"),o={defaultGuide:"quickstart",defaultJsDebugger:"flipper",defaultOs:r?"macos":i?"windows":"linux",defaultPackageManager:"npm",defaultPlatform:r?"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"}
2: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,a,t){t.d(a,{R:()=>o,x:()=>s});var n=t(63696);let r={},i=n.createContext(r);function o(e){let a=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(a):{...a,...e}},[a,e])}function s(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:a},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.