diff --git a/releases/0.49/404.html b/releases/0.49/404.html new file mode 100644 index 00000000000..db93f09777f --- /dev/null +++ b/releases/0.49/404.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/releases/0.49/circle.yml b/releases/0.49/circle.yml new file mode 100644 index 00000000000..56ad41b2f14 --- /dev/null +++ b/releases/0.49/circle.yml @@ -0,0 +1,4 @@ +general: + branches: + ignore: + - gh-pages diff --git a/releases/0.49/css/prism.css b/releases/0.49/css/prism.css new file mode 100644 index 00000000000..e1b64e2eea8 --- /dev/null +++ b/releases/0.49/css/prism.css @@ -0,0 +1,138 @@ +/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+bash+c+git+java+json+objectivec+powershell+jsx+swift */ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, +code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { + text-shadow: none; + background: #b3d4fc; +} + +pre[class*="language-"]::selection, pre[class*="language-"] ::selection, +code[class*="language-"]::selection, code[class*="language-"] ::selection { + text-shadow: none; + background: #b3d4fc; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol, +.token.deleted { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #a67f59; + background: hsla(0, 0%, 100%, .5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/releases/0.49/css/react-native.css b/releases/0.49/css/react-native.css new file mode 100644 index 00000000000..e6b61be593a --- /dev/null +++ b/releases/0.49/css/react-native.css @@ -0,0 +1,2178 @@ +/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */ +/* Document + ========================================================================== */ +/** + * 1. Change the default font family in all browsers (opinionated). + * 2. Correct the line height in all browsers. + * 3. Prevent adjustments of font size after orientation changes in + * IE on Windows Phone and in iOS. + */ +html { + font-family: sans-serif; + /* 1 */ + line-height: 1.15; + /* 2 */ + -ms-text-size-adjust: 100%; + /* 3 */ + -webkit-text-size-adjust: 100%; + /* 3 */ } + +/* Sections + ========================================================================== */ +/** + * Remove the margin in all browsers (opinionated). + */ +body { + margin: 0; } + +/** + * Add the correct display in IE 9-. + */ +article, +aside, +footer, +header, +nav, +section { + display: block; } + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; } + +/* Grouping content + ========================================================================== */ +/** + * Add the correct display in IE 9-. + * 1. Add the correct display in IE. + */ +figcaption, +figure, +main { + /* 1 */ + display: block; } + +/** + * Add the correct margin in IE 8. + */ +figure { + margin: 1em 40px; } + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ +hr { + box-sizing: content-box; + /* 1 */ + height: 0; + /* 1 */ + overflow: visible; + /* 2 */ } + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ +pre { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ } + +/* Text-level semantics + ========================================================================== */ +/** + * 1. Remove the gray background on active links in IE 10. + * 2. Remove gaps in links underline in iOS 8+ and Safari 8+. + */ +a { + background-color: transparent; + /* 1 */ + -webkit-text-decoration-skip: objects; + /* 2 */ } + +/** + * Remove the outline on focused links when they are also active or hovered + * in all browsers (opinionated). + */ +a:active, +a:hover { + outline-width: 0; } + +/** + * 1. Remove the bottom border in Firefox 39-. + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ +abbr[title] { + border-bottom: none; + /* 1 */ + text-decoration: underline; + /* 2 */ + text-decoration: underline dotted; + /* 2 */ } + +/** + * Prevent the duplicate application of `bolder` by the next rule in Safari 6. + */ +b, +strong { + font-weight: inherit; } + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ +b, +strong { + font-weight: bolder; } + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ +code, +kbd, +samp { + font-family: monospace, monospace; + /* 1 */ + font-size: 1em; + /* 2 */ } + +/** + * Add the correct font style in Android 4.3-. + */ +dfn { + font-style: italic; } + +/** + * Add the correct background and color in IE 9-. + */ +mark { + background-color: #ff0; + color: #000; } + +/** + * Add the correct font size in all browsers. + */ +small { + font-size: 80%; } + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sub { + bottom: -0.25em; } + +sup { + top: -0.5em; } + +/* Embedded content + ========================================================================== */ +/** + * Add the correct display in IE 9-. + */ +audio, +video { + display: inline-block; } + +/** + * Add the correct display in iOS 4-7. + */ +audio:not([controls]) { + display: none; + height: 0; } + +/** + * Remove the border on images inside links in IE 10-. + */ +img { + border-style: none; } + +/** + * Hide the overflow in IE. + */ +svg:not(:root) { + overflow: hidden; } + +/* Forms + ========================================================================== */ +/** + * 1. Change the font styles in all browsers (opinionated). + * 2. Remove the margin in Firefox and Safari. + */ +button, +input, +optgroup, +select, +textarea { + font-family: sans-serif; + /* 1 */ + font-size: 100%; + /* 1 */ + line-height: 1.15; + /* 1 */ + margin: 0; + /* 2 */ } + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ +button, +input { + /* 1 */ + overflow: visible; } + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ +button, +select { + /* 1 */ + text-transform: none; } + +/** + * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video` + * controls in Android 4. + * 2. Correct the inability to style clickable types in iOS and Safari. + */ +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; + /* 2 */ } + +/** + * Remove the inner border and padding in Firefox. + */ +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; } + +/** + * Restore the focus styles unset by the previous rule. + */ +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; } + +/** + * Change the border, margin, and padding in all browsers (opinionated). + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ +legend { + box-sizing: border-box; + /* 1 */ + color: inherit; + /* 2 */ + display: table; + /* 1 */ + max-width: 100%; + /* 1 */ + padding: 0; + /* 3 */ + white-space: normal; + /* 1 */ } + +/** + * 1. Add the correct display in IE 9-. + * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ +progress { + display: inline-block; + /* 1 */ + vertical-align: baseline; + /* 2 */ } + +/** + * Remove the default vertical scrollbar in IE. + */ +textarea { + overflow: auto; } + +/** + * 1. Add the correct box sizing in IE 10-. + * 2. Remove the padding in IE 10-. + */ +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; } + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ +[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ } + +/** + * Remove the inner padding and cancel buttons in Chrome and Safari on macOS. + */ +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; } + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ } + +/* Interactive + ========================================================================== */ +/* + * Add the correct display in IE 9-. + * 1. Add the correct display in Edge, IE, and Firefox. + */ +details, +menu { + display: block; } + +/* + * Add the correct display in all browsers. + */ +summary { + display: list-item; } + +/* Scripting + ========================================================================== */ +/** + * Add the correct display in IE 9-. + */ +canvas { + display: inline-block; } + +/** + * Add the correct display in IE. + */ +template { + display: none; } + +/* Hidden + ========================================================================== */ +/** + * Add the correct display in IE 10-. + */ +[hidden] { + display: none; } + +html { + font-family: proxima-nova, "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #484848; + line-height: 1.28; } + +body { + background-color: #F5FCFF; } + +* { + -moz-box-sizing: border-box; + -ms-box-sizing: border-box; + -o-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + border: none; + margin: 0; + padding: 0; } + +p { + margin: 0 0 16px; + line-height: 1.4; } + +em { + font-style: italic; } + +h1, h2, h3, h4, h5, h6 { + margin: 10px 0; + font-family: inherit; + font-weight: 400; + line-height: 20px; + color: #025268; + text-rendering: optimizelegibility; } + +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { + font-weight: normal; + color: #7b7b7b; } + +h1, h2, h3, h4 { + line-height: 40px; } + +h1 { + font-size: 40px; } + +h2 { + font-size: 31px; } + +h3 { + font-size: 23px; } + +h4 { + font-size: 17px; } + +h5 { + font-size: 14px; } + +h6 { + font-size: 11px; } + +h1 small { + font-size: 24px; } + +h2 small { + font-size: 18px; } + +h3 small { + font-size: 16px; } + +h4 small { + font-size: 14px; } + +img { + max-width: 100%; + height: auto; } + +ul, ol { + margin: 0 0 10px 25px; + padding: 0; } + +ul ul, ul ol, ol ol, ol ul { + margin-bottom: 0; } + +li { + line-height: 20px; } + +a { + color: #05A5D1; + text-decoration: none; } + +a:hover, a:focus { + color: #047e9f; + text-decoration: underline; } + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } + +.center { + text-align: center; } + +html * { + color-profile: sRGB; + rendering-intent: auto; } + +.content { + font-size: 18px; +} +.subHeader { + font-size: 21px; + font-weight: 300; + line-height: 30px; + margin-bottom: 10px; } + +.example-container { + position: relative; } + +.embedded-simulator, .embedded-simulator * { + box-sizing: border-box; } + +.embedded-simulator p { + text-align: center; + color: #999; } + +.embedded-simulator { + width: 210px; + position: absolute; + right: -200px; + top: 0; } + +@media screen and (max-width: 680px) { + .embedded-simulator { + position: relative; + right: 0; } } + +.side-by-side { + overflow: hidden; } + +.side-by-side > div { + width: 460; + margin-left: 0; + float: left; } + +.left { + float: left; } + +.right { + float: right; } + +.container { + padding-top: 50px; + min-width: 1160px; } + +.wrap { + max-width: 1260px; + margin: 0 auto; + padding: 0 20px; } + +.skinnyWrap { + width: 690px; + margin-left: auto; + margin-right: auto; + padding-left: 20px; + padding-right: 20px; } + +hr { + height: 0; + border-top: 1px solid #ccc; + border-bottom: 1px solid #eee; } + +ul, li { + margin-left: 20px; } + +h1 .anchor, h2 .anchor, h3 .anchor, h4 .anchor, h5 .anchor, h6 .anchor { + margin-top: -50px; + position: absolute; } + +h1:hover .hash-link, h2:hover .hash-link, h3:hover .hash-link, h4:hover .hash-link, h5:hover .hash-link, h6:hover .hash-link { + visibility: visible; } + +.hash-link { + color: #aaa; + visibility: hidden; } + +.nav-main { + *zoom: 1; + background: #222; + color: #fafafa; + position: fixed; + top: 0; + min-height: 50px; + width: 100%; + z-index: 100; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); } + +.nav-main:before, .nav-main:after { + content: " "; + display: table; } + +.nav-main:after { + clear: both; } + +.nav-main a { + color: #e9e9e9; + text-decoration: none; } + +.nav-main .nav-site-wrapper { + display: inline; +} + +.nav-main .nav-site-internal { + margin: 0 0 0 20px; } + +.nav-main .nav-site-external { + float: right; + margin: 0 12px 0 0; } + +.nav-main .nav-site li { + margin: 0; } + +.nav-main .nav-site a { + box-sizing: content-box; + padding: 0 10px; + line-height: 50px; + display: inline-block; + height: 50px; } + +.nav-site-wrapper a:hover { + color: #fff; } + +.nav-site-wrapper a.active { + color: #fff; + border-bottom: 3px solid #05A5D1; + background-color: #2D2D2D; } + +.nav-main .nav-home { + font-size: 24px; + font-weight: 300; + line-height: 50px; } + +.nav-home img { + vertical-align: -9px; + margin-right: 8px; + margin-left: 1px; + width: 34px; } + +.nav-main a.nav-home { + color: white; } + +.nav-main ul { + display: inline-block; + vertical-align: top; } + +.nav-main li { + display: inline; } + +.nav-main a.nav-version { + font-size: 16px; + font-weight: 300; + margin-left: 8px; + text-decoration: underline; } + +@media screen and (max-width: 680px) { + .nav-main .nav-home { + font-size: 20px; } + .nav-main a.nav-version { + font-size: 14px; } + .nav-main .nav-site-wrapper { + display: block; + overflow: hidden; } + .nav-main ul { + display: -webkit-flex; + display: flex; + overflow: hidden; } + .nav-main li { + -webkit-flex: 1; + flex: 1; } + .nav-main .nav-site li a { + width: 100%; + padding: 0; + text-align: center; + font-size: 14px; } + .nav-main .nav-site a.active { + color: #05A5D1; + font-weight: 300; + background-color: transparent; } + .nav-main .nav-site-internal { + margin: 0; + width: 100%; } + .nav-main .nav-site-external { + position: absolute; + top: 0; + right: 0; + float: none; } + .nav-main .nav-site-external li a { + padding: 0 6px; } } + +.nav-docs { + font-size: 14px; + float: left; + width: 210px; + margin: 0 48px 0 0; } + .nav-docs ul { + list-style: none; + margin: 0; + margin-left: 1px; } + .nav-docs ul ul { + margin-left: 20px; } + .nav-docs li { + margin: 0; } + .nav-docs a:hover { + text-decoration: none; + color: #025268; } + .nav-docs a.active { + color: #05A5D1; + font-weight: bold; } + +.nav-docs-section { + background-color: rgba(59, 55, 56, 0.05); + padding-bottom: 0; } + .nav-docs-section h3 { + color: white; + font-size: 18px; + font-weight: 400; + line-height: 20px; + margin-top: 0; + margin-bottom: 5px; + padding: 10px; + background-color: #222; + text-transform: capitalize; } + .nav-docs-section ul { + display: block; + padding-bottom: 10px; + padding-top: 10px; } + .nav-docs-section a { + color: #025268; + display: block; + margin: 2px 10px 5px; } + .nav-docs-section .nav-docs-section:first-child h3 { + margin-top: 0; } + .nav-docs-section .nav-docs-section:first-child { + padding-top: 0; + border-top: 0; } + .nav-docs-section .nav-docs-section:last-child { + padding-bottom: 0; + border-bottom: 0; } + +@media only screen and (min-width: 680px) { + .nav-main .nav-site-wrapper { + display: inline; + float: right; + } +} + +@media only screen and (max-device-width: 1024px) { + @-webkit-keyframes slide-in { + 0% { + top: -30px; + opacity: 0; } + 100% { + top: 0; + opacity: 1; } } + @-moz-keyframes slide-in { + 0% { + top: -30px; + opacity: 0; } + 100% { + top: 0; + opacity: 1; } } + @-o-keyframes slide-in { + 0% { + top: -30px; + opacity: 0; } + 100% { + top: 0; + opacity: 1; } } + @keyframes slide-in { + 0% { + top: -30px; + opacity: 0; } + 100% { + top: 0; + opacity: 1; } } + .nav-docs { + position: fixed; + z-index: 90; + top: -100%; + left: 0; + width: 100%; + height: 100%; + margin: 0; + padding: 53px 0 0 0; + background: #3B3738; } + .nav-docs-viewport { + border-top: 1px solid #05a5d1; + padding: 25px; + overflow: scroll; + -webkit-overflow-scrolling: touch; + position: relative; + width: 100%; + height: 100%; } + /* Active state */ + .nav-docs.in { + top: 0; + -moz-animation: slide-in 0.3s forwards; + -ms-animation: slide-in 0.3s forwards; + -o-animation: slide-in 0.3s forwards; + -webkit-animation: slide-in 0.3s forwards; + animation: slide-in 0.3s forwards; } + .nav-docs * { + -webkit-font-smoothing: antialiased; } + .nav-docs-section + .nav-docs-section { + margin-top: 50px; } + .nav-docs-section li { + margin: 5px 0; } + .nav-docs-section h3, + .nav-docs-section a { + color: white; } + .nav-docs-section h3 { + border-bottom: 1px solid white; + margin-bottom: 10px; + opacity: 0.3; } + .nav-docs-section a { + margin-right: 25px; + font-size: 120%; + padding: 5px 0; } + .nav-docs-section a.active { + border-bottom-style: solid; + border-bottom-width: 1px; + color: #05A5D1; } +} + +/** + * Multicolumn layout for phone (landscape only) & tablet (regardless its screen orientation)/ + */ +@media only screen and (min-device-width: 375px) and (max-device-width: 1024px) { + .nav-docs-section ul { + display: flex; + flex-wrap: wrap; } + .nav-docs-section li { + width: 100%; } } + +/* 2 columns layout */ +@media only screen and (min-device-width: 375px) and (max-device-width: 1024px) and (orientation: landscape), only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: portrait) { + .nav-docs-section li { + width: 50%; } } + +/* 3 columns layout on tablet (landscape screen orientation) */ +@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) and (orientation: landscape) { + .nav-docs-section li { + width: 33%; } } + +.home-section { + margin: 50px 0; } + +.home-section ol { + margin-left: 0; } + +.home-divider { + border-top-color: #bbb; + margin: 0 auto; + width: 400px; } + +.marketing-row { + *zoom: 1; + margin: 50px 0; } + +.marketing-row:before, .marketing-row:after { + content: " "; + display: table; } + +.marketing-row:after { + clear: both; } + +.marketing-col { + float: left; + margin-left: 40px; + width: 280px; } + +.marketing-col h3 { + color: #2d2d2d; + font-size: 24px; + font-weight: normal; + text-transform: uppercase; } + +.marketing-col p { + font-size: 16px; } + +.marketing-col:first-child { + margin-left: 0; } + +.tutorial-mock { + text-align: center; } + +.tutorial-mock img { + border: 1px solid #ccc; + box-shadow: 5px 5px 5px #888888; } + +#examples h3, .home-presentation h3 { + color: #2d2d2d; + font-size: 24px; + font-weight: normal; + margin-bottom: 5px; } + +#examples p { + margin: 0 0 25px 0; + max-width: 600px; } + +#examples .example { + margin-top: 60px; } + +#examples #todoExample { + font-size: 14px; } + +#examples #todoExample ul { + list-style-type: square; + margin: 0 0 10px 0; } + +#examples #todoExample input { + border: 1px solid #ccc; + font-size: 14px; + padding: 3px; + width: 150px; } + +#examples #todoExample button { + font-size: 14px; + margin-left: 5px; + padding: 4px 10px; } + +#examples #markdownExample textarea { + border: 1px solid #ccc; + font-size: 14px; + margin-bottom: 10px; + padding: 5px; } + +.home-get-started-section { + margin-bottom: 60px; } + +.docs-nextprev { + *zoom: 1; +} + +.docs-nextprev:before, .docs-nextprev:after { + content: " "; + display: table; } + +.docs-nextprev:after { + clear: both; } + +.docs-prev { + float: left; } + +.docs-next { + float: right; } + +section.black content { + padding-bottom: 18px; } + +.blogContent { + *zoom: 1; + padding-top: 20px; } + +.blogContent:before, .blogContent:after { + content: " "; + display: table; } + +.blogContent:after { + clear: both; } + +.blogContent blockquote { + padding: 5px 15px; + margin: 20px 0; + background-color: #f8f5ec; + border-left: 5px solid #f7ebc6; } + +.documentationContent { + *zoom: 1; + padding-top: 20px; + padding-bottom: 80px; } + +.documentationContent:before, .documentationContent:after { + content: " "; + display: table; } + +.documentationContent:after { + clear: both; } + +.documentationContent .subHeader { + font-size: 24px; } + +h2 { + margin-top: 30px; } + +.documentationContent blockquote { + padding: 15px 30px 15px 15px; + margin: 20px 0; + background-color: rgba(248, 245, 236, 0.1); + border-left: 5px solid rgba(191, 87, 73, 0.2); } + +.documentationContent blockquote h4 { + margin-top: 0; } + +.documentationContent blockquote p { + margin-bottom: 0; } + +.documentationContent blockquote p:first-child { + font-size: 14px; + line-height: 20px; + margin-top: 0; + text-rendering: optimizelegibility; } + +.docs-prevnext { + max-width: 640px; + margin: 40px auto; + padding-bottom: 20px; } + +.button { + background: -webkit-linear-gradient(#9a9a9a, #646464); + background: linear-gradient(#9a9a9a, #646464); + border-radius: 4px; + padding: 8px 16px; + font-size: 18px; + font-weight: 300; + margin: 0 12px; + display: inline-block; + color: #fafafa; + text-decoration: none; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } + +.button:hover { + text-decoration: none; } + +.button:active { + box-shadow: none; } + +.hero .button { + box-shadow: 1px 3px 3px rgba(0, 0, 0, 0.3); } + +.button.blue { + background: -webkit-linear-gradient(#77a3d2, #4783c2); + background: linear-gradient(#77a3d2, #4783c2); } + +.row { + padding-bottom: 4px; } + +.row .span4 { + width: 33.33%; + display: table-cell; } + +.row .span8 { + width: 66.66%; + display: table-cell; } + +.row .span6 { + width: 50%; + display: table-cell; } + +p { + margin: 16px 0; } + +.highlight { + padding: 10px; + margin-bottom: 20px; } + +figure { + text-align: center; } + +.inner-content { + float: left; + width: 650px; } + +.showcaseSection .inner-content { + width: 800px; } + +.helpSection .inner-content { + width: 800px; } + +.nosidebar .inner-content { + float: none; + margin: 0 auto; } + +.post-list-item + .post-list-item { + margin-top: 60px; } + +small code, li code, p code { + color: #555; + background-color: rgba(0, 0, 0, 0.04); + padding: 1px 3px; } + +.playground { + *zoom: 1; } + +.playground:before, .playground:after { + content: " "; + display: table; } + +.playground:after { + clear: both; } + +.playground-tab { + border-bottom: none !important; + border-radius: 3px 3px 0 0; + padding: 6px 8px; + font-size: 12px; + font-weight: bold; + color: #c2c0bc; + background-color: #f1ede4; + display: inline-block; + cursor: pointer; } + +.playgroundCode, .playground-tab, .playgroundPreview { + border: 1px solid rgba(16, 16, 16, 0.1); } + +.playground-tab-active { + color: #222; } + +.playgroundCode { + border-radius: 0 3px 3px 3px; + float: left; + overflow: hidden; + width: 600px; } + +.playgroundPreview { + background-color: white; + border-radius: 3px; + float: right; + padding: 15px 20px; + width: 280px; } + +.playgroundError { + color: #c5695c; + font-size: 15px; } + +.MarkdownEditor textarea { + width: 100%; + height: 100px; } + +.hll { + background-color: #f7ebc6; + border-left: 5px solid #f7d87c; + display: block; + margin-left: -14px; + margin-right: -14px; + padding-left: 9px; } + +.highlight .javascript .err { + background-color: transparent; + color: inherit; } + +.highlight { + position: relative; + margin-bottom: 14px; + padding: 30px 14px 14px; + border: none; + border-radius: 0; + overflow: auto; } + +.highlight pre { + padding: 0; + margin-top: 0; + margin-bottom: 0; + background-color: transparent; + border: 0; } + +.highlight pre code { + background: none; + font-size: inherit; + padding: 0; } + +.highlight pre .lineno { + display: inline-block; + width: 22px; + padding-right: 5px; + margin-right: 10px; + color: #bebec5; + text-align: right; } + +.highlight:after { + position: absolute; + top: 0; + right: 0; + left: 0; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + color: #c2c0bc; + background-color: #f1ede4; + content: "Code"; } + +.downloadCenter { + text-align: center; + margin-top: 20px; + margin-bottom: 25px; } + +.downloadSection:hover { + text-decoration: none !important; } + +/* Modal */ +.modal-backdrop { + background: rgba(0, 0, 0, 0.4); + display: none; + height: 100%; + left: 0; + overflow: auto; + position: fixed; + top: 0; + width: 100%; + z-index: 9900; } + +.modal { + background: #F6F6F6; + bottom: 0; + box-shadow: 2px 2px 4px 0 rgba(0, 0, 0, 0.11); + display: none; + border-radius: 10px; + height: 95%; + left: 0; + margin: auto; + max-height: 648px; + max-width: 460px; + overflow: auto; + position: fixed; + right: 0; + top: 0; + width: 80%; + z-index: 9999; } + +.modal-open { + display: block; } + +.modal-content { + padding: 40px 24px 8px 24px; + position: relative; } + +.modal-content iframe { + margin: 0 auto; } + +.modal-button-open { + cursor: pointer; + text-align: center; } + +.modal-button-open-img { + height: 358px; } + +.modal-button-open-img:hover img { + opacity: 0.9; } + +.modal-button-close { + background: transparent; + border-radius: 0 0 0 4px; + border: 0; + color: #555; + font-size: 1.2em; + font-weight: bolder; + line-height: 32px; + margin: 0; + padding: 0 12px; + position: absolute; + right: 0; + top: 0; } + +.modal-button-close:active, +.modal-button-close:focus, +.modal-button-close:hover { + background: #EAF8FD; + outline: none; } + +@media screen and (max-width: 680px) { + .container { + padding-top: 100px; } + .nav-docs { + padding-top: 103px; } } + +.post { + margin-bottom: 30px; } + +.pagination { + margin-bottom: 30px; + width: 100%; + overflow: hidden; } + +.pagination .next { + float: right; } + +div[data-twttr-id] iframe { + margin: 10px auto !important; } + +.three-column { + *zoom: 1; } + +.three-column:before, .three-column:after { + content: " "; + display: table; } + +.three-column:after { + clear: both; } + +.three-column > ul { + float: left; + margin-left: 30px; + width: 190px; } + +.three-column > ul:first-child { + margin-left: 20px; } + +.home-why { + margin-top: 25px; } + +.home-why h3 { + text-align: center; } + +.home-why .blurb { + margin-bottom: 20px; + text-align: center; } + +.home-why .list { + margin: 0 auto; + max-width: 460px; } + +.home-getting-started { + width: 500px; + margin: 20px auto 40px auto; } + +.home-getting-started h3 { + text-align: center; } + +.props { + background-color: #ebf9ff; } + +.compactProps { + border-left: 2px solid #e0f6ff; + margin-left: 20px; + padding-left: 5px; } + +.props > .prop:nth-child(2n) { + background-color: #e0f6ff; } + +.propTitle { + font-weight: bold; + font-size: 16px; } + +.compactProps .propTitle { + font-size: 14px; + margin-bottom: 0; + margin-top: 0; } + +.compactProps .propTitle div { + font-weight: normal; + margin-left: 20px; } + +.methodTitle { + font-weight: bold; + font-size: 24px; + color: #025268; } + +.compactProps .methodTitle { + font-size: 14px; + margin-bottom: 0; + margin-top: 0; } + +.compactProps .methodTitle div { + font-weight: normal; + margin-left: 20px; } + +.prop { + word-wrap: break-word; + padding: 5px 10px; } + +.compactProps .prop { + padding: 3px 10px; } + +.propType { + font-family: 'source-code-pro', Menlo, 'Courier New', Consolas, monospace; + font-weight: normal; + font-size: 15px; + white-space: pre-wrap; } + +.compactProps .propType { + font-weight: normal; + font-size: 13px; } + +.methodType { + font-weight: normal; + font-size: 24px; } + +.compactProps .methodType { + font-weight: normal; + font-size: 13px; } + +.botActions { + background-color: #ebf9ff; +} + +.botActions > .botAction:nth-child(2n) { + background-color: #e0f6ff; +} + +.botCommand { + font-family: 'source-code-pro', Menlo, 'Courier New', Consolas, monospace; + font-weight: bold; + color: #025268; +} + +.botAction { + padding: 5px 10px; +} + +.botMentionName { + font-weight: normal; +} + +.platform { + background-color: #bdebff; + border-radius: 5px; + margin-right: 5px; + padding: 0 5px; + font-size: 13px; + font-weight: normal; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + -webkit-user-select: none; + user-select: none; } + +.color { + display: inline-block; + width: 20px; + height: 20px; + margin-right: 5px; + position: relative; + top: 5px; } + +.color::before { + content: ''; + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border: 1px solid rgba(0, 0, 0, 0.2); } + +.deprecated { + margin-bottom: 24px; } + +.deprecatedTitle { + margin-bottom: 6px; + line-height: 18px; + font-weight: bold; + color: #ffa500; } + +.deprecatedIcon { + width: 18px; + height: 18px; + margin-right: 8px; + vertical-align: top; } + +.deprecatedMessage { + margin-left: 26px; } + +#content { + display: none; } + +table.versions { + width: 60%; } + +.versions th { + width: 20%; } + +.versions td, .versions th { + padding: 2px 5px; } + +.versions tr:nth-child(2n+1) { + background-color: #e0f6ff; } + +@media only screen and (max-device-width: 1024px) { + #content { + display: inline; } + .container { + min-width: 0; + overflow: auto; } + .wrap { + width: auto; } + .home-getting-started { + width: auto; } + .inner-content { + width: auto; + float: none; } + .marketing-col { + margin-left: 0; + float: none; + margin-bottom: 30px; + text-align: center; } + .home-section, .marketing-row { + margin: 0; } + .nav-main .nav-site a { + padding: 0 8px; } + .nav-main .nav-home { + margin-left: 8px; } + .nav-main .wrap { + padding: 0; } + .home-divider { + display: none; } + .hero { + padding: 10px 0 30px 0; } + .prism { + padding: 4px 8px; + margin-left: -12px; + font-size: 11px; } + .nav-docs .nav-docs-section { + border: none; + padding: 0; } + h1 { + font-size: 30px; + line-height: 30px; } + ol { + margin: 0; } } + +@media only screen and (max-device-width: 840px) { + .showcaseSection .inner-content { + width: 100%; } + .helpSection .inner-content { + width: 100%; } } + +.params, .props { + border-spacing: 0; + border: 0; + border-collapse: collapse; } + +.params .name, .props .name, .name code { + color: #4D4E53; } + +.params td, .params th, .props td, .props th { + border: 1px solid #ddd; + margin: 0px; + text-align: left; + vertical-align: top; + padding: 4px 6px; + display: table-cell; } + +.params thead tr, .props thead tr { + background-color: #c9eaf7; + font-weight: bold; } + +.params .params thead tr, .props .props thead tr { + background-color: #fff; + font-weight: bold; } + +.params th, .props th { + border-right: 1px solid #aaa; } + +.params thead .last, .props thead .last { + border-right: 1px solid #ddd; } + +.params td.description > div > p:first-child, +.props td.description > div > p:first-child { + margin-top: 0; + padding-top: 0; } + +.params td.description > p:last-child, +.props td.description > p:last-child { + margin-bottom: 0; + padding-bottom: 0; } + +.edit-page-block { + padding: 5px; + margin: 40px auto; + font-size: 12px; + color: #887766; + text-align: center; + background-color: rgba(5, 165, 209, 0.05); } + +.banner-crna-ejected { + border: 1px solid #05A5D1; + border-radius: 3px; + margin-bottom: 40px; } + .banner-crna-ejected h3 { + font-size: 16px; + margin: 0; + padding: 0 10px; + background-color: #05A5D1; + color: white; } + .banner-crna-ejected p { + padding: 10px; + margin: 2px; + text-decoration: none !important; + background-color: white; } + +.prism { + white-space: pre-wrap; + font-family: 'source-code-pro', Menlo, 'Courier New', Consolas, monospace; + font-size: 13px; + line-height: 20px; + border-left: 4px solid #05A5D1; + padding: 5px 10px; + background-color: rgba(5, 165, 209, 0.05); + overflow: auto; } + +.prism + .prism { + margin-top: 10px; } + +.token.keyword { + color: #1990B8; } + +.token.string, .token.regex { + color: #2F9C0A; } + +.token.boolean, .token.number { + color: #C92C2C; } + +.token.comment { + color: #7D8B99; } + +/** Algolia Doc Search **/ +div.algolia-search-wrapper { + display: inline-block; + vertical-align: top; + margin-left: 15px; } + +@media screen and (max-width: 960px) { + div.algolia-search-wrapper { + display: none; } } + +input#algolia-doc-search { + background: transparent url("../img/search.png") no-repeat 10px center; + background-size: 16px 16px; + font-family: inherit; + padding: 0 10px; + padding-left: 35px; + margin-top: 10px; + height: 30px; + font-size: 16px; + line-height: 20px; + background-color: #2f2f2f; + border-radius: 4px; + color: inherit; + outline: none; + border: none; + width: 170px; + -moz-transition: 0.5s width ease; + -ms-transition: 0.5s width ease; + -o-transition: 0.5s width ease; + -webkit-transition: 0.5s width ease; + transition: 0.5s width ease; } + +input#algolia-doc-search::placeholder { + color: rgba(255, 255, 255, 0.8); } + +input#algolia-doc-search::-moz-placeholder { + color: rgba(255, 255, 255, 0.8); } + +input#algolia-doc-search:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.8); } + +input#algolia-doc-search::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.8); } + +input#algolia-doc-search:focus { + width: 220px; } + +.algolia-autocomplete { + vertical-align: top; + height: 53px; } + .algolia-autocomplete .aa-dropdown-menu { + margin-left: -210px; + margin-top: -4px; } + +.algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight { + background-color: #05A5D1; } + +.aa-cursor .algolia-docsearch-suggestion--content { + color: #05A5D1; } + +.aa-cursor .algolia-docsearch-suggestion { + background: #ebf9ff; } + +.algolia-docsearch-suggestion { + border-bottom-color: #e0f6ff; } + .algolia-docsearch-suggestion--category-header { + background-color: #3B3738; } + .algolia-docsearch-suggestion--highlight { + color: #05A5D1; } + .algolia-docsearch-suggestion--subcategory-column { + border-right-color: #e0f6ff; + background-color: #ebf9ff; + color: #3B3738; } + +.hero { + background: #2D2D2D; + padding: 50px 0; + color: #FDF3E7; + font-weight: 300; } + +.hero .text { + font-size: 300%; + text-align: center; } + +.hero .minitext { + font-size: 24px; + text-align: center; } + +@media only screen and (max-width: 680px) { + .hero .text { + font-size: 200%; + text-align: center; } + .hero .minitext { + font-size: 18px; + text-align: center; } } + +.buttons-unit { + margin-top: 40px; + text-align: center; } + +.buttons-unit a { + color: #FA6900; } + +.buttons-unit .button { + background: #05A5D1; + color: #fafafa; } + +@media screen and (min-width: 600px) { + .buttons-unit .button { + font-size: 24px; } +} + +.buttons-unit .button:active { + background: #0485A9; } + +.buttons-unit.downloads { + margin: 30px 0; } + +.component-grid { + max-width: 800px; +} + +.component { + border: 1px solid #05A5D1; + border-radius: 3px; + margin: 0 auto 10px; + width: 100%; + display: inline-block; + background-color: white; +} + +.component h3 { + font-size: 16px; + margin: 0; + padding: 0 10px; + background-color: #05A5D1; + color: white; +} + +.component h3 a { + color: white; +} + +.component p { + padding: 10px; + margin: 2px; +} + +@supports (display:grid) { + .component-grid { + display: grid; + grid-gap: 22px; + } +} + +@media only screen and (min-device-width: 768px) { + .component-grid { + width: 768px; + } + .component-grid.component-grid-border { + border-bottom: 1px solid #f1eff0; + } + .component { + width: 30%; + height: 150px; + margin: 0 22px 22px auto; + vertical-align: top; + } + + @supports (display:grid) { + .component-grid { + grid-template-columns: repeat(3, 1fr); + } + .component { + width: auto; + height: auto; + margin: 0; + } + } +} + +/** Showcase **/ +.home-showcase-section { + max-width: 800px; + margin: 20px auto 100px auto; + text-align: center; } + +.home-showcase-section p { + max-width: 540px; + margin: 0 auto; } + +.footnote { + font-size: 12px; + color: rgba(0, 0, 0, 0.4); } + +.home-showcase-section .showcase img { + width: 100px; + height: 100px; + border-radius: 20px; } + +.showcaseHeader { + padding-bottom: 15px; + padding-top: 15px; + text-align: center; } + +.showcase { + margin: 30px auto 30px auto; + width: 50%; + display: inline-block; + text-align: center; + vertical-align: top; } + +@media only screen and (min-device-width: 1024px) { + .showcase { + width: 25%; } } + +.showcase h3 { + margin-bottom: 0px; + line-height: 20px; + padding-left: 5px; + padding-right: 5px; + font-size: 16px; } + +.showcase p { + margin-top: 5px; } + +.showcase h3, .showcase p { + color: #484848; } + +.showcase img { + width: 100px; + height: 100px; + border-radius: 20px; } + +.pinned img { + width: 150px; + border-radius: 20px; } + +/** Web player **/ +.web-player > iframe, .web-player > .prism { + display: none; } + +.web-player.desktop > iframe { + display: block; } + +.web-player.mobile > .prism { + display: block; } + +/** Help **/ +.helpSection h2 { + font-size: 24px; } + +.help-row { + margin: 0; } + +.help-row:after { + content: ""; + display: table; + clear: both; } + +.help-col { + float: left; } + +.help-col p { + font-size: 16px; } + +.help-col h3 { + color: #2d2d2d; + font-size: 18px; + line-height: 28px; + font-weight: normal; } + +@media (min-width: 600px) { + .help-col { + float: left; + margin-left: 40px; + width: 240px; } + .help-col:first-child { + margin-left: 0; } } + +.help-list { + padding: 0; + list-style: none; + margin: 1.25em 0 1em 0; } + +.entry ul, li { + margin: 0 0 10px 0; } + +.help-list .help-list-entry { + padding: 16px 0; + border-top: 1px solid #f1eff0; } + +/** Blog **/ +.entry-header { + margin: 0; } + +.entry-header h1 { + margin: 0; + font-size: 33px; + line-height: 36px; + line-height: 1; } + +.entry-header h4 { + margin: 0 0 10px; + line-height: 16px; + font-size: 14px; + line-height: 1; } + +.entry-header .author { + color: #5A6b77; + font-weight: 700; } + +.entry-header .date { + color: rgba(102, 99, 122, 0.5); } + +.entry-readmore { + margin: 12px 0 0; } + +.entry-share { + padding: 36px 0; + display: block; + text-align: left; } + +@media screen and (max-width: 768px) { + .entry-share { + display: none; } } + +.entry-excerpt { + min-width: 320px; + max-width: 640px; + margin: 0 auto 40px; + padding-bottom: 40px; + border-bottom: 1px solid #EDEDED; } + +.entry-body { + min-width: 320px; + max-width: 640px; + margin: 0 auto; } + +.small-title { + font-size: 10px; + color: #66637A; + letter-spacing: .4rem; + text-transform: uppercase; + font-weight: 400; + line-height: 12px; } + +.entry-share .small-title { + float: left; + width: 50%; } + +.social-buttons { + padding-top: 7px; + float: left; + width: 50%; } + +article { + margin: 0 0 40px 0; } + +article h2 { + font-size: 26px; + line-height: 1; } + +article li { + line-height: 28px; } + +.author-info { + margin-top: 26px; + text-align: center; + border-bottom: 1px solid #f1f1f1; + padding-bottom: 20px; } + +.the-image { + position: relative; + display: block; + width: 64px; + height: 64px; + margin: 0 auto; + border-radius: 50%; + background-position: center center; + background-color: #fff; + background-size: cover; } + +.author-image { + position: relative; } + +.author-image:before { + content: ""; + display: block; + position: absolute; + width: 100%; + height: 1px; + top: 50%; + left: 0; + background-color: #F1F1F1; } + +.posted-on { + font-size: 12px; + color: #9d9b9b; + margin-bottom: 0; + margin-top: 15px; } + +.name-title { + margin-top: 2px; + font-size: 22px; + font-weight: 400; + margin: 3px 0 5px; + color: #5A6B77; } + +.name-title a { + color: #5A6B77; } + +.name-title .title { + color: #9d9b9b; } + +.btn { + background: 0 0; + color: #05A5D1; + min-width: 0; + border: 1px solid #05A5D1; + display: inline-block; + padding: 9px 18px; + border-radius: 4px; + text-align: center; +} + +.btn a { + text-decoration: none !important; } + +.btn:hover { + text-decoration: none !important; } + +@media screen and (max-width: 373px) { + .hero .buttons-unit .button { + margin-bottom: 4px; } + + .docs-prevnext .btn { + margin-bottom: 4px; + display: block; + float: none; } } + +.video-container { + border-radius: 4px; + background-clip: padding-box; + margin: 0 0 18px; + height: 180px; + width: 100%; + background-size: cover; + background-position: center center; + position: relative; + height: 0; + overflow: hidden; } + +@media (min-width: 760px) { + .video-container { + height: 345px; } } + +#mc_embed_signup { + clear: left; + width: 100%; } + +/** Footer **/ +footer.nav-footer { + box-sizing: border-box; + border: none; + font-weight: normal; + color: #202020; + font-size: 15px; + line-height: 24px; + background: #012129; + box-shadow: inset 0 10px 10px -5px rgba(0, 0, 0, 0.2); + padding-top: 2em; + padding-bottom: 2em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +footer .sitemap { + display: flex; + justify-content: space-between; + max-width: 1080px; + margin: 0 auto 1em; } + +footer .sitemap div { + flex: 1; } + +footer .sitemap .nav-home { + display: table; + margin: -12px 20px 0 0; + padding: 10px; + width: 50px; + height: 50px; + opacity: 0.4; + transition: opacity 0.15s ease-in-out; } + +footer .sitemap .nav-home:hover, +footer .sitemap .nav-home:focus { + opacity: 1.0; } + +@media screen and (max-width: 768px) { + footer .sitemap { + display: none; } + footer .newsletter { + display: none; } + #mc_embed_signup { + display: none; } } + +footer .sitemap a { + color: white; + display: table; + margin: 2px -10px; + padding: 3px 10px; } + +footer .sitemap a:hover, +footer .sitemap a:focus { + color: #05A5D1; + text-decoration: none; } + +footer .sitemap h5 > a:hover, +footer .sitemap h5 > a:focus { + color: white; + text-decoration: none; } + +footer .sitemap h5, +footer .sitemap h6 { + margin: 0 0 10px; } + +footer .sitemap h5, +footer .sitemap h6, +footer .sitemap h5 > a, +footer .sitemap h6 > a { + color: #05A5D1; + font-size: 15px; +} + +footer .sitemap h5 > a, +footer .sitemap h6 > a { + margin: 0 -10px; } + +footer .fbOpenSource { + display: block; + margin: 1em auto; + opacity: 0.4; + transition: opacity 0.15s ease-in-out; + width: 170px; } + +footer .fbOpenSource:hover { + opacity: 1.0; } + +footer .copyright { + color: rgba(255, 255, 255, 0.4); + text-align: center; } + +footer .newsletter { + display: flex; + justify-content: space-between; + max-width: 640px; + margin: 0 auto 1em; } + +footer .newsletter h5 { + color: #05A5D1; + margin: 0 0 10px; } diff --git a/releases/0.49/docs/accessibility.html b/releases/0.49/docs/accessibility.html new file mode 100644 index 00000000000..476ef286eb7 --- /dev/null +++ b/releases/0.49/docs/accessibility.html @@ -0,0 +1,60 @@ +Both iOS and Android provide APIs for making apps accessible to people with disabilities. In addition, both platforms provide bundled assistive technologies, like the screen readers VoiceOver (iOS) and TalkBack (Android) for the visually impaired. Similarly, in React Native we have included APIs designed to provide developers with support for making apps more accessible. Take note, iOS and Android differ slightly in their approaches, and thus the React Native implementations may vary by platform.
In addition to this documentation, you might find this blog post about React Native accessibility to be useful.
When true, indicates that the view is an accessibility element. When a view is an accessibility element, it groups its children into a single selectable component. By default, all touchable elements are accessible.
On Android, ‘accessible={true}’ property for a react-native View will be translated into native ‘focusable={true}’.
In the above example, we can't get accessibility focus separately on 'text one' and 'text two'. Instead we get focus on a parent view with 'accessible' property.
When a view is marked as accessible, it is a good practice to set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected. VoiceOver will read this string when a user selects the associated element.
To use, set the accessibilityLabel property to a custom string on your View:
In the above example, the accessibilityLabel on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.
Accessibility traits tell a person using VoiceOver what kind of element they have selected. Is this element a label? A button? A header? These questions are answered by accessibilityTraits.
To use, set the accessibilityTraits property to one of (or an array of) accessibility trait strings:
A Boolean value indicating whether VoiceOver should ignore the elements within views that are siblings of the receiver.
For example, in a window that contains sibling views A and B, setting accessibilityViewIsModal to true on view B causes VoiceOver to ignore the elements in the view A.
+On the other hand, if view B contains a child view C and you set accessibilityViewIsModal to true on view C, VoiceOver does not ignore the elements in view A.
Use this property to assign a custom function to be called when someone activates an accessible element by double tapping on it while it's selected.
Assign this property to a custom function which will be called when someone performs the "magic tap" gesture, which is a double-tap with two fingers. A magic tap function should perform the most relevant action a user could take on a component. In the Phone app on iPhone, a magic tap answers a phone call, or ends the current one. If the selected element does not have an onMagicTap function, the system will traverse up the view hierarchy until it finds a view that does.
In some cases, we also want to alert the end user of the type of selected component (i.e., that it is a “button”). If we were using native buttons, this would work automatically. Since we are using javascript, we need to provide a bit more context for TalkBack. To do so, you must specify the ‘accessibilityComponentType’ property for any UI component. For instances, we support ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’ and so on.
In the above example, the TouchableWithoutFeedback is being announced by TalkBack as a native Button.
When components dynamically change, we want TalkBack to alert the end user. This is made possible by the ‘accessibilityLiveRegion’ property. It can be set to ‘none’, ‘polite’ and ‘assertive’:
In the above example method _addOne changes the state.count variable. As soon as an end user clicks the TouchableWithoutFeedback, TalkBack reads text in the Text view because of its 'accessibilityLiveRegion=”polite”' property.
In the case of two overlapping UI components with the same parent, default accessibility focus can have unpredictable behavior. The ‘importantForAccessibility’ property will resolve this by controlling if a view fires accessibility events and if it is reported to accessibility services. It can be set to ‘auto’, ‘yes’, ‘no’ and ‘no-hide-descendants’ (the last value will force accessibility services to ignore the component and all of its children).
In the above example, the yellow layout and its descendants are completely invisible to TalkBack and all other accessibility services. So we can easily use overlapping views with the same parent without confusing TalkBack.
The AccessibilityInfo API allows you to determine whether or not a screen reader is currently active. See the AccessibilityInfo documentation for details.
Sometimes it is useful to trigger an accessibility event on a UI component (i.e. when a custom view appears on a screen or a custom radio button has been selected). Native UIManager module exposes a method ‘sendAccessibilityEvent’ for this purpose. It takes two arguments: view tag and a type of an event.
In the above example we've created a custom radio button that now behaves like a native one. More specifically, TalkBack now correctly announces changes to the radio button selection.
To enable VoiceOver, go to the Settings app on your iOS device. Tap General, then Accessibility. There you will find many tools that people use to make their devices more usable, such as bolder text, increased contrast, and VoiceOver.
To enable VoiceOver, tap on VoiceOver under "Vision" and toggle the switch that appears at the top.
At the very bottom of the Accessibility settings, there is an "Accessibility Shortcut". You can use this to toggle VoiceOver by triple clicking the Home button.
Improve this page by sending a pull request!
Sometimes it's useful to know whether or not the device has a screen reader that is currently active. The
+AccessibilityInfo API is designed for this purpose. You can use it to query the current state of the
+screen reader as well as to register to be notified when the state of the screen reader changes.
Here's a small example illustrating how to use AccessibilityInfo:
Query whether a screen reader is currently enabled. Returns a promise which
+resolves to a boolean. The result is true when a screen reader is enabled
+and false otherwise.
Add an event handler. Supported events:
change: Fires when the state of the screen reader changes. The argument
+to the event handler is a boolean. The boolean is true when a screen
+reader is enabled and false otherwise.announcementFinished: iOS-only event. Fires when the screen reader has
+finished making an announcement. The argument to the event handler is a dictionary
+with these keys:announcement: The string announced by the screen reader.success: A boolean indicating whether the announcement was successfully made.iOS-Only. Set accessibility focus to a react component.
iOS-Only. Post a string to be announced by the screen reader.
Remove an event handler.
Improve this page by sending a pull request!
Display an iOS action sheet. The options object must contain one or more
+of:
options (array of strings) - a list of button titles (required)cancelButtonIndex (int) - index of cancel button in optionsdestructiveButtonIndex (int) - index of destructive button in optionstitle (string) - a title to show above the action sheetmessage (string) - a message to show below the titleDisplay the iOS share sheet. The options object should contain
+one or both of message and url and can additionally have
+a subject or excludedActivityTypes:
url (string) - a URL to sharemessage (string) - a message to sharesubject (string) - a subject for the messageexcludedActivityTypes (array) - the activities to exclude from the ActionSheetNOTE: if url points to a local file, or is a base64-encoded
+uri, the file it points to will be loaded and shared directly.
+In this way, you can share images, videos, PDF files, etc.
Improve this page by sending a pull request!
Displays a circular loading indicator.
Whether to show the indicator (true, the default) or hide it (false).
Size of the indicator (default is 'small'). +Passing a number to the size prop is only supported on Android.
Whether the indicator should hide when not animating (true by default).
Improve this page by sending a pull request!
Launches an alert dialog with the specified title and message.
Optionally provide a list of buttons. Tapping any button will fire the +respective onPress callback and dismiss the alert. By default, the only +button will be an 'OK' button.
This is an API that works both on iOS and Android and can show static
+alerts. To show an alert that prompts the user to enter some information,
+see AlertIOS; entering text in an alert is common on iOS only.
On iOS you can specify any number of buttons. Each button can optionally +specify a style, which is one of 'default', 'cancel' or 'destructive'.
On Android at most three buttons can be specified. Android has a concept +of a neutral, negative and a positive button:
By default alerts on Android can be dismissed by tapping outside of the alert
+box. This event can be handled by providing an optional options parameter,
+with an onDismiss callback property { onDismiss: () => {} }.
Alternatively, the dismissing behavior can be disabled altogether by providing
+an optional options parameter with the cancelable property set to false
+i.e. { cancelable: false }
Example usage:
Improve this page by sending a pull request!
AlertIOS provides functionality to create an iOS alert dialog with a
+message or create a prompt for user input.
Creating an iOS alert:
Creating an iOS prompt:
We recommend using the Alert.alert method for
+cross-platform support if you don't need to create iOS-only prompts.
Create and display a popup alert.
| Name and Type | Description |
|---|---|
| title string | The dialog's title. An empty string hides the title. |
| [message] string | An optional message that appears below + the dialog's title. |
| [callbackOrButtons] ?(() => void) | ButtonsArray | This optional argument should + be either a single-argument function or an array of buttons. If passed + a function, it will be called when the user taps 'OK'. If passed an array of button configurations, each button should include
+ a |
| [type] | Deprecated, do not use. |
Create and display a prompt to enter some text.
| Name and Type | Description |
|---|---|
| title string | The dialog's title. |
| [message] string | An optional message that appears above the text + input. |
| [callbackOrButtons] ?((text: string) => void) | ButtonsArray | This optional argument should + be either a single-argument function or an array of buttons. If passed + a function, it will be called with the prompt's value when the user + taps 'OK'. If passed an array of button configurations, each button should include
+ a |
| [type] | This configures the text input. One of 'plain-text', + 'secure-text' or 'login-password'. |
| [defaultValue] string | The default text in text input. |
| [keyboardType] string | The keyboard type of first text field(if exists). + One of 'default', 'email-address', 'numeric', 'phone-pad', + 'ascii-capable', 'numbers-and-punctuation', 'url', 'number-pad', + 'name-phone-pad', 'decimal-pad', 'twitter' or 'web-search'. |
An Alert button type
| Value | Description |
|---|---|
| default | Default alert with no inputs |
| plain-text | Plain text input alert |
| secure-text | Secure text input alert |
| login-password | Login and password alert |
An Alert button style
| Value | Description |
|---|---|
| default | Default button style |
| cancel | Cancel button style |
| destructive | Destructive button style |
Array or buttons
| Name and Type | Description |
|---|---|
| [text] string | Button label |
| [onPress] function | Callback function when button pressed |
| [style] | Button style |
| Value | Description |
|---|---|
| text | Button label |
| onPress | Callback function when button pressed |
| style | Button style |
Improve this page by sending a pull request!
You will need to build React Native from source if you want to work on a new feature/bug fix, try out the latest features which are not released yet, or maintain your own fork with patches that cannot be merged to the core.
Assuming you have the Android SDK installed, run android to open the Android SDK Manager.
Make sure you have the following installed:
build.gradle)build.gradle)Step 1: Set environment variables through your local shell.
Note: Files may vary based on shell flavor. See below for examples from common shells.
.bash_profile or .bashrc.zprofile or .zshrc.profile or $ENVExample:
Step 2: Create a local.properties file in the android directory of your react-native app with the following contents:
Example:
You can find further instructions on the official page.
First, you need to install react-native from your fork. For example, to install the master branch from the official repo, run the following:
Alternatively, you can clone the repo to your node_modules directory and run npm install inside the cloned repo.
Add gradle-download-task as dependency in android/build.gradle:
:ReactAndroid project #Add the :ReactAndroid project in android/settings.gradle:
Modify your android/app/build.gradle to use the :ReactAndroid project instead of the pre-compiled library, e.g. - replace compile 'com.facebook.react:react-native:+' with compile project(':ReactAndroid'):
If you use 3rd-party React Native modules, you need to override their dependencies so that they don't bundle the pre-compiled library. Otherwise you'll get an error while compiling - Error: more than one library with package name 'com.facebook.react'.
Modify your android/app/build.gradle, and add:
From the Welcome screen of Android Studio choose "Import project" and select the android folder of your app.
You should be able to use the Run button to run your app on a device. Android Studio won't start the packager automatically, you'll need to start it by running npm start on the command line.
Building from source can take a long time, especially for the first build, as it needs to download ~200 MB of artifacts and compile the native code. Every time you update the react-native version from your repo, the build directory may get deleted, and all the files are re-downloaded. To avoid this, you might want to change your build directory path by editing the ~/.gradle/init.gradle file:
If you find that you need to push up a locally compiled React Native .aar and related files to a remote Nexus repository, you can.
Start by following the Point Gradle to your Android SDK section of this page. Once you do this, assuming you have Gradle configured properly, you can then run the following command from the root of your React Native checkout to build and package all required files:
This will package everything that would typically be included in the android directory of your node_modules/react-native/ installation in the root directory of your React Native checkout.
If you made changes to React Native and submit a pull request, all tests will run on your pull request automatically. To run the tests locally, see Running Tests.
Gradle build fails in ndk-build. See the section about local.properties file above.
Improve this page by sending a pull request!
The Animated library is designed to make animations fluid, powerful, and
+easy to build and maintain. Animated focuses on declarative relationships
+between inputs and outputs, with configurable transforms in between, and
+simple start/stop methods to control time-based animation execution.
The simplest workflow for creating an animation is to create an
+Animated.Value, hook it up to one or more style attributes of an animated
+component, and then drive updates via animations using Animated.timing():
Refer to the Animations guide to see
+additional examples of Animated in action.
There are two value types you can use with Animated:
Animated.Value() for single valuesAnimated.ValueXY() for vectorsAnimated.Value can bind to style properties or other props, and can be
+interpolated as well. A single Animated.Value can drive any number of
+properties.
Animated provides three types of animation types. Each animation type
+provides a particular animation curve that controls how your values animate
+from their initial value to the final value:
Animated.decay() starts with an initial
+velocity and gradually slows to a stop.Animated.spring() provides a simple
+spring physics model.Animated.timing() animates a value over time
+using easing functions.In most cases, you will be using timing(). By default, it uses a symmetric
+easeInOut curve that conveys the gradual acceleration of an object to full
+speed and concludes by gradually decelerating to a stop.
Animations are started by calling start() on your animation. start()
+takes a completion callback that will be called when the animation is done.
+If the animation finished running normally, the completion callback will be
+invoked with {finished: true}. If the animation is done because stop()
+was called on it before it could finish (e.g. because it was interrupted by a
+gesture or another animation), then it will receive {finished: false}.
By using the native driver, we send everything about the animation to native +before starting the animation, allowing native code to perform the animation +on the UI thread without having to go through the bridge on every frame. +Once the animation has started, the JS thread can be blocked without +affecting the animation.
You can use the native driver by specifying useNativeDriver: true in your
+animation configuration. See the
+Animations guide to learn
+more.
Only animatable components can be animated. These special components do the +magic of binding the animated values to the properties, and do targeted +native updates to avoid the cost of the react render and reconciliation +process on every frame. They also handle cleanup on unmount so they are safe +by default.
createAnimatedComponent()
+can be used to make a component animatable.Animated exports the following animatable components using the above
+wrapper:
Animated.ImageAnimated.ScrollViewAnimated.TextAnimated.ViewAnimations can also be combined in complex ways using composition functions:
Animated.delay() starts an animation after
+a given delay.Animated.parallel() starts a number of
+animations at the same time.Animated.sequence() starts the animations
+in order, waiting for each to complete before starting the next.Animated.stagger() starts animations in
+order and in parallel, but with successive delays.Animations can also be chained together simply by setting the toValue of
+one animation to be another Animated.Value. See
+Tracking dynamic values in
+the Animations guide.
By default, if one animation is stopped or interrupted, then all other +animations in the group are also stopped.
You can combine two animated values via addition, multiplication, division, +or modulo to make a new animated value:
The interpolate() function allows input ranges to map to different output
+ranges. By default, it will extrapolate the curve beyond the ranges given,
+but you can also have it clamp the output value. It uses lineal interpolation
+by default but also supports easing functions.
Read more about interpolation in the +Animation guide.
Gestures, like panning or scrolling, and other events can map directly to
+animated values using Animated.event(). This is done with a structured map
+syntax so that values can be extracted from complex event objects. The first
+level is an array to allow mapping across multiple args, and that array
+contains nested objects.
For example, when working with horizontal scrolling gestures, you would do
+the following in order to map event.nativeEvent.contentOffset.x to
+scrollX (an Animated.Value):
Animates a value from an initial velocity to zero based on a decay +coefficient.
Config is an object that may have the following options:
velocity: Initial velocity. Required.deceleration: Rate of decay. Default 0.997.useNativeDriver: Uses the native driver when true. Default false.Animates a value along a timed easing curve. The
+Easing module has tons of predefined curves, or you
+can use your own function.
Config is an object that may have the following options:
duration: Length of animation (milliseconds). Default 500.easing: Easing function to define curve.
+Default is Easing.inOut(Easing.ease).delay: Start the animation after delay (milliseconds). Default 0.useNativeDriver: Uses the native driver when true. Default false.Spring animation based on Rebound and
+Origami. Tracks velocity state to
+create fluid motions as the toValue updates, and can be chained together.
Config is an object that may have the following options. Note that you can +only define bounciness/speed or tension/friction but not both:
friction: Controls "bounciness"/overshoot. Default 7.tension: Controls speed. Default 40.speed: Controls speed of the animation. Default 12.bounciness: Controls bounciness. Default 8.useNativeDriver: Uses the native driver when true. Default false.Creates a new Animated value composed from two Animated values added +together.
Creates a new Animated value composed by dividing the first Animated value +by the second Animated value.
Creates a new Animated value composed from two Animated values multiplied +together.
Creates a new Animated value that is the (non-negative) modulo of the +provided Animated value
Create a new Animated value that is limited between 2 values. It uses the
+difference between the last value so even if the value is far from the bounds
+it will start changing when the value starts getting closer again.
+(value = clamp(value + diff, min, max)).
This is useful with scroll events, for example, to show the navbar when +scrolling up and to hide it when scrolling down.
Starts an animation after the given delay.
Starts an array of animations in order, waiting for each to complete +before starting the next. If the current running animation is stopped, no +following animations will be started.
Starts an array of animations all at the same time. By default, if one
+of the animations is stopped, they will all be stopped. You can override
+this with the stopTogether flag.
Array of animations may run in parallel (overlap), but are started in +sequence with successive delays. Nice for doing trailing effects.
Loops a given animation continuously, so that each time it reaches the +end, it resets and begins again from the start. Can specify number of +times to loop using the key 'iterations' in the config. Will loop without +blocking the UI thread if the child animation is set to 'useNativeDriver'.
Takes an array of mappings and extracts values from each arg accordingly,
+then calls setValue on the mapped outputs. e.g.
Config is an object that may have the following options:
listener: Optional async listener.useNativeDriver: Uses the native driver when true. Default false.Advanced imperative API for snooping on animated events that are passed in through props. Use +values directly where possible.
Standard value class for driving animations. Typically initialized with
+new Animated.Value(0);
See also AnimatedValue.
2D value class for driving 2D animations, such as pan gestures.
See also AnimatedValueXY.
exported to use the Interpolation type in flow
See also AnimatedInterpolation.
Exported for ease of type checking. All animated values derive from this class.
Make any React component Animatable. Used to create Animated.View, etc.
Imperative API to attach an animated value to an event on a view. Prefer using
+Animated.event with useNativeDrive: true if possible.
Improve this page by sending a pull request!
Animations are very important to create a great user experience. +Stationary objects must overcome inertia as they start moving. +Objects in motion have momentum and rarely come to a stop immediately. +Animations allow you to convey physically believable motion in your interface.
React Native provides two complementary animation systems:
+Animated for granular and interactive control of specific values, and
+LayoutAnimation for animated global layout transactions.
Animated API #The Animated API is designed to make it very easy to concisely express a wide variety of interesting animation and interaction patterns in a very performant way.
+Animated focuses on declarative relationships between inputs and outputs, with configurable transforms in between, and simple start/stop methods to control time-based animation execution.
Animated exports four animatable component types: View, Text, Image, and ScrollView, but you can also create your own using Animated.createAnimatedComponent().
For example, a container view that fades in when it is mounted may look like this:
Let's break down what's happening here.
+In the FadeInView constructor, a new Animated.Value called fadeAnim is initialized as part of state.
+The opacity property on the View is mapped to this animated value.
+Behind the scenes, the numeric value is extracted and used to set opacity.
When the component mounts, the opacity is set to 0.
+Then, an easing animation is started on the fadeAnim animated value,
+which will update all of its dependent mappings (in this case, just the opacity) on each frame as the value animates to the final value of 1.
This is done in an optimized way that is faster than calling setState and re-rendering.
Because the entire configuration is declarative, we will be able to implement further optimizations that serialize the configuration and runs the animation on a high-priority thread.
Animations are heavily configurable. Custom and predefined easing functions, delays, durations, decay factors, spring constants, and more can all be tweaked depending on the type of animation.
Animated provides several animation types, the most commonly used one being Animated.timing().
+It supports animating a value over time using one of various predefined easing functions, or you can use your own.
+Easing functions are typically used in animation to convey gradual acceleration and deceleration of objects.
By default, timing will use a easeInOut curve that conveys gradual acceleration to full speed and concludes by gradually decelerating to a stop.
+You can specify a different easing function by passing a easing parameter.
+Custom duration or even a delay before the animation starts is also supported.
For example, if we want to create a 2-second long animation of an object that slightly backs up before moving to its final position:
Take a look at the Configuring animations section of the Animated API reference to learn more about all the config parameters supported by the built-in animations.
Animations can be combined and played in sequence or in parallel.
+Sequential animations can play immediately after the previous animation has finished,
+or they can start after a specified delay.
+The Animated API provides several methods, such as sequence() and delay(),
+each of which simply take an array of animations to execute and automatically calls start()/stop() as needed.
For example, the following animation coasts to a stop, then it springs back while twirling in parallel:
If one animation is stopped or interrupted, then all other animations in the group are also stopped.
+Animated.parallel has a stopTogether option that can be set to false to disable this.
You can find a full list of composition methods in the Composing animations section of the Animated API reference.
You can combine two animated values via addition, multiplication, division, or modulo to make a new animated value.
There are some cases where an animated value needs to invert another animated value for calculation. +An example is inverting a scale (2x --> 0.5x):
Each property can be run through an interpolation first. +An interpolation maps input ranges to output ranges, +typically using a linear interpolation but also supports easing functions. +By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value.
A simple mapping to convert a 0-1 range to a 0-100 range would be:
For example, you may want to think about your Animated.Value as going from 0 to 1,
+but animate the position from 150px to 0px and the opacity from 0 to 1.
+This can easily be done by modifying style from the example above like so:
interpolate() supports multiple range segments as well, which is handy for defining dead zones and other handy tricks.
+For example, to get an negation relationship at -300 that goes to 0 at -100, then back up to 1 at 0, and then back down to zero at 100 followed by a dead-zone that remains at 0 for everything beyond that, you could do:
Which would map like so:
interpolate() also supports mapping to strings, allowing you to animate colors as well as values with units. For example, if you wanted to animate a rotation you could do:
interpolate() also supports arbitrary easing functions, many of which are already implemented in the
+Easing module.
+interpolate() also has configurable behavior for extrapolating the outputRange.
+You can set the extrapolation by setting the extrapolate, extrapolateLeft, or extrapolateRight options.
+The default value is extend but you can use clamp to prevent the output value from exceeding outputRange.
Animated values can also track other values.
+Just set the toValue of an animation to another animated value instead of a plain number.
+For example, a "Chat Heads" animation like the one used by Messenger on Android could be implemented with a spring() pinned on another animated value, or with timing() and a duration of 0 for rigid tracking.
+They can also be composed with interpolations:
The leader and follower animated values would be implemented using Animated.ValueXY().
+ValueXY is a handy way to deal with 2D interactions, such as panning or dragging.
+It is a simple wrapper that basically contains two Animated.Value instances and some helper functions that call through to them,
+making ValueXY a drop-in replacement for Value in many cases.
+It allows us to track both x and y values in the example above.
Gestures, like panning or scrolling, and other events can map directly to animated values using Animated.event.
+This is done with a structured map syntax so that values can be extracted from complex event objects.
+The first level is an array to allow mapping across multiple args, and that array contains nested objects.
For example, when working with horizontal scrolling gestures,
+you would do the following in order to map event.nativeEvent.contentOffset.x to scrollX (an Animated.Value):
When using PanResponder, you could use the following code to extract the x and y positions from gestureState.dx and gestureState.dy.
+We use a null in the first position of the array, as we are only interested in the second argument passed to the PanResponder handler,
+which is the gestureState.
You may notice that there is no obvious way to read the current value while animating. +This is because the value may only be known in the native runtime due to optimizations. +If you need to run JavaScript in response to the current value, there are two approaches:
spring.stopAnimation(callback) will stop the animation and invoke callback with the final value. This is useful when making gesture transitions.spring.addListener(callback) will invoke callback asynchronously while the animation is running, providing a recent value.
+This is useful for triggering state changes,
+for example snapping a bobble to a new option as the user drags it closer,
+because these larger state changes are less sensitive to a few frames of lag compared to continuous gestures like panning which need to run at 60 fps.Animated is designed to be fully serializable so that animations can be run in a high performance way, independent of the normal JavaScript event loop.
+This does influence the API, so keep that in mind when it seems a little trickier to do something compared to a fully synchronous system.
+Check out Animated.Value.addListener as a way to work around some of these limitations,
+but use it sparingly since it might have performance implications in the future.
The Animated API is designed to be serializable.
+By using the native driver,
+we send everything about the animation to native before starting the animation,
+allowing native code to perform the animation on the UI thread without having to go through the bridge on every frame.
+Once the animation has started, the JS thread can be blocked without affecting the animation.
Using the native driver for normal animations is quite simple.
+Just add useNativeDriver: true to the animation config when starting it.
Animated values are only compatible with one driver so if you use native driver when starting an animation on a value, +make sure every animation on that value also uses the native driver.
The native driver also works with Animated.event.
+This is specially useful for animations that follow the scroll position as without the native driver,
+the animation will always run a frame behind the gesture due to the async nature of React Native.
You can see the native driver in action by running the RNTester app, +then loading the Native Animated Example. +You can also take a look at the source code to learn how these examples were produced.
Not everything you can do with Animated is currently supported by the native driver.
+The main limitation is that you can only animate non-layout properties:
+things like transform and opacity will work, but flexbox and position properties will not.
+When using Animated.event, it will only work with direct events and not bubbling events.
+This means it does not work with PanResponder but does work with things like ScrollView#onScroll.
While using transform styles such as rotateY, rotateX, and others ensure the transform style perspective is in place.
+At this time some animations may not render on Android without it. Example below.
The RNTester app has various examples of Animated in use:
LayoutAnimation API #LayoutAnimation allows you to globally configure create and update
+animations that will be used for all views in the next render/layout cycle.
+This is useful for doing flexbox layout updates without bothering to measure or
+calculate specific properties in order to animate them directly, and is
+especially useful when layout changes may affect ancestors, for example a "see
+more" expansion that also increases the size of the parent and pushes down the
+row below which would otherwise require explicit coordination between the
+components in order to animate them all in sync.
Note that although LayoutAnimation is very powerful and can be quite useful,
+it provides much less control than Animated and other animation libraries, so
+you may need to use another approach if you can't get LayoutAnimation to do
+what you want.
Note that in order to get this to work on Android you need to set the following flags via UIManager:
This example uses a preset value, you can customize the animations as +you need, see LayoutAnimation.js +for more information.
requestAnimationFrame #requestAnimationFrame is a polyfill from the browser that you might be
+familiar with. It accepts a function as its only argument and calls that
+function before the next repaint. It is an essential building block for
+animations that underlies all of the JavaScript-based animation APIs. In
+general, you shouldn't need to call this yourself - the animation APIs will
+manage frame updates for you.
setNativeProps #As mentioned in the Direct Manipulation section,
+setNativeProps allows us to modify properties of native-backed
+components (components that are actually backed by native views, unlike
+composite components) directly, without having to setState and
+re-render the component hierarchy.
We could use this in the Rebound example to update the scale - this
+might be helpful if the component that we are updating is deeply nested
+and hasn't been optimized with shouldComponentUpdate.
If you find your animations with dropping frames (performing below 60 frames
+per second), look into using setNativeProps or shouldComponentUpdate to
+optimize them. Or you could run the animations on the UI thread rather than
+the JavaScript thread with the useNativeDriver
+option.
+You may also want to defer any computationally intensive work until after
+animations are complete, using the
+InteractionManager. You can monitor the
+frame rate by using the In-App Developer Menu "FPS Monitor" tool.
Improve this page by sending a pull request!
App extensions let you provide custom functionality and content outside of your main app. There are different types of app extensions on iOS, and they are all covered in the App Extension Programming Guide. In this guide, we'll briefly cover how you may take advantage of app extensions on iOS.
As these extensions are loaded outside of the regular app sandbox, it's highly likely that several of these app extensions will be loaded simultaneously. As you might expect, these extensions have small memory usage limits. Keep these in mind when developing your app extensions. It's always highly recommended to test your application on an actual device, and more so when developing app extensions: too frequently, developers find that their extension works just fine in the iOS Simulator, only to get user reports that their extension is not loading on actual devices.
We highly recommend that you watch Conrad Kramer's talk on Memory Use in Extensions to learn more about this topic.
The memory limit of a Today widget is 16 MB. As it happens, Today widget implementations using React Native may work unreliably because the memory usage tends to be too high. You can tell if your Today widget is exceeding the memory limit if it yields the message 'Unable to Load':

Always make sure to test your app extensions in a real device, but be aware that this may not be sufficient, especially when dealing with Today widgets. Debug-configured builds are more likely to exceed the memory limits, while release-configured builds don't fail right away. We highly recommend that you use Xcode's Instruments to analyze your real world memory usage, as it's very likely that your release-configured build is very close to the 16 MB limit. In situations like these, it is easy to go over the 16 MB limit by performing common operations, such as fetching data from an API.
To experiment with the limits of React Native Today widget implementations, try extending the example project in react-native-today-widget.
Other types of app extensions have greater memory limits than the Today widget. For instance, Custom Keyboard extensions are limited to 48 MB, and Share extensions are limited to 120 MB. Implementing such app extensions with React Native is more viable. One proof of concept example is react-native-ios-share-extension.
Improve this page by sending a pull request!
AppRegistry is the JS entry point to running all React Native apps. App
+root components should register themselves with
+AppRegistry.registerComponent, then the native system can load the bundle
+for the app and then actually run the app when it's ready by invoking
+AppRegistry.runApplication.
To "stop" an application when a view should be destroyed, call
+AppRegistry.unmountApplicationComponentAtRootTag with the tag that was
+passed into runApplication. These should always be used as a pair.
AppRegistry should be required early in the require sequence to make
+sure the JS execution environment is setup before other modules are
+required.
Register a headless task. A headless task is a bit of code that runs without a UI. +@param taskKey the key associated with this task +@param task a promise returning function that takes some data passed from the native side as + the only argument; when the promise is resolved or rejected the native side is + notified of this event and it may decide to destroy the JS context.
Only called from native code. Starts a headless task.
@param taskId the native id for this task instance to keep track of its execution +@param taskKey the key for the task to start +@param data the data to pass to the task
Improve this page by sending a pull request!
AppState can tell you if the app is in the foreground or background,
+and notify you when the state changes.
AppState is frequently used to determine the intent and proper behavior when +handling push notifications.
active - The app is running in the foregroundbackground - The app is running in the background. The user is either
+ in another app or on the home screeninactive - This is a state that occurs when transitioning between
+ foreground & background, and during periods of inactivity such as
+ entering the Multitasking view or in the event of an incoming callFor more information, see +Apple's documentation
To see the current state, you can check AppState.currentState, which
+will be kept up-to-date. However, currentState will be null at launch
+while AppState retrieves it over the bridge.
This example will only ever appear to say "Current state is: active" because
+the app is only visible to the user when in the active state, and the null
+state will happen only momentarily.
Add a handler to AppState changes by listening to the change event type
+and providing the handler
TODO: now that AppState is a subclass of NativeEventEmitter, we could deprecate
+addEventListener and removeEventListener and just use addListener and
+listener.remove() directly. That will be a breaking change though, as both
+the method and event names are different (addListener events are currently
+required to be globally unique).
Remove a handler by passing the change event type and the handler
Improve this page by sending a pull request!
AsyncStorage is a simple, unencrypted, asynchronous, persistent, key-value storage
+system that is global to the app. It should be used instead of LocalStorage.
It is recommended that you use an abstraction on top of AsyncStorage
+instead of AsyncStorage directly for anything more than light usage since
+it operates globally.
On iOS, AsyncStorage is backed by native code that stores small values in a
+serialized dictionary and larger values in separate files. On Android,
+AsyncStorage will use either RocksDB or SQLite
+based on what is available.
The AsyncStorage JavaScript code is a simple facade that provides a clear
+JavaScript API, real Error objects, and simple non-multi functions. Each
+method in the API returns a Promise object.
Persisting data:
Fetching data:
Fetches an item for a key and invokes a callback upon completion.
+Returns a Promise object.
| Name and Type | Description |
|---|---|
| key string | Key of the item to fetch. |
| [callback] ?(error: ?Error, result: ?string) => void | Function that will be called with a result if found or + any error. |
Sets the value for a key and invokes a callback upon completion.
+Returns a Promise object.
| Name and Type | Description |
|---|---|
| key string | Key of the item to set. |
| value string | Value to set for the |
| [callback] ?(error: ?Error) => void | Function that will be called with any error. |
Removes an item for a key and invokes a callback upon completion.
+Returns a Promise object.
| Name and Type | Description |
|---|---|
| key string | Key of the item to remove. |
| [callback] ?(error: ?Error) => void | Function that will be called with any error. |
Merges an existing key value with an input value, assuming both values
+are stringified JSON. Returns a Promise object.
NOTE: This is not supported by all native implementations.
| Name and Type | Description |
|---|---|
| key string | Key of the item to modify. |
| value string | New value to merge for the |
| [callback] ?(error: ?Error) => void | Function that will be called with any error. |
Erases all AsyncStorage for all clients, libraries, etc. You probably
+don't want to call this; use removeItem or multiRemove to clear only
+your app's keys. Returns a Promise object.
| Name and Type | Description |
|---|---|
| [callback] ?(error: ?Error) => void | Function that will be called with any error. |
Gets all keys known to your app; for all callers, libraries, etc.
+Returns a Promise object.
| Name and Type | Description |
|---|---|
| [callback] ?(error: ?Error, keys: ?Array<string>) => void | Function that will be called the keys found and any error. |
Flushes any pending requests using a single batch call to get the data.
This allows you to batch the fetching of items given an array of key
+inputs. Your callback will be invoked with an array of corresponding
+key-value pairs found:
The method returns a Promise object.
| Name and Type | Description |
|---|---|
| keys Array<string> | Array of key for the items to get. |
| [callback] ?(errors: ?Array<Error>, result: ?Array<Array<string>>) => void | Function that will be called with a key-value array of + the results, plus an array of any key-specific errors found. |
Use this as a batch operation for storing multiple key-value pairs. When +the operation completes you'll get a single callback with any errors:
The method returns a Promise object.
| Name and Type | Description |
|---|---|
| keyValuePairs Array<Array<string>> | Array of key-value array for the items to set. |
| [callback] ?(errors: ?Array<Error>) => void | Function that will be called with an array of any + key-specific errors found. |
Call this to batch the deletion of all keys in the keys array. Returns
+a Promise object.
| Name and Type | Description |
|---|---|
| keys Array<string> | Array of key for the items to delete. |
| [callback] ?(errors: ?Array<Error>) => void | Function that will be called an array of any key-specific + errors found. |
Batch operation to merge in existing and new values for a given set of
+keys. This assumes that the values are stringified JSON. Returns a
+Promise object.
NOTE: This is not supported by all native implementations.
| Name and Type | Description |
|---|---|
| keyValuePairs Array<Array<string>> | Array of key-value array for the items to merge. |
| [callback] ?(errors: ?Array<Error>) => void | Function that will be called with an array of any + key-specific errors found. |
Improve this page by sending a pull request!
Detect hardware button presses for back navigation.
Android: Detect hardware back button presses, and programmatically invoke the default back button +functionality to exit the app if there are no listeners or if none of the listeners return true.
tvOS: Detect presses of the menu button on the TV remote. (Still to be implemented: +programmatically disable menu button handling +functionality to exit the app if there are no listeners or if none of the listeners return true.)
iOS: Not applicable.
The event subscriptions are called in reverse order (i.e. last registered subscription first), +and if one subscription returns true then subscriptions registered earlier will not be called.
Example:
Improve this page by sending a pull request!
Apple TV support has been implemented with the intention of making existing React Native iOS applications "just work" on tvOS, with few or no changes needed in the JavaScript code for the applications.
The RNTester app supports Apple TV; use the RNTester-tvOS build target to build for tvOS.
Native layer: React Native Xcode projects all now have Apple TV build targets, with names ending in the string '-tvOS'.
react-native init: New React Native projects created with react-native init will have Apple TV target automatically created in their XCode projects.
JavaScript layer: Support for Apple TV has been added to Platform.ios.js. You can check whether code is running on AppleTV by doing
General support for tvOS: Apple TV specific changes in native code are all wrapped by the TARGET_OS_TV define. These include changes to suppress APIs that are not supported on tvOS (e.g. web views, sliders, switches, status bar, etc.), and changes to support user input from the TV remote or keyboard.
Common codebase: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.
Access to touchable controls: When running on Apple TV, the native view class is RCTTVView, which has additional methods to make use of the tvOS focus engine. The Touchable mixin has code added to detect focus changes and use existing methods to style the components properly and initiate the proper actions when the view is selected using the TV remote, so TouchableHighlight and TouchableOpacity will "just work". In particular:
touchableHandleActivePressIn will be executed when the touchable view goes into focustouchableHandleActivePressOut will be executed when the touchable view goes out of focustouchableHandlePress will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.TV remote/keyboard input: A new native class, RCTTVRemoteHandler, sets up gesture recognizers for TV remote events. When TV remote events occur, this class fires notifications that are picked up by RCTTVNavigationEventEmitter (a subclass of RCTEventEmitter), that fires a JS event. This event will be picked up by instances of the TVEventHandler JavaScript object. Application code that needs to implement custom handling of TV remote events can create an instance of TVEventHandler and listen for these events, as in the following code:
Dev Menu support: On the simulator, cmd-D will bring up the developer menu, just like on iOS. To bring it up on a real Apple TV device, make a long press on the play/pause button on the remote. (Please do not shake the Apple TV device, that will not work :) )
TV remote animations: RCTTVView native code implements Apple-recommended parallax animations to help guide the eye as the user navigates through views. The animations can be disabled or adjusted with new optional view properties.
Back navigation with the TV remote menu button: The BackHandler component, originally written to support the Android back button, now also supports back navigation on the Apple TV using the menu button on the TV remote.
TabBarIOS behavior: The TabBarIOS component wraps the native UITabBar API, which works differently on Apple TV. To avoid jittery rerendering of the tab bar in tvOS (see this issue), the selected tab bar item can only be set from Javascript on initial render, and is controlled after that by the user through native code.
Known issues:
removeClippedSubviews to false in ListView and similar components. For more discussion of this issue, see this PR.Improve this page by sending a pull request!
A basic button component that should render nicely on any platform. Supports +a minimal level of customization.

If this button doesn't look right for your app, you can build your own +button using TouchableOpacity +or TouchableNativeFeedback. +For inspiration, look at the source code for this button component. +Or, take a look at the wide variety of button components built by the community.
Example usage:
Text to display for blindness accessibility features
If true, disable all interactions for this component.
Handler to be called when the user taps the button
Used to locate this view in end-to-end tests.
Text to display inside the button
Improve this page by sending a pull request!
CameraRoll provides access to the local camera roll / gallery.
+Before using this you must link the RCTCameraRoll library.
+You can refer to Linking for help.
The user's permission is required in order to access the Camera Roll on devices running iOS 10 or later.
+Add the NSPhotoLibraryUsageDescription key in your Info.plist with a string that describes how your
+app will use this data. This key will appear as Privacy - Photo Library Usage Description in Xcode.
Saves the photo or video to the camera roll / gallery.
On Android, the tag must be a local image or video URI, such as "file:///sdcard/img.png".
On iOS, the tag can be any image URI (including local, remote asset-library and base64 data URIs) +or a local video file URI (remote or data URIs are not supported for saving video at this time).
If the tag has a file extension of .mov or .mp4, it will be inferred as a video. Otherwise
+it will be treated as a photo. To override the automatic choice, you can pass an optional
+type parameter that must be one of 'photo' or 'video'.
Returns a Promise which will resolve with the new URI.
Returns a Promise with photo identifier objects from the local camera
+roll of the device matching shape defined by getPhotosReturnChecker.
Expects a params object of the following shape:
first : {number} : The number of photos wanted in reverse order of the photo application (i.e. most recent first for SavedPhotos).after : {string} : A cursor that matches page_info { end_cursor } returned from a previous call to getPhotos.groupTypes : {string} : Specifies which group types to filter the results to. Valid values are:AlbumAllEventFacesLibraryPhotoStreamSavedPhotos // defaultgroupName : {string} : Specifies filter on group names, like 'Recent Photos' or custom album titles.assetType : {string} : Specifies filter on asset type. Valid values are:AllVideosPhotos // defaultmimeTypes : {string} : Filter by mimetype (e.g. image/jpeg).Returns a Promise which when resolved will be of the following shape:
edges : {Array<node>} An array of node objectsnode: {object} An object with the following shape:type: {string}group_name: {string}image: {object} : An object with the following shape:uri: {string}height: {number}width: {number}isStored: {boolean}timestamp: {number}location: {object} : An object with the following shape:latitude: {number}longitude: {number}altitude: {number}heading: {number}speed: {number}page_info : {object} : An object with the following shape:has_next_page: {boolean}start_cursor: {boolean}end_cursor: {boolean}Improve this page by sending a pull request!
Renders a boolean input.
This is a controlled component that requires an onValueChange callback that
+updates the value prop in order for the component to reflect user actions.
+If the value prop is not updated, the component will continue to render
+the supplied value prop instead of the expected result of any user actions.
@keyword checkbox +@keyword toggle
If true the user won't be able to toggle the checkbox. +Default value is false.
Used in case the props change removes the component.
Invoked with the new value when the value changes.
Used to locate this view in end-to-end tests.
The value of the checkbox. If true the checkbox will be turned on. +Default value is false.
Improve this page by sending a pull request!
Clipboard gives you an interface for setting and getting content from Clipboard on both iOS and Android
Get content of string type, this method returns a Promise, so you can use following code to get clipboard content
Set content of string type. You can use following code to set clipboard content
@param the content to be stored in the clipboard.
Improve this page by sending a pull request!
Components in React Native are styled using JavaScript. Color properties usually match how CSS works on the web.
React Native supports rgb() and rgba() in both hexadecimal and functional notation:
'#f0f' (#rgb)'#ff00ff' (#rrggbb)
'rgb(255, 0, 255)'
'rgba(255, 255, 255, 1.0)'
'#f0ff' (#rgba)
'#ff00ff00' (#rrggbbaa)hsl() and hsla() is supported in functional notation:
'hsl(360, 100%, 100%)''hsla(360, 100%, 100%, 1.0)'transparent #This is a shortcut for rgba(0,0,0,0):
'transparent'You can also use color names as values. React Native follows the CSS3 specification:
Improve this page by sending a pull request!
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.
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.
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 special, cross-language mechanisms that would allow us to pass information between them.
Properties are the simplest 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.
In order to embed a React Native view in a native component, we use RCTRootView. RCTRootView is a UIView that holds a React Native app. It also provides an interface between native side and the hosted app.
RCTRootView has an initializer that allows you to pass arbitrary properties down to the React Native app. The initialProperties parameter has to be an instance of NSDictionary. The dictionary is internally converted into a JSON object that the top-level JS component can reference.
RCTRootView also provides a read-write property appProperties. After appProperties 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.
It is fine to update properties anytime. However, updates have to be performed on the main thread. You use the getter on any thread.
There is no way to update only a few properties at a time. We suggest that you build it into your own wrapper instead.
Note: +Currently, JS functions
componentWillReceivePropsandcomponentWillUpdatePropsof the top level RN component will not be called after a prop update. However, you can access the new props incomponentWillMountfunction.
The problem exposing properties of native components is covered in detail in this article. In short, export properties with RCT_CUSTOM_VIEW_PROPERTY macro in your custom native component, then just use them in React Native as if the component was an ordinary React Native component.
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.
Although we have a flavor of cross-language callbacks (described here), 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.
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).
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.
Events are described in detail in this article. Note that using events gives us no guarantees about execution time, as the event is handled on a separate thread.
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:
reactTag as an identifier).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.
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 this article.
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.
Although this solution is complex, it is used in RCTUIManager, which is an internal React Native class that manages all React Native views.
Native modules can also be used to expose existing native libraries to JS. The Geolocation library is a living example of the idea.
Warning: +All native modules share the same namespace. Watch out for name collisions when creating new ones.
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.
This case is covered in this article. Basically, as all our native react views are subclasses of UIView, most style and size attributes will work like you would expect out of the box.
The simplest 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.
For instance, to make an RN app 200 (logical) pixels high, and the hosting view's width wide, we could do:
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.
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.
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.
ScrollView component. This guarantees that your content will always be available and it won't overlap with native views.RCTRootView. The owner is then responsible for re-laying out the subviews and keeping the UI consistent. We achieve this with RCTRootView's flexibility modes.RCTRootView supports 4 different size flexibility modes:
RCTRootViewSizeFlexibilityNone is the default value, which makes a root view's size fixed (but it still can be updated with setFrame:). The other three modes allow us to track React Native content's size updates. For instance, setting mode to RCTRootViewSizeFlexibilityHeight will cause React Native to measure the content's height and pass that information back to RCTRootView'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.
Warning: +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
flexbox) while you're usingRCTRootViewSizeFlexibilityWidthon the hostingRCTRootView.
Let's look at an example.
In the example we have a FlexibleSizeExampleView 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 RCTRootViewSizeFlexibilityHeight, which means that rootViewDidChangeIntrinsicSize: 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.
You can checkout full source code of the example here.
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 rootViewDidChangeIntrinsicSize: method will be called once the content size is known.
Note: React Native layout calculation is performed on a special thread, while native UI view updates are done on the main thread. This 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.
Note: React Native does not perform any layout calculations until the root view becomes a subview of some other views. If 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
UIView'shiddenproperty). Then change its visibility in the delegate method.
Improve this page by sending a pull request!
React Native provides a number of built-in components. You will find a full list of components and APIs on the sidebar to the left. If you're not sure where to get started, take a look at the following categories:
You're not limited to the components and APIs bundled with React Native. React Native is a community of thousands of developers. If you're looking for a library that does something specific, search the npm registry for packages mentioning react-native, or check out Awesome React Native for a curated list.
Most apps will end up using one of these basic components. You'll want to get yourself familiarized with all of these if you're new to React Native.
The most fundamental component for building a UI.
+A component for displaying text.
+A component for displaying images.
+A component for inputting text into the app via a keyboard.
+Provides a scrolling container that can host multiple components and views.
+Provides an abstraction layer similar to CSS stylesheets.
+Render common user interface controls on any platform using the following components. For platform specific components, keep reading.
+ +Unlike the more generic ScrollView, the following list view components only render elements that are currently showing on the screen. This makes them a great choice for displaying long lists of data.
A component for rendering performant scrollable lists.
+Like FlatList, but for sectioned lists.
Many of the following components provide wrappers for commonly used UIKit classes.
API to display an iOS action sheet or share sheet.
+Create an iOS alert dialog with a message or create a prompt for user input.
+Renders a date/time picker (selector) on iOS.
+Renders a image picker on iOS.
+A wrapper around UINavigationController, enabling you to implement a navigation stack.
Renders a UIProgressView on iOS.
Handle push notifications for your app, including permission handling and icon badge number.
+Renders a UISegmentedControl on iOS.
Renders a UITabViewController on iOS. Use with TabBarIOS.Item.
Many of the following components provide wrappers for commonly used Android classes.
Detect hardware button presses for back navigation.
+Opens the standard Android date picker dialog.
+Renders a DrawerLayout on Android.
Provides access to the permissions model introduced in Android M.
+Renders a ProgressBar on Android.
Opens the standard Android time picker dialog.
+Create an Android Toast alert.
+Renders a Toolbar on Android.
Container that allows to flip left and right between child views.
+These components may come in handy for certain applications. For an exhaustive list of components and APIs, check out the sidebar to the left.
Displays a circular loading indicator.
+Launches an alert dialog with the specified title and message.
+A library for creating fluid, powerful animations that are easy to build and maintain.
+Provides access to the local camera roll / gallery.
+Provides an interface for setting and getting content from the clipboard on both iOS and Android.
+Provides an interface for getting device dimensions.
+Provides a view that moves out of the way of the virtual keyboard automatically.
+Provides a general interface to interact with both incoming and outgoing app links.
+Provides a simple way to present content above an enclosing view.
+Provides access to the device pixel density.
+This component is used inside a ScrollView to add pull to refresh functionality.
Component to control the app status bar.
+A component that renders web content in a native view.
+Improve this page by sending a pull request!
React Native is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody using Facebook's mobile apps. If you're interested in contributing to React Native, hopefully this document makes the process for contributing clear.
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated.
There are many ways to contribute to React Native, and many of them do not involve writing any code. Here's a few ideas to get started:
Contributions are very welcome. If you think you need help planning your contribution, please hop into #react-native and let people know you're looking for a mentor.
Core contributors to React Native meet monthly and post their meeting notes on the React Native blog. You can also find ad hoc discussions in the React Native Core Contributors Facebook group.
One great way you can contribute to the project without writing any code is to help triage issues and pull requests as they come in.
You can learn more about handling issues in the maintainer's guide.
Some of the core team will be working directly on GitHub. These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
When a change made on GitHub is approved, it will first be imported into Facebook's internal source control. The change will eventually sync back to GitHub as a single commit once it has passed all internal tests.
We will do our best to keep master in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to communicate these changes and version appropriately so you can lock into a specific version if need be.
To see what changes are coming and provide better feedback to React Native contributors, use the latest release candidate when possible. By the time a release candidate is released, the changes it contains will have been shipped in production Facebook apps for over two weeks.
We use GitHub Issues for our public bugs. If you would like to report a problem, take a look around and see if someone already opened an issue about it. If you a are certain this is a new, unreported bug, you can submit a bug report.
If you have questions about using React Native, the Community page list various resources that should help you get started.
We also have a place where you can request features or enhancements. If you see anything you'd like to be implemented, vote it up and explain your use case.
When opening a new issue, always make sure to fill out the issue template. This step is very important! Not doing so may result in your issue getting closed. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template.
master. The bug may have already been fixed!We're not able to provide support through GitHub Issues. If you're looking for help with your code, consider asking on Stack Overflow or reaching out to the community through other channels.
Facebook has a bounty program for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
So you have decided to contribute code back to upstream by opening a pull request. You've invested a good chunk of time, and we appreciate it. We will do our best to work with you and get the PR looked at.
Working on your first Pull Request? You can learn how from this free video series:
How to Contribute to an Open Source Project on GitHub
We have a list of beginner friendly issues to help you get your feet wet in the React Native codebase and familiar with our contribution process. This is a great place to get started.
If you would like to request a new feature or enhancement but are not yet thinking about opening a pull request, we have a place to track feature requests.
If you intend to change the public API, or make any non-trivial changes to the implementation, we recommend filing an issue that includes [Proposal] in the title. This lets us reach an agreement on your proposal before you put significant effort into it. These types of issues should be rare. If you have been contributing to the project long enough, you will probably already have access to the React Native Core Contributors Facebook Group, where this sort of discussion is usually held.
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
Before submitting a pull request, please make sure the following is done:
master.npm run lint).All pull requests should be opened against the master branch.
Note: It is not necessary to keep clicking
Merge master to your branchon the PR page. You would want to merge master if there are conflicts or tests are failing. The Facebook-GitHub-Bot ultimately squashes all commits to a single one before merging your PR.
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website.
See What is a Test Plan? to learn more.
Make sure all tests pass on both Travis and Circle CI. PRs that break tests are unlikely to be merged. Learn more about testing your changes here.
When adding a new breaking change, follow this template in your pull request:
If your pull request is merged, a core contributor will update the list of breaking changes which is then used to populate the release notes.
Copy and paste this to the top of your new file(s):
If you've added a new module, add a @providesModule <moduleName> at the end of the comment. This will allow the haste package manager to find it.
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, the Facebook GitHub Bot will reply with a link to the CLA form. You may also complete your CLA here.
The core team will be monitoring for pull requests. Read what to expect from maintainers to understand what may happen after you open a pull request.
Our linter will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running npm run lint.
However, there are still some styles that the linter cannot pick up.
'use strict';' over "setTimeout and setInterval" over ' for string literal props{} of props should hug their values (no spaces)> of opening tags on the same line as the last prop/> of self-closing tags on their own line and left-align them with the opening <@property declarationsif, on the same line- method, @interface, and @implementation brackets on the following line* operator goes with the variable name (e.g. NSObject *variableName;)By contributing to React Native, you agree that your contributions will be licensed under its BSD license.
Improve this page by sending a pull request!
Opens the standard Android date picker dialog.
Opens the standard Android date picker dialog.
The available keys for the options object are:
date (Date object or timestamp in milliseconds) - date to show by defaultminDate (Date or timestamp in milliseconds) - minimum date that can be selectedmaxDate (Date object or timestamp in milliseconds) - maximum date that can be selectedmode (enum('calendar', 'spinner', 'default')) - To set the date-picker mode to calendar/spinner/defaultReturns a Promise which will be invoked an object containing action, year, month (0-11),
+day if the user picked a date. If the user dismissed the dialog, the Promise will
+still be resolved with action being DatePickerAndroid.dismissedAction and all the other keys
+being undefined. Always check whether the action before reading the values.
Note the native date picker dialog has some UI glitches on Android 4 and lower
+when using the minDate and maxDate options.
A date has been selected.
The dialog has been dismissed.
Improve this page by sending a pull request!
Use DatePickerIOS to render a date/time picker (selector) on iOS. This is
+a controlled component, so you must hook in to the onDateChange callback
+and update the date prop in order for the component to update, otherwise
+the user's change will be reverted immediately to reflect props.date as the
+source of truth.
The currently selected date.
Maximum date.
Restricts the range of possible date/time values.
Minimum date.
Restricts the range of possible date/time values.
The interval at which minutes can be selected.
The date picker mode.
Date change handler.
This is called when the user changes the date or time in the UI. +The first and only argument is a Date object representing the new +date and time.
Timezone offset in minutes.
By default, the date picker will use the device's timezone. With this +parameter, it is possible to force a certain timezone offset. For +instance, to show times in Pacific Standard Time, pass -7 * 60.
Improve this page by sending a pull request!
React Native supports a few keyboard shortcuts in the iOS Simulator. They are described below. To enable them, open the Hardware menu, select Keyboard, and make sure that "Connect Hardware Keyboard" is checked.
You can access the developer menu by shaking your device or by selecting "Shake Gesture" inside the Hardware menu in the iOS Simulator. You can also use the ⌘D keyboard shortcut when your app is running in the iOS Simulator, or ⌘M when running in an Android emulator.

The Developer Menu is disabled in release (production) builds.
Instead of recompiling your app every time you make a change, you can reload your app's JavaScript code instantly. To do so, select "Reload" from the Developer Menu. You can also press ⌘R in the iOS Simulator, or tap R twice on Android emulators.
You can speed up your development times by having your app reload automatically any time your code changes. Automatic reloading can be enabled by selecting "Enable Live Reload" from the Developer Menu.
You may even go a step further and keep your app running as new versions of your files are injected into the JavaScript bundle automatically by enabling Hot Reloading from the Developer Menu. This will allow you to persist the app's state through reloads.
There are some instances where hot reloading cannot be implemented perfectly. If you run into any issues, use a full reload to reset your app.
You will need to rebuild your app for changes to take effect in certain situations:
Images.xcassets on iOS or the res/drawable folder on Android.Errors and warnings are displayed inside your app in development builds.
In-app errors are displayed in a full screen alert with a red background inside your app. This screen is known as a RedBox. You can use console.error() to manually trigger one.
Warnings will be displayed on screen with a yellow background. These alerts are known as YellowBoxes. Click on the alerts to show more information or to dismiss them.
As with a RedBox, you can use console.warn() to trigger a YellowBox.
YellowBoxes can be disabled during development by using console.disableYellowBox = true;. Specific warnings can be ignored programmatically by setting an array of prefixes that should be ignored: console.ignoredYellowBox = ['Warning: ...'];.
In CI/Xcode, YellowBoxes can also be disabled by setting the IS_TESTING environment variable.
RedBoxes and YellowBoxes are automatically disabled in release (production) builds.
To debug the JavaScript code in Chrome, select "Debug JS Remotely" from the Developer Menu. This will open a new tab at http://localhost:8081/debugger-ui.
Select Tools → Developer Tools from the Chrome Menu to open the Developer Tools. You may also access the DevTools using keyboard shortcuts (⌘⌥I on macOS, Ctrl Shift I on Windows). You may also want to enable Pause On Caught Exceptions for a better debugging experience.
Note: the React Developer Tools Chrome extension does not work with React Native, but you can use its standalone version instead. Read this section to learn how.
To use a custom JavaScript debugger in place of Chrome Developer Tools, set the REACT_DEBUGGER environment variable to a command that will start your custom debugger. You can then select "Debug JS Remotely" from the Developer Menu to start debugging.
The debugger will receive a list of all project roots, separated by a space. For example, if you set REACT_DEBUGGER="node /path/to/launchDebugger.js --port 2345 --type ReactNative", then the command node /path/to/launchDebugger.js --port 2345 --type ReactNative /path/to/reactNative/app will be used to start your debugger.
Custom debugger commands executed this way should be short-lived processes, and they shouldn't produce more than 200 kilobytes of output.
You can use the standalone version of React Developer Tools to debug the React component hierarchy. To use it, install the react-devtools package globally:
Now run react-devtools from the terminal to launch the standalone DevTools app:

It should connect to your simulator within a few seconds.
Note: if you prefer to avoid global installations, you can add
react-devtoolsas a project dependency. Add thereact-devtoolspackage to your project usingnpm install --save-dev react-devtools, then add"react-devtools": "react-devtools"to thescriptssection in yourpackage.json, and then runnpm run react-devtoolsfrom your project folder to open the DevTools.
Open the in-app developer menu and choose "Show Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:

However, when react-devtools is running, Inspector will enter a special collapsed mode, and instead use the DevTools as primary UI. In this mode, clicking on something in the simulator will bring up the relevant components in the DevTools:

You can choose "Hide Inspector" in the same menu to exit this mode.
When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.
First, follow the instructions for debugging in Chrome to open the Chrome console.
Make sure that the dropdown in the top left corner of the Chrome console says debuggerWorker.js. This step is essential.
Then select a React component in React DevTools. There is a search box at the top that helps you find one by name. As soon as you select it, it will be available as $r in the Chrome console, letting you inspect its props, state, and instance properties.

You can enable a performance overlay to help you debug performance problems by selecting "Perf Monitor" in the Developer Menu.
You can display the console logs for an iOS or Android app by using the following commands in a terminal while the app is running:
You may also access these through Debug → Open System Log... in the iOS Simulator or by running adb logcat *:S ReactNative:V ReactNativeJS:V in a terminal while an Android app is running on a device or emulator.
If you're using Create React Native App, console logs already appear in the same terminal output as the packager.
If you're using Create React Native App, this is configured for you already.
On iOS devices, open the file RCTWebSocketExecutor.m and change "localhost" to the IP address of your computer, then select "Debug JS Remotely" from the Developer Menu.
On Android 5.0+ devices connected via USB, you can use the adb command line tool to setup port forwarding from the device to your computer:
adb reverse tcp:8081 tcp:8081
Alternatively, select "Dev Settings" from the Developer Menu, then update the "Debug server host for device" setting to match the IP address of your computer.
If you run into any issues, it may be possible that one of your Chrome extensions is interacting in unexpected ways with the debugger. Try disabling all of your extensions and re-enabling them one-by-one until you find the problematic extension.
Follow this guide to enable Stetho for Debug mode:
In android/app/build.gradle, add these lines in the dependencies section:
The above will configure Stetho v1.5.0. You can check at http://facebook.github.io/stetho/ if a newer version is available.
Create the following Java classes to wrap the Stetho call, one for release and one for debug:
Open android/app/src/main/java/com/{yourAppName}/MainApplication.java and replace the original onCreate function:
Open the project in Android Studio and resolve any dependency issues. The IDE should guide you through this steps after hovering your pointer over the red lines.
Run react-native run-android.
In a new Chrome tab, open: chrome://inspect, then click on the 'Inspect device' item next to "Powered by Stetho".
When working with native code, such as when writing native modules, you can launch the app from Android Studio or Xcode and take advantage of the native debugging features (setting up breakpoints, etc.) as you would in case of building a standard native app.
Improve this page by sending a pull request!
This should only be called from native code by sending the +didUpdateDimensions event.
@param {object} dims Simple string-keyed object of dimensions to set
Initial dimensions are set before runApplication is called so they should
+be available before any other require's are run, but may be updated later.
Note: Although dimensions are available immediately, they may change (e.g
+due to device rotation) so any rendering logic or styles that depend on
+these constants should try to call this function on every render, rather
+than caching the value (for example, using inline styles rather than
+setting a value in a StyleSheet).
Example: var {height, width} = Dimensions.get('window');
@param {string} dim Name of dimension as defined when calling set.
+@returns {Object?} Value for the dimension.
Add an event handler. Supported events:
change: Fires when a property within the Dimensions object changes. The argument
+to the event handler is an object with window and screen properties whose values
+are the same as the return values of Dimensions.get('window') and
+Dimensions.get('screen'), respectively.Remove an event handler.
Improve this page by sending a pull request!
It is sometimes necessary to make changes directly to a component
+without using state/props to trigger a re-render of the entire subtree.
+When using React in the browser for example, you sometimes need to
+directly modify a DOM node, and the same is true for views in mobile
+apps. setNativeProps is the React Native equivalent to setting
+properties directly on a DOM node.
Use setNativeProps when frequent re-rendering creates a performance bottleneck
Direct manipulation will not be a tool that you reach for +frequently; you will typically only be using it for creating +continuous animations to avoid the overhead of rendering the component +hierarchy and reconciling many views.
setNativePropsis imperative +and stores state in the native layer (DOM, UIView, etc.) and not +within your React components, which makes your code more difficult to +reason about. Before you use it, try to solve your problem withsetState+and shouldComponentUpdate.
TouchableOpacity
+uses setNativeProps internally to update the opacity of its child
+component:
This allows us to write the following code and know that the child will +have its opacity updated in response to taps, without the child having +any knowledge of that fact or requiring any changes to its implementation:
Let's imagine that setNativeProps was not available. One way that we
+might implement it with that constraint is to store the opacity value
+in the state, then update that value whenever onPress is fired:
This is computationally intensive compared to the original example - +React needs to re-render the component hierarchy each time the opacity +changes, even though other properties of the view and its children +haven't changed. Usually this overhead isn't a concern but when +performing continuous animations and responding to gestures, judiciously +optimizing your components can improve your animations' fidelity.
If you look at the implementation of setNativeProps in
+NativeMethodsMixin.js
+you will notice that it is a wrapper around RCTUIManager.updateView -
+this is the exact same function call that results from re-rendering -
+see receiveComponent in
+ReactNativeBaseComponent.js.
Composite components are not backed by a native view, so you cannot call
+setNativeProps on them. Consider this example:
If you run this you will immediately see this error: Touchable child
+must either be native or forward setNativeProps to a native component.
+This occurs because MyButton isn't directly backed by a native view
+whose opacity should be set. You can think about it like this: if you
+define a component with createReactClass you would not expect to be
+able to set a style prop on it and have that work - you would need to
+pass the style prop down to a child, unless you are wrapping a native
+component. Similarly, we are going to forward setNativeProps to a
+native-backed child component.
All we need to do is provide a setNativeProps method on our component
+that calls setNativeProps on the appropriate child with the given
+arguments.
You can now use MyButton inside of TouchableOpacity! A sidenote for
+clarity: we used the ref callback syntax here, rather than the traditional string-based ref.
You may have noticed that we passed all of the props down to the child
+view using {...this.props}. The reason for this is that
+TouchableOpacity is actually a composite component, and so in addition
+to depending on setNativeProps on its child, it also requires that the
+child perform touch handling. To do this, it passes on various
+props
+that call back to the TouchableOpacity component.
+TouchableHighlight, in contrast, is backed by a native view and only
+requires that we implement setNativeProps.
Another very common use case of setNativeProps is to clear the value
+of a TextInput. The controlled prop of TextInput can sometimes drop
+characters when the bufferDelay is low and the user types very
+quickly. Some developers prefer to skip this prop entirely and instead
+use setNativeProps to directly manipulate the TextInput value when
+necessary. For example, the following code demonstrates clearing the
+input when you tap a button:
If you update a property that is also managed by the render function,
+you might end up with some unpredictable and confusing bugs because
+anytime the component re-renders and that property changes, whatever
+value was previously set from setNativeProps will be completely
+ignored and overridden.
By intelligently applying
+shouldComponentUpdate
+you can avoid the unnecessary overhead involved in reconciling unchanged
+component subtrees, to the point where it may be performant enough to
+use setState instead of setNativeProps.
The methods described here are available on most of the default components provided by React Native. Note, however, that they are not available on composite components that aren't directly backed by a native view. This will generally include most components that you define in your own app.
Determines the location on screen, width, and height of the given view and returns the values via an async callback. If successful, the callback will be called with the following arguments:
Note that these measurements are not available until after the rendering has been completed in native. If you need the measurements as soon as possible, consider using the onLayout prop instead.
Determines the location of the given view in the window and returns the values via an async callback. If the React root view is embedded in another native view, this will give you the absolute coordinates. If successful, the callback will be called with the following arguments:
Like measure(), but measures the view relative an ancestor, specified as relativeToNativeNode. This means that the returned x, y are relative to the origin x, y of the ancestor view.
As always, to obtain a native node handle for a component, you can use ReactNative.findNodeHandle(component).
Requests focus for the given input or view. The exact behavior triggered will depend on the platform and type of view.
Removes focus from an input or view. This is the opposite of focus().
Improve this page by sending a pull request!
React component that wraps the platform DrawerLayout (Android only). The
+Drawer (typically used for navigation) is rendered with renderNavigationView
+and direct children are the main view (where your content goes). The navigation
+view is initially not visible on the screen, but can be pulled in from the
+side of the window specified by the drawerPosition prop and its width can
+be set by the drawerWidth prop.
Example:
Specifies the background color of the drawer. The default value is white. +If you want to set the opacity of the drawer, use rgba. Example:
Specifies the lock mode of the drawer. The drawer can be locked in 3 states:
+- unlocked (default), meaning that the drawer will respond (open/close) to touch gestures.
+- locked-closed, meaning that the drawer will stay closed and not respond to gestures.
+- locked-open, meaning that the drawer will stay opened and not respond to gestures.
+The drawer may still be opened and closed programmatically (openDrawer/closeDrawer).
Specifies the side of the screen from which the drawer will slide in.
Specifies the width of the drawer, more precisely the width of the view that be pulled in +from the edge of the window.
Determines whether the keyboard gets dismissed in response to a drag. + - 'none' (the default), drags do not dismiss the keyboard. + - 'on-drag', the keyboard is dismissed when a drag begins.
Function called whenever the navigation view has been closed.
Function called whenever the navigation view has been opened.
Function called whenever there is an interaction with the navigation view.
Function called when the drawer state has changed. The drawer can be in 3 states: +- idle, meaning there is no interaction with the navigation view happening at the time +- dragging, meaning there is currently an interaction with the navigation view +- settling, meaning that there was an interaction with the navigation view, and the +navigation view is now finishing its closing or opening animation
The navigation view that will be rendered to the side of the screen and can be pulled in.
Improve this page by sending a pull request!
The Easing module implements common easing functions. This module is used
+by Animate.timing() to convey physically
+believable motion in animations.
You can find a visualization of some common easing functions at +http://easings.net/
The Easing module provides several predefined animations through the
+following methods:
back provides a simple animation where the
+object goes slightly back before moving forwardbounce provides a bouncing animationease provides a simple inertial animationelastic provides a simple spring interactionThree standard easing functions are provided:
The poly function can be used to implement
+quartic, quintic, and other higher power functions.
Additional mathematical functions are provided by the following methods:
bezier provides a cubic bezier curvecircle provides a circular functionsin provides a sinusoidal functionexp provides an exponential functionThe following helpers are used to modify other easing functions.
A stepping function, returns 1 for any positive value of n.
A stepping function, returns 1 if n is greater than or equal to 1.
A linear function, f(t) = t. Position correlates to elapsed time one to
+one.
A simple inertial interaction, similar to an object slowly accelerating to +speed.
A quadratic function, f(t) = t * t. Position equals the square of elapsed
+time.
A cubic function, f(t) = t * t * t. Position equals the cube of elapsed
+time.
A power function. Position is equal to the Nth power of elapsed time.
n = 4: http://easings.net/#easeInQuart +n = 5: http://easings.net/#easeInQuint
A sinusoidal function.
A circular function.
An exponential function.
A simple elastic interaction, similar to a spring oscillating back and +forth.
Default bounciness is 1, which overshoots a little bit once. 0 bounciness +doesn't overshoot at all, and bounciness of N > 1 will overshoot about N +times.
http://easings.net/#easeInElastic
Wolfram Plots:
Use with Animated.parallel() to create a simple effect where the object
+animates back slightly as the animation starts.
Wolfram Plot:
Provides a simple bouncing effect.
Provides a cubic bezier curve, equivalent to CSS Transitions'
+transition-timing-function.
A useful tool to visualize cubic bezier curves can be found at +http://cubic-bezier.com/
Runs an easing function forwards.
Runs an easing function backwards.
Makes any easing function symmetrical. The easing function will run +forwards for half of the duration, then backwards for the rest of the +duration.
Improve this page by sending a pull request!
A performant interface for rendering simple, flat lists, supporting the most handy features:
If you need section support, use <SectionList>.
Minimal Example:
More complex example demonstrating PureComponent usage for perf optimization and avoiding bugs.
onPressItem handler, the props will remain === and PureComponent will
+prevent wasteful re-renders unless the actual id, selected, or title props change, even
+if the inner SomeOtherWidget has no such optimizations.extraData={this.state} to FlatList we make sure FlatList itself will re-render
+when the state.selected changes. Without setting this prop, FlatList would not know it
+needs to re-render any items because it is also a PureComponent and the prop comparison will
+not show any changes.keyExtractor tells the list to use the ids for the react keys.This is a convenience wrapper around <VirtualizedList>,
+and thus inherits its props (as well as those of ScrollView) that aren't explicitly listed
+here, along with the following caveats:
PureComponent which means that it will not re-render if props remain shallow-
+equal. Make sure that everything your renderItem function depends on is passed as a prop
+(e.g. extraData) that is not === after updates, otherwise your UI may not update on
+changes. This includes the data prop and parent component state.key prop on each item and uses that for the React key.
+Alternatively, you can provide a custom keyExtractor prop.Also inherets ScrollView Props, unless it is nested in another FlatList of same orientation.
Scrolls to the end of the content. May be janky without getItemLayout prop.
Scrolls to the item at the specified index such that it is positioned in the viewable area
+such that viewPosition 0 places it at the top, 1 at the bottom, and 0.5 centered in the
+middle. viewOffset is a fixed number of pixels to offset the final target position.
Note: cannot scroll to locations outside the render window without specifying the
+getItemLayout prop.
Requires linear scan through data - use scrollToIndex instead if possible.
Note: cannot scroll to locations outside the render window without specifying the
+getItemLayout prop.
Scroll to a specific content pixel offset in the list.
Check out scrollToOffset of VirtualizedList
Tells the list an interaction has occured, which should trigger viewability calculations, e.g.
+if waitForInteractions is true and the user has not scrolled. This is typically called by
+taps on items or by navigation actions.
Displays the scroll indicators momentarily.
Improve this page by sending a pull request!
A component can specify the layout of its children using the flexbox algorithm. Flexbox is designed to provide a consistent layout on different screen sizes.
You will normally use a combination of flexDirection, alignItems, and justifyContent to achieve the right layout.
Flexbox works the same way in React Native as it does in CSS on the web, with a few exceptions. The defaults are different, with
flexDirectiondefaulting tocolumninstead ofrow, and theflexparameter only supporting a single number.
Adding flexDirection to a component's style determines the primary axis of its layout. Should the children be organized horizontally (row) or vertically (column)? The default is column.
Adding justifyContent to a component's style determines the distribution of children along the primary axis. Should children be distributed at the start, the center, the end, or spaced evenly? Available options are flex-start, center, flex-end, space-around, and space-between.
Adding alignItems to a component's style determines the alignment of children along the secondary axis (if the primary axis is row, then the secondary is column, and vice versa). Should children be aligned at the start, the center, the end, or stretched to fill? Available options are flex-start, center, flex-end, and stretch.
For
stretchto have an effect, children must not have a fixed dimension along the secondary axis. In the following example, settingalignItems: stretchdoes nothing until thewidth: 50is removed from the children.
We've covered the basics, but there are many other styles you may need for layouts. The full list of props that control layout is documented here.
We're getting close to being able to build a real application. One thing we are still missing is a way to take user input, so let's move on to learn how to handle text input with the TextInput component.
Improve this page by sending a pull request!
The Geolocation API extends the web spec: +https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
As a browser polyfill, this API is available through the navigator.geolocation
+global - you do not need to import it.
You need to include the NSLocationWhenInUseUsageDescription key
+in Info.plist to enable geolocation when using the app. Geolocation is
+enabled by default when you create a project with react-native init.
In order to enable geolocation in the background, you need to include the +'NSLocationAlwaysUsageDescription' key in Info.plist and add location as +a background mode in the 'Capabilities' tab in Xcode.
To request access to location, you need to add the following line to your
+app's AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Android API >= 18 Positions will also contain a mocked boolean to indicate if position
+was created from a mock provider.
Request suitable Location permission based on the key configured on pList. +If NSLocationAlwaysUsageDescription is set, it will request Always authorization, +although if NSLocationWhenInUseUsageDescription is set, it will request InUse +authorization.
Invokes the success callback once with the latest location info. Supported +options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool) +On Android, if the location is cached this can return almost immediately, +or it will request an update which might take a while.
Invokes the success callback whenever the location changes. Supported +options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool), distanceFilter(m), useSignificantChanges (bool)
Improve this page by sending a pull request!
The gesture responder system manages the lifecycle of gestures in your app. A touch can go through several phases as the app determines what the user's intention is. For example, the app needs to determine if the touch is scrolling, sliding on a widget, or tapping. This can even change during the duration of a touch. There can also be multiple simultaneous touches.
The touch responder system is needed to allow components to negotiate these touch interactions without any additional knowledge about their parent or child components. This system is implemented in ResponderEventPlugin.js, which contains further details and documentation.
To make your app feel great, every action should have the following attributes:
These features make users more comfortable while using an app, because it allows people to experiment and interact without fear of making mistakes.
The responder system can be complicated to use. So we have provided an abstract Touchable implementation for things that should be "tappable". This uses the responder system and allows you to easily configure tap interactions declaratively. Use TouchableHighlight anywhere where you would use a button or link on web.
A view can become the touch responder by implementing the correct negotiation methods. There are two methods to ask the view if it wants to become responder:
View.props.onStartShouldSetResponder: (evt) => true, - Does this view want to become responder on the start of a touch?View.props.onMoveShouldSetResponder: (evt) => true, - Called for every touch move on the View when it is not the responder: does this view want to "claim" touch responsiveness?If the View returns true and attempts to become the responder, one of the following will happen:
View.props.onResponderGrant: (evt) => {} - The View is now responding for touch events. This is the time to highlight and show the user what is happeningView.props.onResponderReject: (evt) => {} - Something else is the responder right now and will not release itIf the view is responding, the following handlers can be called:
View.props.onResponderMove: (evt) => {} - The user is moving their fingerView.props.onResponderRelease: (evt) => {} - Fired at the end of the touch, ie "touchUp"View.props.onResponderTerminationRequest: (evt) => true - Something else wants to become responder. Should this view release the responder? Returning true allows releaseView.props.onResponderTerminate: (evt) => {} - The responder has been taken from the View. Might be taken by other views after a call to onResponderTerminationRequest, or might be taken by the OS without asking (happens with control center/ notification center on iOS)evt is a synthetic touch event with the following form:
nativeEventchangedTouches - Array of all touch events that have changed since the last eventidentifier - The ID of the touchlocationX - The X position of the touch, relative to the elementlocationY - The Y position of the touch, relative to the elementpageX - The X position of the touch, relative to the root elementpageY - The Y position of the touch, relative to the root elementtarget - The node id of the element receiving the touch eventtimestamp - A time identifier for the touch, useful for velocity calculationtouches - Array of all current touches on the screenonStartShouldSetResponder and onMoveShouldSetResponder are called with a bubbling pattern, where the deepest node is called first. That means that the deepest component will become responder when multiple Views return true for *ShouldSetResponder handlers. This is desirable in most cases, because it makes sure all controls and buttons are usable.
However, sometimes a parent will want to make sure that it becomes responder. This can be handled by using the capture phase. Before the responder system bubbles up from the deepest component, it will do a capture phase, firing on*ShouldSetResponderCapture. So if a parent View wants to prevent the child from becoming responder on a touch start, it should have a onStartShouldSetResponderCapture handler which returns true.
View.props.onStartShouldSetResponderCapture: (evt) => true,View.props.onMoveShouldSetResponderCapture: (evt) => true,For higher-level gesture interpretation, check out PanResponder.
Improve this page by sending a pull request!
This page will help you install and build your first React Native app. If you already have React Native installed, you can skip ahead to the Tutorial.
Create React Native App is the easiest way to start building a new React Native application. It allows you to start a project without installing or configuring any tools to build native code - no Xcode or Android Studio installation required (see Caveats).
Assuming that you have Node installed, you can use npm to install the create-react-native-app command line utility:
Then run the following commands to create a new React Native project called "AwesomeProject":
This will start a development server for you, and print a QR code in your terminal.
Install the Expo client app on your iOS or Android phone and connect to the same wireless network as your computer. Using the Expo app, scan the QR code from your terminal to open your project.
Now that you have successfully run the app, let's modify it. Open App.js in your text editor of choice and edit some lines. The application should reload automatically once you save your changes.
Congratulations! You've successfully run and modified your first React Native app.

Create React Native App also has a user guide you can reference if you have questions specific to the tool.
If you can't get this to work, see the Troubleshooting section in the README for Create React Native App.
If you're curious to learn more about React Native, continue on +to the Tutorial.
Create React Native App makes it really easy to run your React Native app on a physical device without setting up a development environment. If you want to run your app on the iOS Simulator or an Android Virtual Device, please refer to the instructions for building projects with native code to learn how to install Xcode and set up your Android development environment.
Once you've set these up, you can launch your app on an Android Virtual Device by running npm run android, or on the iOS Simulator by running npm run ios (macOS only).
Because you don't build any native code when using Create React Native App to create a project, it's not possible to include custom native modules beyond the React Native APIs and components that are available in the Expo client app.
If you know that you'll eventually need to include your own native code, Create React Native App is still a good way to get started. In that case you'll just need to "eject" eventually to create your own native builds. If you do eject, the "Building Projects with Native Code" instructions will be required to continue working on your project.
Create React Native App configures your project to use the most recent React Native version that is supported by the Expo client app. The Expo client app usually gains support for a given React Native version about a week after the React Native version is released as stable. You can check this document to find out what versions are supported.
If you're integrating React Native into an existing project, you'll want to skip Create React Native App and go directly to setting up the native build environment. Select "Building Projects with Native Code" above for instructions on configuring a native build environment for React Native.
Follow these instructions if you need to build native code in your project. For example, if you are integrating React Native into an existing application, or if you "ejected" from Create React Native App, you'll need this section.
+ +The instructions are a bit different depending on your development operating system, and whether you want to start developing for iOS or Android. If you want to develop for both iOS and Android, that's fine - you just have to pick +one to start with, since the setup is a bit different.
+ ++ +A Mac is required to build projects with native code for iOS. You can follow the Quick Start to learn how to build your app using Create React Native App instead.
You will need Node, Watchman, the React Native command line interface, and Xcode.
While you can use any editor of your choice to develop your app, you will need to install Xcode in order to set up the necessary tooling to build your React Native app for iOS.
You will need Node, Watchman, the React Native command line interface, a JDK, and Android Studio.
You will need Node, the React Native command line interface, a JDK, and Android Studio.
You will need Node, the React Native command line interface, Python2, a JDK, and Android Studio.
While you can use any editor of your choice to develop your app, you will need to install Android Studio in order to set up the necessary tooling to build your React Native app for Android.
We recommend installing Node and Watchman using Homebrew. Run the following commands in a Terminal after installing Homebrew:
If you have already installed Node on your system, make sure it is version 4 or newer.
Watchman is a tool by Facebook for watching changes in the filesystem. It is highly recommended you install it for better performance.
Follow the installation instructions for your Linux distribution to install Node 6 or newer.
We recommend installing Node and Python2 via Chocolatey, a popular package manager for Windows.
React Native also requires a recent version of the Java SE Development Kit (JDK), as well as Python 2. Both can be installed using Chocolatey.
Open an Administrator Command Prompt (right click Command Prompt and select "Run as Administrator"), then run the following command:
If you have already installed Node on your system, make sure it is version 4 or newer. If you already have a JDK on your system, make sure it is version 8 or newer.
You can find additional installation options on Node's Downloads page.
Node comes with npm, which lets you install the React Native command line interface.
Run the following command in a Terminal:
If you get an error like
Cannot find module 'npmlog', try installing npm directly:curl -0 -L https://npmjs.org/install.sh | sudo sh.
Node comes with npm, which lets you install the React Native command line interface.
Run the following command in a Command Prompt or shell:
If you get an error like
Cannot find module 'npmlog', try installing npm directly:curl -0 -L https://npmjs.org/install.sh | sudo sh.
The easiest way to install Xcode is via the Mac App Store. Installing Xcode will also install the iOS Simulator and all the necessary tools to build your iOS app.
If you have already installed Xcode on your system, make sure it is version 8 or higher.
You will also need to install the Xcode Command Line Tools. Open Xcode, then choose "Preferences..." from the Xcode menu. Go to the Locations panel and install the tools by selecting the most recent version in the Command Line Tools dropdown.

React Native requires a recent version of the Java SE Development Kit (JDK). Download and install JDK 8 or newer if needed.
Setting up your development environment can be somewhat tedious if you're new to Android development. If you're already familiar with Android development, there are a few things you may need to configure. In either case, please make sure to carefully follow the next few steps.
Download and install Android Studio. Choose a "Custom" setup when prompted to select an installation type. Make sure the boxes next to all of the following are checked:
Android SDKAndroid SDK PlatformPerformance (Intel ® HAXM)Android Virtual DeviceAndroid SDKAndroid SDK PlatformAndroid Virtual DeviceThen, click "Next" to install all of these components.
If the checkboxes are grayed out, you will have a chance to install these components later on.
Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.
Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the Android 6.0 (Marshmallow) SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.
The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".


The SDK Manager can also be found within the Android Studio "Preferences" dialog, under Appearance & Behavior → System Settings → Android SDK.
Select the "SDK Platforms" tab from within the SDK Manager, then check the box next to "Show Package Details" in the bottom right corner. Look for and expand the Android 6.0 (Marshmallow) entry, then make sure the following items are all checked:
Google APIsAndroid SDK Platform 23Intel x86 Atom_64 System ImageGoogle APIs Intel x86 Atom_64 System Image

Next, select the "SDK Tools" tab and check the box next to "Show Package Details" here as well. Look for and expand the "Android SDK Build-Tools" entry, then make sure that 23.0.1 is selected.


Finally, click "Apply" to download and install the Android SDK and related build tools.


The React Native tools require some environment variables to be set up in order to build apps with native code.
Add the following lines to your $HOME/.bash_profile config file:
.bash_profileis specific tobash. If you're using another shell, you will need to edit the appropriate shell-specific config file.
Type source $HOME/.bash_profile to load the config into your current shell. Verify that ANDROID_HOME has been added to your path by running echo $PATH.
Please make sure you use the correct Android SDK path. You can find the actual location of the SDK in the Android Studio "Preferences" dialog, under Appearance & Behavior → System Settings → Android SDK.
Open the System pane under System and Security in the Control Panel, then click on Change settings.... Open the Advanced tab and click on Environment Variables.... Click on New... to create a new ANDROID_HOME user variable that points to the path to your Android SDK:

The SDK is installed, by default, at the following location:
You can find the actual location of the SDK in the Android Studio "Preferences" dialog, under Appearance & Behavior → System Settings → Android SDK.
Open a new Command Prompt window to ensure the new environment variable is loaded before proceeding to the next step.
Follow the Watchman installation guide to compile and install Watchman from source.
Watchman is a tool by Facebook for watching +changes in the filesystem. It is highly recommended you install it for better performance, but it's alright to skip this if you find the process to be tedious.
Use the React Native command line interface to generate a new React Native project called "AwesomeProject":
This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Create React Native App, or if you're adding iOS support to an existing React Native project (see Platform Specific Code).
Use the React Native command line interface to generate a new React Native project called "AwesomeProject":
This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Create React Native App, or if you're adding Android support to an existing React Native project (see Platform Specific Code).
You will need an Android device to run your React Native Android app. This can be either a physical Android device, or more commonly, you can use an Android Virtual Device which allows you to emulate an Android device on your computer.
Either way, you will need to prepare the device to run Android apps for development.
If you have a physical Android device, you can use it for development in place of an AVD by plugging it in to your computer using a USB cable and following the instructions here.
You can see the list of available Android Virtual Devices (AVDs) by opening the "AVD Manager" from within Android Studio. Look for an icon that looks like this:

If you have just installed Android Studio, you will likely need to create a new AVD. Select "Create Virtual Device...", then pick any Phone from the list and click "Next".


Select the "x86 Images" tab, then look for the Marshmallow API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.
We recommend configuring VM acceleration on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.

If you don't have HAXM installed, click on "Install HAXM" or follow these instructions to set it up, then go back to the AVD Manager.


If you don't have HAXM installed, follow these instructions to set it up, then go back to the AVD Manager.

Click "Next" then "Finish" to create your AVD. At this point you should be able to click on the green triangle button next to your AVD to launch it, then proceed to the next step.
Run react-native run-ios inside your React Native project folder:
You should see your new app running in the iOS Simulator shortly.

react-native run-ios is just one way to run your app. You can also run it directly from within Xcode or Nuclide.
If you can't get this to work, see the Troubleshooting page.
The above command will automatically run your app on the iOS Simulator by default. If you want to run the app on an actual physical iOS device, please follow the instructions here.
Run react-native run-android inside your React Native project folder:
If everything is set up correctly, you should see your new app running in your Android emulator shortly.


react-native run-android is just one way to run your app - you can also run it directly from within Android Studio or Nuclide.
If you can't get this to work, see the Troubleshooting page.
Now that you have successfully run the app, let's modify it.
index.js in your text editor of choice and edit some lines.⌘R in your iOS Simulator to reload the app and see your changes!index.js in your text editor of choice and edit some lines.R key twice or select Reload from the Developer Menu (⌘M) to see your changes!Now that you have successfully run the app, let's modify it.
index.js in your text editor of choice and edit some lines.R key twice or select Reload from the Developer Menu (Ctrl + M) to see your changes!Congratulations! You've successfully run and modified your first React Native app.

Congratulations! You've successfully run and modified your first React Native app.

Turn on Live Reload in the Developer Menu. Your app will now reload automatically whenever you save any changes!
If you want to add this new React Native code to an existing application, check out the Integration guide.
If you're curious to learn more about React Native, continue on +to the Tutorial.
Turn on Live Reload in the Developer Menu. Your app will now reload automatically whenever you save any changes!
If you want to add this new React Native code to an existing application, check out the Integration guide.
If you're curious to learn more about React Native, continue on +to the Tutorial.
+Improve this page by sending a pull request!
TextInput is a basic component that allows the user to enter text. It has an onChangeText prop that takes
+a function to be called every time the text changed, and an onSubmitEditing prop that takes a function to be called when the text is submitted.
For example, let's say that as the user types, you're translating their words into a different language. In this new language, every single word is written the same way: 🍕. So the sentence "Hello there Bob" would be translated +as "🍕🍕🍕".
In this example, we store text in the state, because it changes over time.
There are a lot more things you might want to do with a text input. For example, you could validate the text inside while the user types. For more detailed examples, see the React docs on controlled components, or the reference docs for TextInput.
Text input is one of the ways the user interacts with the app. Next, let's look at another type of input and learn how to handle touches.
Improve this page by sending a pull request!
Users interact with mobile apps mainly through touch. They can use a combination of gestures, such as tapping on a button, scrolling a list, or zooming on a map. React Native provides components to handle all sorts of common gestures, as well as a comprehensive gesture responder system to allow for more advanced gesture recognition, but the one component you will most likely be interested in is the basic Button.
Button provides a basic button component that is rendered nicely on all platforms. The minimal example to display a button looks like this:
This will render a blue label on iOS, and a blue rounded rectangle with white text on Android. Pressing the button will call the "onPress" function, which in this case displays an alert popup. If you like, you can specify a "color" prop to change the color of your button.

Go ahead and play around with the Button component using the example below. You can select which platform your app is previewed in by clicking on the toggle in the bottom right, then click on "Tap to Play" to preview the app.
If the basic button doesn't look right for your app, you can build your own button using any of the "Touchable" components provided by React Native. The "Touchable" components provide the capability to capture tapping gestures, and can display feedback when a gesture is recognized. These components do not provide any default styling, however, so you will need to do a bit of work to get them looking nicely in your app.
Which "Touchable" component you use will depend on what kind of feedback you want to provide:
Generally, you can use TouchableHighlight anywhere you would use a button or link on web. The view's background will be darkened when the user presses down on the button.
You may consider using TouchableNativeFeedback on Android to display ink surface reaction ripples that respond to the user's touch.
TouchableOpacity can be used to provide feedback by reducing the opacity of the button, allowing the background to be seen through while the user is pressing down.
If you need to handle a tap gesture but you don't want any feedback to be displayed, use TouchableWithoutFeedback.
In some cases, you may want to detect when a user presses and holds a view for a set amount of time. These long presses can be handled by passing a function to the onLongPress props of any of the "Touchable" components.
Let's see all of these in action:
Another gesture commonly used in mobile apps is the swipe or pan. This gesture allows the user to scroll through a list of items, or swipe through pages of content. In order to handle these and other gestures, we'll learn how to use a ScrollView next.
Improve this page by sending a pull request!
Headless JS is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music.
A task is a simple async function that you register on AppRegistry, similar to registering React applications:
Then, in SomeTaskName.js:
You can do anything in your task as long as it doesn't touch UI: network requests, timers and so on. Once your task completes (i.e. the promise is resolved), React Native will go into "paused" mode (unless there are other tasks running, or there is a foreground app).
Yes, this does still require some native code, but it's pretty thin. You need to extend HeadlessJsTaskService and override getTaskConfig, e.g.:
Then add the service to your AndroidManifest.xml file:
Now, whenever you start your service, e.g. as a periodic task or in response to some system event / broadcast, JS will spin up, run your task, then spin down.
Example:
boolean argument to control this behaviour.BroadcastReceiver, make sure to call HeadlessJsTaskService.acquireWakeLockNow() before returning from onReceive().Service can be started from Java API. First you need to decide when the service should be started and implement your solution accordingly. Here is a simple example that reacts to network connection change.
Following lines shows part of Android manifest file for registering broadcast receiver.
Broadcast receiver then handles intent that was broadcasted in onReceive function. This is a great place to check whether your app is on foreground or not. If app is not on foreground we can prepare our intent to be started, with no information or additional information bundled using putExta (keep in mind bundle can handle only parcelable values). In the end service is started and wakelock is acquired.
Improve this page by sending a pull request!
A component's height and width determine its size on the screen.
The simplest way to set the dimensions of a component is by adding a fixed width and height to style. All dimensions in React Native are unitless, and represent density-independent pixels.
Setting dimensions this way is common for components that should always render at exactly the same size, regardless of screen dimensions.
Use flex in a component's style to have the component expand and shrink dynamically based on available space. Normally you will use flex: 1, which tells a component to fill all available space, shared evenly amongst each other component with the same parent. The larger the flex given, the higher the ratio of space a component will take compared to its siblings.
A component can only expand to fill available space if its parent has dimensions greater than 0. If a parent does not have either a fixed
widthandheightorflex, the parent will have dimensions of 0 and theflexchildren will not be visible.
After you can control a component's size, the next step is to learn how to lay it out on the screen.
Improve this page by sending a pull request!
A React component for displaying different types of images, +including network images, static resources, temporary local images, and +images from local disk, such as the camera roll.
This example shows fetching and displaying an image from local storage
+as well as one from network and even from data provided in the 'data:' uri scheme.
Note that for network and data images, you will need to manually specify the dimensions of your image!
You can also add style to an image:
When building your own native code, GIF and WebP are not supported by default on Android.
You will need to add some optional modules in android/app/build.gradle, depending on the needs of your app.
Also, if you use GIF with ProGuard, you will need to add this rule in proguard-rules.pro :
blurRadius: the blur radius of the blur filter added to the image
Invoked on load error with {nativeEvent: {error}}.
Invoked on mount and layout changes with
+{nativeEvent: {layout: {x, y, width, height}}}.
Invoked when load completes successfully.
Invoked when load either succeeds or fails.
Invoked on load start.
e.g., onLoadStart={(e) => this.setState({loading: true})}
Determines how to resize the image when the frame doesn't match the raw +image dimensions.
cover: Scale the image uniformly (maintain the image's aspect ratio)
+so that both dimensions (width and height) of the image will be equal
+to or larger than the corresponding dimension of the view (minus padding).
contain: Scale the image uniformly (maintain the image's aspect ratio)
+so that both dimensions (width and height) of the image will be equal to
+or less than the corresponding dimension of the view (minus padding).
stretch: Scale width and height independently, This may change the
+aspect ratio of the src.
repeat: Repeat the image to cover the frame of the view. The
+image will keep it's size and aspect ratio. (iOS only)
The image source (either a remote URL or a local file resource).
This prop can also contain several remote URLs, specified together with
+their width and height and potentially with scale/other URI arguments.
+The native side will then choose the best uri to display based on the
+measured size of the image container. A cache property can be added to
+control how networked request interacts with the local cache.
The currently supported formats are png, jpg, jpeg, bmp, gif,
+webp (Android only), psd (iOS only).
Changes the color of all the non-transparent pixels to the tintColor.
When the image has rounded corners, specifying an overlayColor will +cause the remaining space in the corners to be filled with a solid color. +This is useful in cases which are not supported by the Android +implementation of rounded corners: + - Certain resize modes, such as 'contain' + - Animated GIFs
A typical way to use this prop is with images displayed on a solid
+background and setting the overlayColor to the same color
+as the background.
For details of how this works under the hood, see +http://frescolib.org/docs/rounded-corners-and-circles.html
ImageResizeModeis anEnumfor different image resizing modes, set via the +resizeModestyle property onImagecomponents. The values arecontain,cover, +stretch,center,repeat.
A unique identifier for this element to be used in UI Automation +testing scripts.
The mechanism that should be used to resize the image when the image's dimensions
+differ from the image view's dimensions. Defaults to auto.
auto: Use heuristics to pick between resize and scale.
resize: A software operation which changes the encoded image in memory before it
+gets decoded. This should be used instead of scale when the image is much larger
+than the view.
scale: The image gets drawn downscaled or upscaled. Compared to resize, scale is
+faster (usually hardware accelerated) and produces higher quality images. This
+should be used if the image is smaller than the view. It should also be used if the
+image is slightly bigger than the view.
More details about resize and scale can be found at http://frescolib.org/docs/resizing-rotating.html.
The text that's read by the screen reader when the user interacts with +the image.
When true, indicates the image is an accessibility element.
When the image is resized, the corners of the size specified
+by capInsets will stay a fixed size, but the center content and borders
+of the image will be stretched. This is useful for creating resizable
+rounded buttons, shadows, and other resizable assets. More info in the
+official Apple documentation.
A static image to display while loading the image source.
uri - a string representing the resource identifier for the image, which
+should be either a local file path or the name of a static image resource
+(which should be wrapped in the require('./path/to/image.png') function).width, height - can be specified if known at build time, in which case
+these will be used to set the default <Image/> component dimensions.scale - used to indicate the scale factor of the image. Defaults to 1.0 if
+unspecified, meaning that one image pixel equates to one display point / DIP.number - Opaque type returned by something like require('./image.jpg').Invoked when a partial load of the image is complete. The definition of +what constitutes a "partial load" is loader specific though this is meant +for progressive JPEG loads.
Invoked on download progress with {nativeEvent: {loaded, total}}.
Retrieve the width and height (in pixels) of an image prior to displaying it. +This method can fail if the image cannot be found, or fails to download.
In order to retrieve the image dimensions, the image may first need to be +loaded or downloaded, after which it will be cached. This means that in +principle you could use this method to preload images, however it is not +optimized for that purpose, and may in future be implemented in a way that +does not fully load/download the image data. A proper, supported way to +preload images will be provided as a separate API.
Does not work for static image resources.
| Name and Type | Description |
|---|---|
| uri string | The location of the image. |
| success function | The function that will be called if the image was successfully found and width +and height retrieved. |
| [failure] function | The function that will be called if there was an error, such as failing to +to retrieve the image. |
Prefetches a remote image for later use by downloading it to the disk +cache
| Name and Type | Description |
|---|---|
| url string | The remote location of the image. |
Improve this page by sending a pull request!
Crop the image specified by the URI param. If URI points to a remote +image, it will be downloaded automatically. If the image cannot be +loaded/downloaded, the failure callback will be called.
If the cropping process is successful, the resultant cropped image +will be stored in the ImageStore, and the URI returned in the success +callback will point to the image in the store. Remember to delete the +cropped image from the ImageStore when you are done with it.
Improve this page by sending a pull request!
React Native provides a unified way of managing images and other media assets in your iOS and Android apps. To add a static image to your app, place it somewhere in your source code tree and reference it like this:
The image name is resolved the same way JS modules are resolved. In the example above, the packager will look for my-icon.png in the same folder as the component that requires it. Also, if you have my-icon.ios.png and my-icon.android.png, the packager will pick the correct file for the platform.
You can also use the @2x and @3x suffixes to provide images for different screen densities. If you have the following file structure:
...and button.js code contains:
...the packager will bundle and serve the image corresponding to device's screen density. For example, check@2x.png, will be used on an iPhone 7, whilecheck@3x.png will be used on an iPhone 7 Plus or a Nexus 5. If there is no image matching the screen density, the closest best option will be selected.
On Windows, you might need to restart the packager if you add new images to your project.
Here are some benefits that you get:
In order for this to work, the image name in require has to be known statically.
Note that image sources required this way include size (width, height) info for the Image. If you need to scale the image dynamically (i.e. via flex), you may need to manually set { width: undefined, height: undefined } on the style attribute.
The require syntax described above can be used to statically include audio, video or document files in your project as well. Most common file types are supported including .mp3, .wav, .mp4, .mov, .html and .pdf. See packager defaults for the full list.
You can add support for other types by creating a packager config file (see the packager config file for the full list of configuration options).
A caveat is that videos must use absolute positioning instead of flexGrow, since size info is not currently passed for non-image assets. This limitation doesn't occur for videos that are linked directly into Xcode or the Assets folder for Android.
If you are building a hybrid app (some UIs in React Native, some UIs in platform code) you can still use images that are already bundled into the app.
For images included via Xcode asset catalogs or in the Android drawable folder, use the image name without the extension:
For images in the Android assets folder, use the asset:/ scheme:
These approaches provide no safety checks. It's up to you to guarantee that those images are available in the application. Also you have to specify image dimensions manually.
Many of the images you will display in your app will not be available at compile time, or you will want to load some dynamically to keep the binary size down. Unlike with static resources, you will need to manually specify the dimensions of your image. It's highly recommended that you use https as well in order to satisfy App Transport Security requirements on iOS.
If you would like to set such things as the HTTP-Verb, Headers or a Body along with the image request, you may do this by defining these properties on the source object:
Sometimes, you might be getting encoded image data from a REST API call. You can use the 'data:' uri scheme to use these images. Same as for network resources, you will need to manually specify the dimensions of your image.
This is recommended for very small and dynamic images only, like icons in a list from a DB.
In some cases you might only want to display an image if it is already in the local cache, i.e. a low resolution placeholder until a higher resolution is available. In other cases you do not care if the image is outdated and are willing to display an outdated image to save bandwidth. The cache source property gives you control over how the network layer interacts with the cache.
default: Use the native platforms default strategy.reload: The data for the URL will be loaded from the originating source.
+No existing cache data should be used to satisfy a URL load request.force-cache: The existing cached data will be used to satisfy the request,
+regardless of its age or expiration date. If there is no existing data in the cache
+corresponding the request, the data is loaded from the originating source.only-if-cached: The existing cache data will be used to satisfy a request, regardless of
+its age or expiration date. If there is no existing data in the cache corresponding
+to a URL load request, no attempt is made to load the data from the originating source,
+and the load is considered to have failed.See CameraRoll for an example of
+using local resources that are outside of Images.xcassets.
iOS saves multiple sizes for the same image in your Camera Roll, it is very important to pick the one that's as close as possible for performance reasons. You wouldn't want to use the full quality 3264x2448 image as source when displaying a 200x200 thumbnail. If there's an exact match, React Native will pick it, otherwise it's going to use the first one that's at least 50% bigger in order to avoid blur when resizing from a close size. All of this is done by default so you don't have to worry about writing the tedious (and error prone) code to do it yourself.
In the browser if you don't give a size to an image, the browser is going to render a 0x0 element, download the image, and then render the image based with the correct size. The big issue with this behavior is that your UI is going to jump all around as images load, this makes for a very bad user experience.
In React Native this behavior is intentionally not implemented. It is more work for the developer to know the dimensions (or aspect ratio) of the remote image in advance, but we believe that it leads to a better user experience. Static images loaded from the app bundle via the require('./my-icon.png') syntax can be automatically sized because their dimensions are available immediately at the time of mounting.
For example, the result of require('./my-icon.png') might be:
In React Native, one interesting decision is that the src attribute is named source and doesn't take a string but an object with a uri attribute.
On the infrastructure side, the reason is that it allows us to attach metadata to this object. For example if you are using require('./my-icon.png'), then we add information about its actual location and size (don't rely on this fact, it might change in the future!). This is also future proofing, for example we may want to support sprites at some point, instead of outputting {uri: ...}, we can output {uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}} and transparently support spriting on all the existing call sites.
On the user side, this lets you annotate the object with useful attributes such as the dimension of the image in order to compute the size it's going to be displayed in. Feel free to use it as your data structure to store more information about your image.
A common feature request from developers familiar with the web is background-image. To handle this use case, you can use the <ImageBackground> component, which has the same props as <Image>, and add whatever children to it you would like to layer on top of it.
You might not want to use <ImageBackground> in some cases, since the implementation is very simple. Refer to <ImageBackground>'s source code for more insight, and create your own custom component when needed.
Please note that the following corner specific, border radius style properties are currently ignored by iOS's image component:
borderTopLeftRadiusborderTopRightRadiusborderBottomLeftRadiusborderBottomRightRadiusImage decoding can take more than a frame-worth of time. This is one of the major sources of frame drops on the web because decoding is done in the main thread. In React Native, image decoding is done in a different thread. In practice, you already need to handle the case when the image is not downloaded yet, so displaying the placeholder for a few more frames while it is decoding does not require any code change.
Improve this page by sending a pull request!
Check if the ImageStore contains image data for the specified URI. +@platform ios
Delete an image from the ImageStore. Images are stored in memory and
+must be manually removed when you are finished with them, otherwise they
+will continue to use up RAM until the app is terminated. It is safe to
+call removeImageForTag() without first calling hasImageForTag(), it
+will simply fail silently.
+@platform ios
Stores a base64-encoded image in the ImageStore, and returns a URI that
+can be used to access or display the image later. Images are stored in
+memory only, and must be manually deleted when you are finished with
+them by calling removeImageForTag().
Note that it is very inefficient to transfer large quantities of binary +data between JS and native code, so you should avoid calling this more +than necessary. +@platform ios
Retrieves the base64-encoded data for an image in the ImageStore. If the +specified URI does not match an image in the store, the failure callback +will be called.
Note that it is very inefficient to transfer large quantities of binary
+data between JS and native code, so you should avoid calling this more
+than necessary. To display an image in the ImageStore, you can just pass
+the URI to an <Image/> component; there is no need to retrieve the
+base64 data.
Improve this page by sending a pull request!
When the image has rounded corners, specifying an overlayColor will +cause the remaining space in the corners to be filled with a solid color. +This is useful in cases which are not supported by the Android +implementation of rounded corners: + - Certain resize modes, such as 'contain' + - Animated GIFs
A typical way to use this prop is with images displayed on a solid
+background and setting the overlayColor to the same color
+as the background.
For details of how this works under the hood, see +http://frescolib.org/docs/rounded-corners-and-circles.html
Improve this page by sending a pull request!
Building apps for mobile platforms is nuanced, there are many little details that developers coming from a web background often do not consider. This guide is intended to explain some of these nuances and demonstrate how you might factor them in to your application.
We are improving and adding more details to this page. If you'd like to help out, chime in at react-native/14979.
Entering text on touch phone is a challange - small screen, software keyboard. But based on what kind of data you need, you can make it easier by properly configuring the text inputs:
Check out TextInput docs for more configuration options.
Software keyboard takes almost half of the screen. If you have interactive elements that can get covered by the keyboard, make sure they are still accessible by using KeyboardAvoidingView (see docs).
On mobile phones it's hard to be very precise when pressing buttons. Make sure all interactive elements are 44x44 or larger. One way to do this is to leave enough space for the element, padding, minWidth and minHeight style values can be useful for that. Alternatively, you can use hitSlop prop to increase interactive area without affecting the layout. Here's a demo:
Android API 21+ uses the material design ripple to provide user with feedback when they touch an interactable area on the screen. React Native exposes this through the TouchableNativeFeedback component. Using this touchable effect instead of opacity or highlight will often make your app feel much more fitting on the platform. That said, you need to be careful when using it because it doesn't work on iOS or on Android API < 21, so you will need to fallback to using one of the other Touchable components on iOS. You can use a library like react-native-platform-touchable to handle the platform differences for you.
Material Design and Human Interface Guidelines are great resources for learning more about designing for mobile platforms.
Improve this page by sending a pull request!
React Native is great when you are starting a new mobile app from scratch. However, it also works well for adding a single view or user flow to existing native applications. With a few steps, you can add new React Native based features, screens, views, etc.
The specific steps are different depending on what platform you're targeting.
The keys to integrating React Native components into your iOS application are to:
RCTRootView to your iOS app. This view will serve as the container for your React Native component.The keys to integrating React Native components into your Android application are to:
ReactRootView to your Android app. This view will serve as the container for your React Native component.Follow the instructions for building apps with native code from the Getting Started guide to configure your development environment for building React Native apps for iOS.
To ensure a smooth experience, create a new folder for your integrated React Native project, then copy your existing iOS project to a /ios subfolder.
Follow the instructions for building apps with native code from the Getting Started guide to configure your development environment for building React Native apps for Android.
To ensure a smooth experience, create a new folder for your integrated React Native project, then copy your existing Android project to a /android subfolder.
Go to the root directory for your project and create a new package.json file with the following contents:
Next, you will install the react and react-native packages. Open a terminal or command prompt, then navigate to the root directory for your project and type the following commands:
This will create a new /node_modules folder in your project's root directory. This folder stores all the JavaScript dependencies required to build your project.
CocoaPods is a package management tool for iOS and macOS development. We use it to add the actual React Native framework code locally into your current project.
We recommend installing CocoaPods using Homebrew.
It is technically possible not to use CocoaPods, but that would require manual library and linker additions that would overly complicate this process.
Assume the app for integration is a 2048 game. Here is what the main menu of the native application looks like without React Native.
Assume the app for integration is a 2048 game. Here is what the main menu of the native application looks like without React Native.

Before you integrate React Native into your application, you will want to decide what parts of the React Native framework you would like to integrate. We will use CocoaPods to specify which of these "subspecs" your app will depend on.
The list of supported subspecs is available in /node_modules/react-native/React.podspec. They are generally named by functionality. For example, you will generally always want the Core subspec. That will get you the AppRegistry, StyleSheet, View and other core React Native libraries. If you want to add the React Native Text library (e.g., for <Text> elements), then you will need the RCTText subspec. If you want the Image library (e.g., for <Image> elements), then you will need the RCTImage subspec.
You can specify which subspecs your app will depend on in a Podfile file. The easiest way to create a Podfile is by running the CocoaPods init command in the /ios subfolder of your project:
The Podfile will contain a boilerplate setup that you will tweak for your integration purposes. In the end, Podfile should look something similar to this:
After you have created your Podfile, you are ready to install the React Native pod.
You should see output such as:
If you get a warning such as "The
swift-2048 [Debug]target overrides theFRAMEWORK_SEARCH_PATHSbuild setting defined inPods/Target Support Files/Pods-swift-2048/Pods-swift-2048.debug.xcconfig. This can lead to problems with the CocoaPods installation", then make sure theFramework Search PathsinBuild Settingsfor bothDebugandReleaseonly contain$(inherited).
Now we will actually modify the native iOS application to integrate React Native. For our 2048 sample app, we will add a "High Score" screen in React Native.
The first bit of code we will write is the actual React Native code for the new "High Score" screen that will be integrated into our application.
index.js file #First, create an empty index.js file in the root of your React Native project.
index.js is the starting point for React Native applications, and it is always required. It can be a small file that requires other file that are part of your React Native component or application, or it can contain all the code that is needed for it. In our case, we will just put everything in index.js.
In your index.js, create your component. In our sample here, we will add simple <Text> component within a styled <View>
RNHighScoresis the name of your module that will be used when you add a view to React Native from within your iOS application.
RCTRootView #Now that your React Native component is created via index.js, you need to add that component to a new or existing ViewController. The easiest path to take is to optionally create an event path to your component and then add that component to an existing ViewController.
We will tie our React Native component with a new native view in the ViewController that will actually host it called RCTRootView .
You can add a new link on the main game menu to go to the "High Score" React Native page.

We will now add an event handler from the menu link. A method will be added to the main ViewController of your application. This is where RCTRootView comes into play.
When you build a React Native application, you use the React Native packager to create an index.bundle that will be served by the React Native server. Inside index.bundle will be our RNHighScore module. So, we need to point our RCTRootView to the location of the index.bundle resource (via NSURL) and tie it to the module.
We will, for debugging purposes, log that the event handler was invoked. Then, we will create a string with the location of our React Native code that exists inside the index.bundle. Finally, we will create the main RCTRootView. Notice how we provide RNHighScores as the moduleName that we created above when writing the code for our React Native component.
First import the RCTRootView header.
The
initialPropertiesare here for illustration purposes so we have some data for our high score screen. In our React Native component, we will usethis.propsto get access to that data.
Note that
RCTRootView initWithURLstarts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using[RCTRootView alloc] initWithURL, useRCTBridge initWithBundleURLto create a bridge and then useRCTRootView initWithBridge.
First import the React library.
The
initialPropertiesare here for illustration purposes so we have some data for our high score screen. In our React Native component, we will usethis.propsto get access to that data.
Note that
RCTRootView bundleURLstarts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of usingRCTRootView bundleURL, useRCTBridge initWithBundleURLto create a bridge and then useRCTRootView initWithBridge.
When moving your app to production, the
NSURLcan point to a pre-bundled file on disk via something like[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];. You can use thereact-native-xcode.shscript innode_modules/react-native/scripts/to generate that pre-bundled file.
When moving your app to production, the
NSURLcan point to a pre-bundled file on disk via something likelet mainBundle = NSBundle(URLForResource: "main" withExtension:"jsbundle"). You can use thereact-native-xcode.shscript innode_modules/react-native/scripts/to generate that pre-bundled file.
Wire up the new link in the main menu to the newly added event handler method.

One of the easier ways to do this is to open the view in the storyboard and right click on the new link. Select something such as the
Touch Up Insideevent, drag that to the storyboard and then select the created method from the list provided.
You have now done all the basic steps to integrate React Native with your current application. Now we will start the React Native packager to build the index.bundle package and the server running on localhost to serve it.
Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project's Info.plist (or equivalent) file.
App Transport Security is good for your users. Make sure to re-enable it prior to releasing your app for production.
To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project:
If you are using Xcode or your favorite editor, build and run your native iOS application as normal. Alternatively, you can run the app from the command line using:
In our sample application, you should see the link to the "High Scores" and then when you click on that you will see the rendering of your React Native component.
Here is the native application home screen:

Here is the React Native high score screen:

If you are getting module resolution issues when running your application please see this GitHub issue for information and possible resolution. This comment seemed to be the latest possible resolution.
You can examine the code that added the React Native screen to our sample app on GitHub.
You can examine the code that added the React Native screen to our sample app on GitHub.
Add the React Native dependency to your app's build.gradle file:
If you want to ensure that you are always using a specific React Native version in your native build, replace
+with an actual React Native version you've downloaded fromnpm.
Add an entry for the local React Native maven directory to build.gradle. Be sure to add it to the "allprojects" block:
Make sure that the path is correct! You shouldn’t run into any “Failed to resolve: com.facebook.react:react-native:0.x.x" errors after running Gradle sync in Android Studio.
Next, make sure you have the Internet permission in your AndroidManifest.xml:
If you need to access to the DevSettingsActivity add to your AndroidManifest.xml:
This is only really used in dev mode when reloading JavaScript from the development server, so you can strip this in release builds if you need to.
Now we will actually modify the native Android application to integrate React Native.
The first bit of code we will write is the actual React Native code for the new "High Score" screen that will be integrated into our application.
index.js file #First, create an empty index.js file in the root of your React Native project.
index.js is the starting point for React Native applications, and it is always required. It can be a small file that requires other file that are part of your React Native component or application, or it can contain all the code that is needed for it. In our case, we will just put everything in index.js.
In your index.js, create your component. In our sample here, we will add simple <Text> component within a styled <View>:
If your app is targeting the Android API level 23 or greater, make sure you have the overlay permission enabled for the development build. You can check it with Settings.canDrawOverlays(this);. This is required in dev builds because react native development errors must be displayed above all the other windows. Due to the new permissions system introduced in the API level 23, the user needs to approve it. This can be achieved by adding the following code to the Activity file in the onCreate() method. OVERLAY_PERMISSION_REQ_CODE is a field of the class which would be responsible for passing the result back to the Activity.
Finally, the onActivityResult() method (as shown in the code below) has to be overridden to handle the permission Accepted or Denied cases for consistent UX.
ReactRootView #You need to add some native code in order to start the React Native runtime and get it to render something. To do this, we're going to create an Activity that creates a ReactRootView, starts a React application inside it and sets it as the main content view.
If you are targetting Android version <5, use the
AppCompatActivityclass from thecom.android.support:appcompatpackage instead ofActivity.
If you are using a starter kit for React Native, replace the "HelloWorld" string with the one in your index.js file (it’s the first argument to the
AppRegistry.registerComponent()method).
If you are using Android Studio, use Alt + Enter to add all missing imports in your MyReactActivity class. Be careful to use your package’s BuildConfig and not the one from the ...facebook... package.
We need set the theme of MyReactActivity to Theme.AppCompat.Light.NoActionBar because some components rely on this theme.
A
ReactInstanceManagercan be shared amongst multiple activities and/or fragments. You will want to make your ownReactFragmentorReactActivityand have a singleton holder that holds aReactInstanceManager. When you need theReactInstanceManager(e.g., to hook up theReactInstanceManagerto the lifecycle of those Activities or Fragments) use the one provided by the singleton.
Next, we need to pass some activity lifecycle callbacks down to the ReactInstanceManager:
We also need to pass back button events to React Native:
This allows JavaScript to control what happens when the user presses the hardware back button (e.g. to implement navigation). When JavaScript doesn't handle a back press, your invokeDefaultOnBackPressed method will be called. By default this simply finishes your Activity.
Finally, we need to hook up the dev menu. By default, this is activated by (rage) shaking the device, but this is not very useful in emulators. So we make it show when you press the hardware menu button (use Ctrl + M if you're using Android Studio emulator):
Now your activity is ready to run some JavaScript code.
You have now done all the basic steps to integrate React Native with your current application. Now we will start the React Native packager to build the index.bundle package and the server running on localhost to serve it.
To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project:
Now build and run your Android app as normal.
Once you reach your React-powered activity inside the app, it should load the JavaScript code from the development server and display:

You can use Android Studio to create your release builds too! It’s as easy as creating release builds of your previously-existing native Android app. There’s just one additional step, which you’ll have to do before every release build. You need to execute the following to create a React Native bundle, which will be included with your native Android app:
Don’t forget to replace the paths with correct ones and create the assets folder if it doesn’t exist.
Now just create a release build of your native app from within Android Studio as usual and you should be good to go!
At this point you can continue developing your app as usual. Refer to our debugging and deployment docs to learn more about working with React Native.
+Improve this page by sending a pull request!
InteractionManager allows long-running work to be scheduled after any +interactions/animations have completed. In particular, this allows JavaScript +animations to run smoothly.
Applications can schedule tasks to run after interactions with the following:
Compare this to other scheduling alternatives:
The touch handling system considers one or more active touches to be an
+'interaction' and will delay runAfterInteractions() callbacks until all
+touches have ended or been cancelled.
InteractionManager also allows applications to register animations by +creating an interaction 'handle' on animation start, and clearing it upon +completion:
runAfterInteractions takes either a plain callback function, or a
+PromiseTask object with a gen method that returns a Promise. If a
+PromiseTask is supplied, then it is fully resolved (including asynchronous
+dependencies that also schedule more tasks via runAfterInteractions) before
+starting on the next task that might have been queued up synchronously
+earlier.
By default, queued tasks are executed together in a loop in one
+setImmediate batch. If setDeadline is called with a positive number, then
+tasks will only be executed until the deadline (in terms of js event loop run
+time) approaches, at which point execution will yield via setTimeout,
+allowing events such as touches to start interactions and block queued tasks
+from executing, making apps more responsive.
Schedule a function to run after all interactions have completed. Returns a cancellable +"promise".
Notify manager that an interaction has started.
Notify manager that an interaction has completed.
A positive number will use setTimeout to schedule any tasks after the +eventLoopRunningTime hits the deadline value, otherwise all tasks will be +executed in one setImmediate batch (default).
Improve this page by sending a pull request!
When using React Native, you're going to be running your JavaScript code in two environments:
While both environments are very similar, you may end up hitting some inconsistencies. We're likely going to experiment with other JS engines in the future, so it's best to avoid relying on specifics of any runtime.
Syntax transformers make writing code more enjoyable by allowing you to use new JavaScript syntax without having to wait for support on all interpreters.
As of version 0.5.0, React Native ships with the Babel JavaScript compiler. Check Babel documentation on its supported transformations for more details.
Here's a full list of React Native's enabled transformations.
ES5
promise.catch(function() { });ES6
<C onPress={() => this.setState({pressed: true})}let greeting = 'hi';Math.max(...array);class C extends React.Component { render() { return <View />; } }const answer = 42;var {isActive, style} = this.props;for (var num of [1, 2, 3]) {}import React, { Component } from 'react';var key = 'abc'; var obj = {[key]: 10};var obj = { method() { return 10; } };var name = 'vjeux'; var obj = { name };function(type, ...args) { }var who = 'world'; var str = `Hello ${who}`;ES7
var extended = { ...obj, a: 10 };function f(a, b, c,) { }async function doStuffAsync() { const foo = await doOtherStuffAsync(); };Specific
Many standards functions are also available on all the supported JavaScript runtimes.
Browser
ES6
ES7
Specific
__DEV__Improve this page by sending a pull request!
Keyboard module to control keyboard events.
The Keyboard module allows you to listen for native events and react to them, as +well as make changes to the keyboard, like dismissing it.
The addListener function connects a JavaScript function to an identified native
+keyboard notification event.
This function then returns the reference to the listener.
@param {string} eventName The nativeEvent is the string that identifies the event you're listening for. This
+can be any of the following:
keyboardWillShowkeyboardDidShowkeyboardWillHidekeyboardDidHidekeyboardWillChangeFramekeyboardDidChangeFrameNote that if you set android:windowSoftInputMode to adjustResize or adjustNothing,
+only keyboardDidShow and keyboardDidHide events will be available on Android.
+keyboardWillShow as well as keyboardWillHide are generally not available on Android
+since there is no native corresponding event.
@param {function} callback function to be called when the event fires.
Removes a specific listener.
@param {string} eventName The nativeEvent is the string that identifies the event you're listening for.
+@param {function} callback function to be called when the event fires.
Removes all listeners for a specific event type.
@param {string} eventType The native event string listeners are watching which will be removed.
Dismisses the active keyboard and removes focus.
Improve this page by sending a pull request!
It is a component to solve the common problem of views that need to move out of the way of the virtual keyboard. +It can automatically adjust either its position or bottom padding based on the position of the keyboard.
The style of the content container(View) when behavior is 'position'.
This is the distance between the top of the user screen and the react native view, +may be non-zero in some use cases.
Improve this page by sending a pull request!
alignContent controls how rows align in the cross direction,
+ overriding the alignContent of the parent.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/align-content
+ for more details.
alignItems aligns children in the cross direction.
+ For example, if children are flowing vertically, alignItems
+ controls how they align horizontally.
+ It works like align-items in CSS (default: stretch).
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
+ for more details.
alignSelf controls how a child aligns in the cross direction,
+ overriding the alignItems of the parent. It works like align-self
+ in CSS (default: auto).
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/align-self
+ for more details.
Aspect ratio control the size of the undefined dimension of a node. Aspect ratio is a +non-standard property only available in react native and not CSS.
borderBottomWidth works like border-bottom-width in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-width
+for more details.
borderLeftWidth works like border-left-width in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/border-left-width
+for more details.
borderRightWidth works like border-right-width in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/border-right-width
+for more details.
borderTopWidth works like border-top-width in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/border-top-width
+for more details.
borderWidth works like border-width in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/border-width
+for more details.
bottom is the number of logical pixels to offset the bottom edge of
+ this component.
It works similarly to bottom in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/bottom
+ for more details of how bottom affects layout.
display sets the display type of this component.
It works similarly to display in CSS, but only support 'flex' and 'none'.
+ 'flex' is the default.
In React Native flex does not work the same way that it does in CSS.
+ flex is a number rather than a string, and it works
+ according to the Yoga library
+ at https://github.com/facebook/yoga
When flex is a positive number, it makes the component flexible
+ and it will be sized proportional to its flex value. So a
+ component with flex set to 2 will take twice the space as a
+ component with flex set to 1.
When flex is 0, the component is sized according to width
+ and height and it is inflexible.
When flex is -1, the component is normally sized according
+ width and height. However, if there's not enough space,
+ the component will shrink to its minWidth and minHeight.
flexGrow, flexShrink, and flexBasis work the same as in CSS.
flexDirection controls which directions children of a container go.
+ row goes left to right, column goes top to bottom, and you may
+ be able to guess what the other two do. It works like flex-direction
+ in CSS, except the default is column.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction
+ for more details.
flexWrap controls whether children can wrap around after they
+ hit the end of a flex container.
+ It works like flex-wrap in CSS (default: nowrap).
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap
+ for more details.
height sets the height of this component.
It works similarly to height in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/height for more details.
justifyContent aligns children in the main direction.
+ For example, if children are flowing vertically, justifyContent
+ controls how they align vertically.
+ It works like justify-content in CSS (default: flex-start).
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
+ for more details.
left is the number of logical pixels to offset the left edge of
+ this component.
It works similarly to left in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/left
+ for more details of how left affects layout.
Setting margin has the same effect as setting each of
+ marginTop, marginLeft, marginBottom, and marginRight.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/margin
+ for more details.
marginBottom works like margin-bottom in CSS.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-bottom
+ for more details.
Setting marginHorizontal has the same effect as setting
+ both marginLeft and marginRight.
marginLeft works like margin-left in CSS.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-left
+ for more details.
marginRight works like margin-right in CSS.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-right
+ for more details.
marginTop works like margin-top in CSS.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-top
+ for more details.
Setting marginVertical has the same effect as setting both
+ marginTop and marginBottom.
maxHeight is the maximum height for this component, in logical pixels.
It works similarly to max-height in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/max-height + for more details.
maxWidth is the maximum width for this component, in logical pixels.
It works similarly to max-width in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/max-width + for more details.
minHeight is the minimum height for this component, in logical pixels.
It works similarly to min-height in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/min-height + for more details.
minWidth is the minimum width for this component, in logical pixels.
It works similarly to min-width in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/min-width + for more details.
overflow controls how children are measured and displayed.
+ overflow: hidden causes views to be clipped while overflow: scroll
+ causes views to be measured independently of their parents main axis.
+ It works like overflow in CSS (default: visible).
+ See https://developer.mozilla.org/en/docs/Web/CSS/overflow
+ for more details.
+ overflow: visible only works on iOS. On Android, all views will clip
+ their children.
Setting padding has the same effect as setting each of
+ paddingTop, paddingBottom, paddingLeft, and paddingRight.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/padding
+ for more details.
paddingBottom works like padding-bottom in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-bottom
+for more details.
Setting paddingHorizontal is like setting both of
+ paddingLeft and paddingRight.
paddingLeft works like padding-left in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-left
+for more details.
paddingRight works like padding-right in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-right
+for more details.
paddingTop works like padding-top in CSS.
+See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-top
+for more details.
Setting paddingVertical is like setting both of
+ paddingTop and paddingBottom.
position in React Native is similar to regular CSS, but
+ everything is set to relative by default, so absolute
+ positioning is always just relative to the parent.
If you want to position a child using specific numbers of logical
+ pixels relative to its parent, set the child to have absolute
+ position.
If you want to position a child relative to something + that is not its parent, just don't use styles for that. Use the + component tree.
See https://github.com/facebook/yoga
+ for more details on how position differs between React Native
+ and CSS.
right is the number of logical pixels to offset the right edge of
+ this component.
It works similarly to right in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/right
+ for more details of how right affects layout.
top is the number of logical pixels to offset the top edge of
+ this component.
It works similarly to top in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/top
+ for more details of how top affects layout.
width sets the width of this component.
It works similarly to width in CSS, but in React Native you
+ must use points or percentages. Ems and other units are not supported.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/width for more details.
zIndex controls which components display on top of others.
+ Normally, you don't use zIndex. Components render according to
+ their order in the document tree, so later components draw over
+ earlier ones. zIndex may be useful if you have animations or custom
+ modal interfaces where you don't want this behavior.
It works like the CSS z-index property - components with a larger
+ zIndex will render on top. Think of the z-direction like it's
+ pointing from the phone into your eyeball.
+ See https://developer.mozilla.org/en-US/docs/Web/CSS/z-index for
+ more details.
direction specifies the directional flow of the user interface.
+ The default is inherit, except for root node which will have
+ value based on the current locale.
+ See https://facebook.github.io/yoga/docs/rtl/
+ for more details.
Improve this page by sending a pull request!
Automatically animates views to their new positions when the +next layout happens.
A common way to use this API is to call it before calling setState.
Note that in order to get this to work on Android you need to set the following flags via UIManager:
Schedules an animation to happen on the next layout.
@param config Specifies animation properties:
duration in millisecondscreate, config for animating in new views (see Anim type)update, config for animating views that have been updated
+(see Anim type)@param onAnimationDidEnd Called when the animation finished. +Only supported on iOS. +@param onError Called on error. Only supported on iOS.
Helper for creating a config for configureNext.
Improve this page by sending a pull request!
Not every app uses all the native capabilities, and including the code to support +all those features would impact the binary size... But we still want to make it +easy to add these features whenever you need them.
With that in mind we exposed many of these features as independent static libraries.
For most of the libs it will be as simple as dragging two files, sometimes a third +step will be necessary, but no more than that.
All the libraries we ship with React Native live on the Libraries folder in
+the root of the repository. Some of them are pure JavaScript, and you only need
+to require it. Other libraries also rely on some native code, in that case
+you'll have to add these files to your app, otherwise the app will throw an
+error as soon as you try to use the library.
Install a library with native dependencies:
Note: --save or --save-dev flag is very important for this step. React Native will link
+your libs based on dependencies and devDependencies in your package.json file.
Link your native dependencies:
Done! All libraries with native dependencies should be successfully linked to your iOS/Android project.
If the library has native code, there must be a .xcodeproj file inside it's
+folder.
+Drag this file to your project on Xcode (usually under the Libraries group
+on Xcode);

Click on your main project file (the one that represents the .xcodeproj)
+select Build Phases and drag the static library from the Products folder
+inside the Library you are importing to Link Binary With Libraries

Not every library will need this step, what you need to consider is:
Do I need to know the contents of the library at compile time?
What that means is, are you using this library on the native side or only in +JavaScript? If you are only using it in JavaScript, you are good to go!
This step is not necessary for libraries that we ship with React Native with the
+exception of PushNotificationIOS and Linking.
In the case of the PushNotificationIOS for example, you have to call a method
+on the library from your AppDelegate every time a new push notification is
+received.
For that we need to know the library's headers. To achieve that you have to go
+to your project's file, select Build Settings and search for Header Search
+Paths. There you should include the path to your library (if it has relevant
+files on subdirectories remember to make it recursive, like React on the
+example).

Improve this page by sending a pull request!
Linking gives you a general interface to interact with both incoming
+and outgoing app links.
If your app was launched from an external url registered to your app you can +access and handle it from any component you want with
NOTE: For instructions on how to add support for deep linking on Android, +refer to Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links.
If you wish to receive the intent in an existing instance of MainActivity,
+you may set the launchMode of MainActivity to singleTask in
+AndroidManifest.xml. See <activity>
+documentation for more information.
NOTE: On iOS, you'll need to link RCTLinking to your project by following
+the steps described here.
+If you also want to listen to incoming app links during your app's
+execution, you'll need to add the following lines to your *AppDelegate.m:
If you're targeting iOS 8.x or older, you can use the following code instead:
// If your app is using Universal Links, +you'll need to add the following code as well:
And then on your React component you'll be able to listen to the events on
+Linking as follows
To start the corresponding activity for a link (web URL, email, contact etc.), call
If you want to check if any installed app can handle a given URL beforehand you can call
Add a handler to Linking changes by listening to the url event type
+and providing the handler
Remove a handler by passing the url event type and the handler
Try to open the given url with any of the installed apps.
You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386" on Android +or "http://maps.apple.com/?ll=37.484847,-122.148386" on iOS), a contact, +or any other URL that can be opened with the installed apps.
The method returns a Promise object. If the user confirms the open dialog or the
+url automatically opens, the promise is resolved. If the user cancels the open dialog
+or there are no registered applications for the url, the promise is rejected.
NOTE: This method will fail if the system doesn't know how to open the specified URL. +If you're passing in a non-http(s) URL, it's best to check {@code canOpenURL} first.
NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly!
Determine whether or not an installed app can handle a given URL.
NOTE: For web URLs, the protocol ("http://", "https://") must be set accordingly!
NOTE: As of iOS 9, your app needs to provide the LSApplicationQueriesSchemes key
+inside Info.plist or canOpenURL will always return false.
@param URL the URL to open
If the app launch was triggered by an app link,
+it will give the link url, otherwise it will give null
NOTE: To support deep linking on Android, refer http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents
Improve this page by sending a pull request!
DEPRECATED - use one of the new list components, such as FlatList
+or SectionList for bounded memory use, fewer bugs,
+better performance, an easier to use API, and more features. Check out this
+blog post
+for more details.
ListView - A core component designed for efficient display of vertically
+scrolling lists of changing data. The minimal API is to create a
+ListView.DataSource, populate it with a simple
+array of data blobs, and instantiate a ListView component with that data
+source and a renderRow callback which takes a blob from the data array and
+returns a renderable component.
Minimal example:
ListView also supports more advanced features, including sections with sticky
+section headers, header and footer support, callbacks on reaching the end of
+the available data (onEndReached) and on the set of rows that are visible
+in the device viewport change (onChangeVisibleRows), and several
+performance optimizations.
There are a few performance operations designed to make ListView scroll +smoothly while dynamically loading potentially very large (or conceptually +infinite) data sets:
Only re-render changed rows - the rowHasChanged function provided to the +data source tells the ListView if it needs to re-render a row because the +source data has changed - see ListViewDataSource for more details.
Rate-limited row rendering - By default, only one row is rendered per
+event-loop (customizable with the pageSize prop). This breaks up the
+work into smaller chunks to reduce the chance of dropping frames while
+rendering rows.
An instance of ListView.DataSource to use
Flag indicating whether empty section headers should be rendered. In the future release +empty section headers will be rendered by default, and the flag will be deprecated. +If empty sections are not desired to be rendered their indices should be excluded from sectionID object.
How many rows to render on initial component mount. Use this to make +it so that the first screen worth of data appears at one time instead of +over the course of multiple frames.
(visibleRows, changedRows) => void
Called when the set of visible rows changes. visibleRows maps
+{ sectionID: { rowID: true }} for all the visible rows, and
+changedRows maps { sectionID: { rowID: true | false }} for the rows
+that have changed their visibility, with true indicating visible, and
+false indicating the view has moved out of view.
Called when all rows have been rendered and the list has been scrolled +to within onEndReachedThreshold of the bottom. The native scroll +event is provided.
Threshold in pixels (virtual, not physical) for calling onEndReached.
Number of rows to render per event loop. Note: if your 'rows' are actually +cells, i.e. they don't span the full width of your view (as in the +ListViewGridLayoutExample), you should set the pageSize to be a multiple +of the number of cells per row, otherwise you're likely to see gaps at +the edge of the ListView as new pages are loaded.
A performance optimization for improving scroll perf of +large lists, used in conjunction with overflow: 'hidden' on the row +containers. This is enabled by default.
() => renderable
The header and footer are always rendered (if these props are provided) +on every render pass. If they are expensive to re-render, wrap them +in StaticContainer or other mechanism as appropriate. Footer is always +at the bottom of the list, and header at the top, on every render pass. +In a horizontal ListView, the header is rendered on the left and the +footer on the right.
(rowData, sectionID, rowID, highlightRow) => renderable
Takes a data entry from the data source and its ids and should return
+a renderable component to be rendered as the row. By default the data
+is exactly what was put into the data source, but it's also possible to
+provide custom extractors. ListView can be notified when a row is
+being highlighted by calling highlightRow(sectionID, rowID). This
+sets a boolean value of adjacentRowHighlighted in renderSeparator, allowing you
+to control the separators above and below the highlighted row. The highlighted
+state of a row can be reset by calling highlightRow(null).
(props) => renderable
A function that returns the scrollable component in which the list rows +are rendered. Defaults to returning a ScrollView with the given props.
(sectionData, sectionID) => renderable
If provided, a header is rendered for this section.
(sectionID, rowID, adjacentRowHighlighted) => renderable
If provided, a renderable component to be rendered as the separator +below each row but not the last row if there is a section header below. +Take a sectionID and rowID of the row above and whether its adjacent row +is highlighted.
How early to start rendering rows before they come on screen, in +pixels.
An array of child indices determining which children get docked to the
+top of the screen when scrolling. For example, passing
+stickyHeaderIndices={[0]} will cause the first child to be fixed to the
+top of the scroll view. This property is not supported in conjunction
+with horizontal={true}.
Makes the sections headers sticky. The sticky behavior means that it
+will scroll with the content at the top of the section until it reaches
+the top of the screen, at which point it will stick to the top until it
+is pushed off the screen by the next section header. This property is
+not supported in conjunction with horizontal={true}. Only enabled by
+default on iOS because of typical platform standards.
Exports some data, e.g. for perf investigations or analytics.
Scrolls to a given x, y offset, either immediately or with a smooth animation.
See ScrollView#scrollTo.
If this is a vertical ListView scrolls to the bottom. +If this is a horizontal ListView scrolls to the right.
Use scrollToEnd({animated: true}) for smooth animated scrolling,
+scrollToEnd({animated: false}) for immediate scrolling.
+If no options are passed, animated defaults to true.
See ScrollView#scrollToEnd.
Displays the scroll indicators momentarily.
Improve this page by sending a pull request!
Provides efficient data processing and access to the
+ListView component. A ListViewDataSource is created with functions for
+extracting data from the input blob, and comparing elements (with default
+implementations for convenience). The input blob can be as simple as an
+array of strings, or an object with rows nested inside section objects.
To update the data in the datasource, use cloneWithRows (or
+cloneWithRowsAndSections if you care about sections). The data in the
+data source is immutable, so you can't modify it directly. The clone methods
+suck in the new data and compute a diff for each row so ListView knows
+whether to re-render it or not.
In this example, a component receives data in chunks, handled by
+_onDataArrived, which concats the new data onto the old data and updates the
+data source. We use concat to create a new array - mutating this._data,
+e.g. with this._data.push(newRowData), would be an error. _rowHasChanged
+understands the shape of the row data and knows how to efficiently compare
+it.
You can provide custom extraction and hasChanged functions for section
+headers and rows. If absent, data will be extracted with the
+defaultGetRowData and defaultGetSectionHeaderData functions.
The default extractor expects data of one of the following forms:
or
or
The constructor takes in a params argument that can contain any of the +following:
Clones this ListViewDataSource with the specified dataBlob and
+rowIdentities. The dataBlob is just an arbitrary blob of data. At
+construction an extractor to get the interesting information was defined
+(or the default was used).
The rowIdentities is a 2D array of identifiers for rows.
+ie. [['a1', 'a2'], ['b1', 'b2', 'b3'], ...]. If not provided, it's
+assumed that the keys of the section data are the row identities.
Note: This function does NOT clone the data in this data source. It simply
+passes the functions defined at construction to a new data source with
+the data specified. If you wish to maintain the existing data you must
+handle merging of old and new data separately and then pass that into
+this function as the dataBlob.
This performs the same function as the cloneWithRows function but here
+you also specify what your sectionIdentities are. If you don't care
+about sections you should safely be able to use cloneWithRows.
sectionIdentities is an array of identifiers for sections.
+ie. ['s1', 's2', ...]. The identifiers should correspond to the keys or array indexes
+of the data you wish to include. If not provided, it's assumed that the
+keys of dataBlob are the section identities.
Note: this returns a new object!
Returns the total number of rows in the data source.
If you are specifying the rowIdentities or sectionIdentities, then getRowCount will return the number of rows in the filtered data source.
Returns the total number of rows in the data source (see getRowCount for how this is calculated) plus the number of sections in the data.
If you are specifying the rowIdentities or sectionIdentities, then getRowAndSectionCount will return the number of rows & sections in the filtered data source.
Returns if the row is dirtied and needs to be rerendered
Gets the data required to render the row.
Gets the rowID at index provided if the dataSource arrays were flattened, +or null of out of range indexes.
Gets the sectionID at index provided if the dataSource arrays were flattened, +or null for out of range indexes.
Returns an array containing the number of rows in each section
Returns if the section header is dirtied and needs to be rerendered
Gets the data required to render the section header
Improve this page by sending a pull request!
So you have read through the contributor's guide and you're getting ready to send your first pull request. Perhaps you've found an issue in React Native and want to work with the maintainers to land a fix. Here's what you can expect to happen when you open an issue or send a pull request.
The following is adapted from the excellent Open Source Guide from GitHub and reflects how the maintainers of React Native are encouraged to handle your contributions.
We see dozens of new issues being created every day. In order to help maintainers focus on what is actionable, maintainers ask contributors to do a bit of work prior to opening a new issue:
Issues that do not meet the above criteria can be closed immediately, with a link to the contributor's guide.
You have gathered all the information required to open a new issue, and you are confident it meets the contributor guidelines. Once you post an issue, this is what our maintainers will consider when deciding how to move forward:
Is this issue a feature request?
Some features may not be a good fit for the core React Native library. This is usually the case for *new modules that Facebook does not use in production. In this case, a maintainer will explain that this should be released to npm as a separate module, allowing users to easily pull in the module in their projects.
Even if the feature does belong in the core library, adding it means maintaining it. A maintainer will encourage you to submit a pull request or otherwise post your request to Canny by issuing the @facebook-github-bot feature command, closing the issue.
An exception can be made for proposals and long-running discussions, though these should be rare. If you have been contributing to the project long enough, you will probably already have access to the React Native Core Contributors Facebook Group, where this sort of discussion is usually held.
Is this issue a request for help?
Questions should absolutely be asked on Stack Overflow rather than GitHub. Maintainers may encourage you to ask on Stack Overflow by issuing the @facebook-github-bot stack-overflow command, closing the issue.
+Feel free to also answer some questions on Stack Overflow, you'll get rep!
Was the Issue Template used to fill out the issue? Did the author answer Yes to both questions at the top?
If not, the maintainer will ask you to provide more information by issuing the @facebook-github-bot no-template command, closing the issue.
Is the issue a duplicate of an existing, open issue?
A maintainer will use the @facebook-github-bot duplicate #123 command to mark the issue as a duplicate of issue #123, closing it.
Does the issue include a Snack or list of steps to reproduce the issue?
Issues should be relatively easy to reproduce. Sometimes the issue affects a particular app but a minimal repro is not provided, perhaps a crash is seen in the logs and the author is not sure where its coming from, maybe the issue is sporadic.
As it happens, if a maintainer cannot easily reproduce the issue, one cannot reasonably expect them to be able to work on a fix. These issues can be closed by issuing the @facebook-github-bot needs-repro command.
Exceptions can be made if multiple people appear to be affected by the issue, especially right after a new React Native release is cut.
Is the issue for an old release of React Native?
If so, expect to be asked if the issue can be reproduced in the latest release candidate.
Can the issue be reliably reproduced?
If not, a maintainer may issue the @facebook-github-bot cannot-repro command, closing the issue.
Does the issue need more information?
Some issues need additional information in order to reproduce them. Maintainers should explain what additional information is needed, using the @facebook-github-bot label Needs more information command to label the issue as such.
Issues with the 'Needs more information' label that have been open for more than a week without a response from the author can be closed using @facebook-github-bot no-reply.
Has the issue been resolved already in the comments?
Sometimes another contributor has already provided a solution in the comments. Maintainers may issue the @facebook-github-bot answered command to close the issue.
Reopening a closed issue: Sometimes it's necessary to reopen an issue. For example, if an issue was closed waiting for the author, then the author replied and it turns out this is indeed a bug, you can comment
@facebook-github-bot reopento reopen it.
Valid bug reports with good repro steps are some of the best issues! Maintainers should thank the author for finding the issue, then explain that React Native is a community project and ask them if they would be up for sending a fix.
If a issue is still open after going through all of the checks above, it will move on to the triage stage. A maintainer will then do the following:
@facebook-github-bot label Android command.You can generally figure out who may be relevant for a given issue by looking at the CODEOWNERS file.
You can find the full command reference in the Facebook GitHub Bot section below.
Issues in the "Needs more information" state may be closed after a week with no followup from the author. Issues that have have had no activity in the last two months may be closed periodically. If your issue gets closed in this manner, it's nothing personal. If you strongly believe that the issue should remain open, just let us know why.
Simply commenting that the issue still exists is not very compelling (it's rare for critical, release blocking issues to have no activity for two months!). In order to make a good case for reopening the issue, you may need to do a bit of work:
A couple of contributors making a good case may be all that is needed to reopen the issue.
The core team will be monitoring for pull requests. When we get one, we'll run some Facebook-specific integration tests on it first. From here, we'll need to get another person to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
We use the Contributors Chrome extension to help us understand who is sending a pull request. Pull requests opened by contributors that have a history of having their PRs merged are more likely to be looked at first. Aside from that, we try to go through pull requests on a chronological order.
Reviewing a PR can sometimes require more time from a maintainer than it took you to write the code. Maintainers need to consider all the ramifications of importing your patch into the codebase. Does it potentially introduce breaking changes? What are the performance considerations of adding a new dependency? Will the docs need to be updated as well? Does this belong in core, or would it be a better fit as a third party package?
Once you open a pull request, this is how you can expect maintainers to review it:
Is the pull request missing information?
A test plan is required! Add the labels 'Needs revision' and 'Needs response from author'. You can then follow up with a response like:
Hey @author, thanks for sending the pull request. +Can you please add all the info specified in the template? This is necessary for people to be able to understand and review your pull request.
Does the code style match the Style guide?
If not, link to the style guide and add the label 'Needs revision'.
Does the pull request add a completely new feature we don't want to add to the core and maintain?
Ask the author to release it a separate npm module and close the pull request.
Does the pull request do several unrelated things at the same time?
Ask the author to split it.
Is the pull request old and need rebasing?
Ask the author "Can you rebase please?" and add the label 'Needs response from author'.
Is a pull request waiting for a response from author?
Pull requests like these usually have the label 'Needs response from author'. If there has been no reply in the last 30 days, close it with a response like the following:
Thanks for making the pull request, but we are closing it due to inactivity. If you want to get your proposed changes merged, please rebase your branch with master and send a new pull request.
Is the pull request old and waiting for review?
Review it or cc someone who might be able to review. Finding the right person to review a pull request can sometimes be tricky. A pull request may simultaneously touch iOS, Java, and JavaScript code. If a pull request has been waiting for review for a while, you can help out by looking at the blame history for the files you're touching. Is there anyone that appears to be knowledgeable in the part of the codebase the PR is touching?
Sometimes a maintainer may decide that a pull request will not be accepted. Maybe the pull request is out of scope for the project, or the idea is good but the implementation is poor. Whatever the reason, when closing a pull request maintainers should keep the conversation friendly:
Sometimes when a maintainer says no to a pull request or close an issue, a contributor may get upset and criticize your decision. Maintainers will take steps to defuse the situation.
If a contributor becomes hostile or disrespectful, they will be referred to the Code of Conduct. Negative users will be blocked, and inappropriate comments will be deleted.
The Facebook GitHub Bot allows members of the community to perform administrative actions such as labeling and closing issues. +To have access to the bot, please add your GitHub username to the first line of IssueCommands.txt, in alphabetical order, by submitting a Pull Request.
The bot can be triggered by adding any of the following commands as a standalone comment on an issue:
+ Use this when more information is needed, especially if the issue does not adhere to the issue template. The bot will close the issue after adding the "Needs more information" label. +
+ Mark issues that do not belong in the bug tracker, and redirect to Stack Overflow. The bot will close the issue after adding the "For Stack Overflow" label. +
+ Prompts the author to provide a reproducible example or Snack. The bot will apply the "Needs more information" label. +
+ Use this when the issue cannot be reproduced, either because it affects a particular app but no minimal repro was provided, or the issue describes something sporadic that is unlikely to be reproduced by a community member. The bot will close the issue. +
+ Marks an issue as a duplicate. Requires a issue number to be provided. The bot will close the issue. +
+
+ Example: @facebook-github-bot duplicate #42
+
+ Use this command to add a label, such as "iOS" or "Android", to an issue. +
+ Example: @facebook-github-bot label Android
+
+ Use this when an issue describes a feature request, as opposed to a reproducible bug. The bot will point the author to the feature request tracker, add the "Feature Request" label, then close the issue. +
+ Use this when an issue describes a type of expected behavior. The bot will close the issue. +
+ Use this when an issue appears to be a question that has already been answered by someone on the thread. The bot will close the issue. +
+ Closes an issue without providing a particular explanation. +
+ Re-opens a previously closed issue. +
+ Mark issues that describe a reproducible bug and encourage the author to send a pull request. The bot will add the "Help Wanted" label. +
+ Use this when an issue requires more information from the author but they have not added a comment in a while. The bot will close the issue. +
+ Use this when an issue has been open for over 30 days with no activity and no community member has volunteered to work on a fix. The bot will close the issue after adding the "Icebox" label. +
Additionally, the following commands can be used on a pull request:
+ Remind the author that the CLA needs to be signed. +
+ Flag the PR for merging. If used by a core contributor, the bot will attempt to import the pull request. In general, core contributors are those who have consistently submitted high quality contributions to the project. Access control for this command is configured internally in Facebook, outside of the IssueCommands.txt file mentioned above. +
+ Flag PRs that change too many files at once. These PRs are extremely unlikely to be reviewed. The bot will leave a helpful message indicating next steps such as splitting the PR. The bot will close the PR after adding the "Large PR" label. +
Improve this page by sending a pull request!
Renders the child view with a mask specified in the maskElement prop.
The above example will render a view with a blue background that fills its +parent, and then mask that view with text that says "Basic Mask".
The alpha channel of the view rendered by the maskElement prop determines how
+much of the view's content and background shows through. Fully or partially
+opaque pixels allow the underlying content to show through but fully
+transparent pixels block that content.
Improve this page by sending a pull request!
The Modal component is a simple way to present content above an enclosing view.
Note: If you need more control over how to present modals over the rest of your app, +then consider using a top-level Navigator.
DeprecatedUse the animationType prop instead.
The animationType prop controls how the modal animates.
slide slides in from the bottomfade fades into viewnone appears without an animationDefault is set to none.
The onRequestClose callback is called when the user taps the hardware back button on Android or the menu button on Apple TV.
The onShow prop allows passing a function that will be called once the modal has been shown.
The transparent prop determines whether your modal will fill the entire view. Setting this to true will render the modal over a transparent background.
The visible prop determines whether your modal is visible.
The hardwareAccelerated prop controls whether to force hardware acceleration for the underlying window.
The onOrientationChange callback is called when the orientation changes while the modal is being displayed.
+The orientation provided is only 'portrait' or 'landscape'. This callback is also called on initial render, regardless of the current orientation.
The presentationStyle prop controls how the modal appears (generally on larger devices such as iPad or plus-sized iPhones).
+See https://developer.apple.com/reference/uikit/uimodalpresentationstyle for details.
fullScreen covers the screen completelypageSheet covers portrait-width view centered (only on larger devices)formSheet covers narrow-width view centered (only on larger devices)overFullScreen covers the screen completely, but allows transparencyDefault is set to overFullScreen or fullScreen depending on transparent property.
The supportedOrientations prop allows the modal to be rotated to any of the specified orientations.
+On iOS, the modal is still restricted by what's specified in your app's Info.plist's UISupportedInterfaceOrientations field.
+When using presentationStyle of pageSheet or formSheet, this property will be ignored by iOS.
Improve this page by sending a pull request!
If you just read through this website, you should be able to build a pretty cool React Native app. But React Native isn't just a product made by one company - it's a community of thousands of developers. So if you're interested in React Native, here's some related stuff you might want to check out.
If you're using React Native, you probably already know about React. So I feel a bit silly mentioning this. But if you haven't, check out React - it's the best way to build a modern website.
One common question is how to handle the "state" of your React Native application. The most popular library for this is Redux. Don't be afraid of how often Redux uses the word "reducer" - it's a pretty simple library, and there's also a nice series of videos explaining it.
If you're looking for a library that does a specific thing, check out Awesome React Native, a curated list of components that also has demos, articles, and other stuff.
Try out apps from the Showcase to see what React Native is capable of! There are also some example apps on GitHub. You can run the apps on a simulator or device, and you can see the source code for these apps, which is neat.
The folks who built the app for Facebook's F8 conference in 2016 also open-sourced the code and wrote up a detailed series of tutorials. This is useful if you want a more in-depth example that's more realistic than most sample apps out there.
Nuclide is the IDE that Facebook uses internally for JavaScript development. The killer feature of Nuclide is its debugging ability. It also has great inline Flow support. VS Code is another IDE that is popular with JavaScript developers.
Ignite is a starter kit that uses Redux and a few different common UI libraries. It has a CLI to generate apps, components, and containers. If you like all of the individual tech choices, Ignite could be perfect for you.
CodePush is a service from Microsoft that makes it easy to deploy live updates to your React Native app. If you don't like going through the app store process to deploy little tweaks, and you also don't like setting up your own backend, give CodePush a try.
Expo is a development environment plus application that focuses on letting you build React Native apps in the Expo development environment, without ever touching Xcode or Android Studio. If you wish React Native was even more JavaScripty and webby, check out Expo.
The React Developer Tools are great for debugging React and React Native apps.
The React Native Community Facebook group has thousands of developers, and it's pretty active. Come there to show off your project, or ask how other people solved similar problems.
Reactiflux is a Discord chat where a lot of React-related discussion happens, including React Native. Discord is just like Slack except it works better for open source projects with a zillion contributors. Check out the #react-native channel.
The React Twitter account covers both React and React Native. Follow the React Native Twitter account and blog to find out what's happening in the world of React Native.
There are a lot of React Native Meetups that happen around the world. Often there is React Native content in React meetups as well.
Sometimes we have React conferences. We posted the videos from React.js Conf 2017 and React.js Conf 2016, and we'll probably have more conferences in the future, too. Stay tuned. You can also find a list of dedicated React Native conferences here.
Improve this page by sending a pull request!
There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like ScrollView and TextInput, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, it's quite easy to wrap up these existing components for seamless integration with your React Native application.
Like the native module guide, this too is a more advanced guide that assumes you are somewhat familiar with Android SDK programming. This guide will show you how to build a native UI component, walking you through the implementation of a subset of the existing ImageViewcomponent available in the core React Native library.
For this example we are going to walk through the implementation requirements to allow the use of ImageViews in JavaScript.
Native views are created and manipulated by extending ViewManager or more commonly SimpleViewManager . A SimpleViewManager is convenient in this case because it applies common properties such as background color, opacity, and Flexbox layout.
These subclasses are essentially singletons - only one instance of each is created by the bridge. They vend native views to the NativeViewHierarchyManager, which delegates back to them to set and update the properties of the views as necessary. The ViewManagers are also typically the delegates for the views, sending events back to JavaScript via the bridge.
Vending a view is simple:
createViewInstance method@ReactProp (or @ReactPropGroup) annotationcreateViewManagers of the applications package.ViewManager subclass #In this example we create view manager class ReactImageManager that extends SimpleViewManager of type ReactImageView. ReactImageView is the type of object managed by the manager, this will be the custom native view. Name returned by getName is used to reference the native view type from JavaScript.
createViewInstance #Views are created in the createViewInstance method, the view should initialize itself in its default state, any properties will be set via a follow up call to updateView.
@ReactProp (or @ReactPropGroup) annotation #Properties that are to be reflected in JavaScript needs to be exposed as setter method annotated with @ReactProp (or @ReactPropGroup). Setter method should take view to be updated (of the current view type) as a first argument and property value as a second argument. Setter should be declared as a void method and should be public. Property type sent to JS is determined automatically based on the type of value argument of the setter. The following type of values are currently supported: boolean, int, float, double, String, Boolean, Integer, ReadableArray, ReadableMap.
Annotation @ReactProp has one obligatory argument name of type String. Name assigned to the @ReactProp annotation linked to the setter method is used to reference the property on JS side.
Except from name, @ReactProp annotation may take following optional arguments: defaultBoolean, defaultInt, defaultFloat. Those arguments should be of the corresponding primitive type (accordingly boolean, int, float) and the value provided will be passed to the setter method in case when the property that the setter is referencing has been removed from the component. Note that "default" values are only provided for primitive types, in case when setter is of some complex type, null will be provided as a default value in case when corresponding property gets removed.
Setter declaration requirements for methods annotated with @ReactPropGroup are different than for @ReactProp, please refer to the @ReactPropGroup annotation class docs for more information about it.
IMPORTANT! in ReactJS updating the property value will result in setter method call. Note that one of the ways we can update component is by removing properties that have been set before. In that case setter method will be called as well to notify view manager that property has changed. In that case "default" value will be provided (for primitive types "default" can value can be specified using defaultBoolean, defaultFloat, etc. arguments of @ReactProp annotation, for complex types setter will be called with value set to null).
ViewManager #The final Java step is to register the ViewManager to the application, this happens in a similar way to Native Modules, via the applications package member function createViewManagers.
The very final step is to create the JavaScript module that defines the interface layer between Java and JavaScript for the users of your new view. Much of the effort is handled by internal React code in Java and JavaScript and all that is left for you is to describe the propTypes.
requireNativeComponent commonly takes two parameters, the first is the name of the native view and the second is an object that describes the component interface. The component interface should declare a friendly name for use in debug messages and must declare the propTypes reflected by the Native View. The propTypes are used for checking the validity of a user's use of the native view. Note that if you need your JavaScript component to do more than just specify a name and propTypes, like do custom event handling, you can wrap the native component in a normal react component. In that case, you want to pass in the wrapper component instead of iface to requireNativeComponent. This is illustrated in the MyCustomView example below.
So now we know how to expose native view components that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning? When a native event occurs the native code should issue an event to the JavaScript representation of the View, and the two views are linked with the value returned from the getId() method.
The event name topChange maps to the onChange callback prop in JavaScript (mappings are in UIManagerModuleConstants.java). This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:
Note the use of nativeOnly above. Sometimes you'll have some special properties that you need to expose for the native component, but don't actually want them as part of the API for the associated React component. For example, Switch has a custom onChange handler for the raw native event, and exposes an onValueChange handler property that is invoked with just the boolean value rather than the raw event (similar to onChangeMessage in the example above). Since you don't want these native only properties to be part of the API, you don't want to put them in propTypes, but if you don't you'll get an error. The solution is simply to call them out via the nativeOnly option.
Improve this page by sending a pull request!
There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like ScrollView and TextInput, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, it's quite easy to wrap up these existing components for seamless integration with your React Native application.
Like the native module guide, this too is a more advanced guide that assumes you are somewhat familiar with iOS programming. This guide will show you how to build a native UI component, walking you through the implementation of a subset of the existing MapView component available in the core React Native library.
Let's say we want to add an interactive Map to our app - might as well use MKMapView, we just need to make it usable from JavaScript.
Native views are created and manipulated by subclasses of RCTViewManager. These subclasses are similar in function to view controllers, but are essentially singletons - only one instance of each is created by the bridge. They expose native views to the RCTUIManager, which delegates back to them to set and update the properties of the views as necessary. The RCTViewManagers are also typically the delegates for the views, sending events back to JavaScript via the bridge.
Exposing a view is simple:
RCTViewManager to create a manager for your component.RCT_EXPORT_MODULE() marker macro.-(UIView *)view method.Note: Do not attempt to set the frame or backgroundColor properties on the UIView instance that you expose through the -view method. React Native will overwrite the values set by your custom class in order to match your JavaScript component's layout props. If you need this granularity of control it might be better to wrap the UIView instance you want to style in another UIView and return the wrapper UIView instead. See Issue 2948 for more context.
In the example above, we prefixed our class name with
RNT. Prefixes are used to avoid name collisions with other frameworks. Apple frameworks use two-letter prefixes, and React Native usesRCTas a prefix. In order to avoid name collisions, we recommend using a three-letter prefix other thanRCTin your own classes.
Then you just need a little bit of JavaScript to make this a usable React component:
Make sure to use RNTMap here. We want to require the manager here, which will expose the view of our manager for use in Javascript.
Note: When rendering, don't forget to stretch the view, otherwise you'll be staring at a blank screen.
This is now a fully-functioning native map view component in JavaScript, complete with pinch-zoom and other native gesture support. We can't really control it from JavaScript yet, though :(
The first thing we can do to make this component more usable is to bridge over some native properties. Let's say we want to be able to disable zooming and specify the visible region. Disabling zoom is a simple boolean, so we add this one line:
Note that we explicitly specify the type as BOOL - React Native uses RCTConvert under the hood to convert all sorts of different data types when talking over the bridge, and bad values will show convenient "RedBox" errors to let you know there is an issue ASAP. When things are straightforward like this, the whole implementation is taken care of for you by this macro.
Now to actually disable zooming, we set the property in JS:
To document the properties (and which values they accept) of our MapView component we'll add a wrapper component and document the interface with React PropTypes:
Now we have a nicely documented wrapper component that is easy to work with. Note that we changed the second argument to requireNativeComponent from null to the new MapView wrapper component. This allows the infrastructure to verify that the propTypes match the native props to reduce the chances of mismatches between the ObjC and JS code.
Next, let's add the more complex region prop. We start by adding the native code:
Ok, this is more complicated than the simple BOOL case we had before. Now we have a MKCoordinateRegion type that needs a conversion function, and we have custom code so that the view will animate when we set the region from JS. Within the function body that we provide, json refers to the raw value that has been passed from JS. There is also a view variable which gives us access to the manager's view instance, and a defaultView that we use to reset the property back to the default value if JS sends us a null sentinel.
You could write any conversion function you want for your view - here is the implementation for MKCoordinateRegion via a category on RCTConvert. It uses an already existing category of ReactNative RCTConvert+CoreLocation:
These conversion functions are designed to safely process any JSON that the JS might throw at them by displaying "RedBox" errors and returning standard initialization values when missing keys or other developer errors are encountered.
To finish up support for the region prop, we need to document it in propTypes (or we'll get an error that the native prop is undocumented), then we can set it just like any other prop:
Here you can see that the shape of the region is explicit in the JS documentation - ideally we could codegen some of this stuff, but that's not happening yet.
Sometimes your native component will have some special properties that you don't want to them to be part of the API for the associated React component. For example, Switch has a custom onChange handler for the raw native event, and exposes an onValueChange handler property that is invoked with just the boolean value rather than the raw event. Since you don't want these native only properties to be part of the API, you don't want to put them in propTypes, but if you don't you'll get an error. The solution is simply to add them to the nativeOnly option, e.g.
So now we have a native map component that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning to change the visible region?
Until now we've just returned a MKMapView instance from our manager's -(UIView *)view method. We can't add new properties to MKMapView so we have to create a new subclass from MKMapView which we use for our View. We can then add a onRegionChange callback on this subclass:
Next, declare an event handler property on RNTMapManager, make it a delegate for all the views it exposes, and forward events to JS by calling the event handler block from the native view.
In the delegate method -mapView:regionDidChangeAnimated: the event handler block is called on the corresponding view with the region data. Calling the onRegionChange event handler block results in calling the same callback prop in JavaScript. This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:
Since all our native react views are subclasses of UIView, most style attributes will work like you would expect out of the box. Some components will want a default style, however, for example UIDatePicker which is a fixed size. This default style is important for the layout algorithm to work as expected, but we also want to be able to override the default style when using the component. DatePickerIOS does this by wrapping the native component in an extra view, which has flexible styling, and using a fixed style (which is generated with constants passed in from native) on the inner native component:
The RCTDatePickerIOSConsts constants are exported from native by grabbing the actual frame of the native component like so:
This guide covered many of the aspects of bridging over custom native components, but there is even more you might need to consider, such as custom hooks for inserting and laying out subviews. If you want to go even deeper, check out the source code of some of the implemented components.
Improve this page by sending a pull request!
Sometimes an app needs access to a platform API that React Native doesn't have a corresponding module for yet. Maybe you want to reuse some existing Java code without having to reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image processing, a database, or any number of advanced extensions.
We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform. This is a more advanced feature and we don't expect it to be part of the usual development process, however it is essential that it exists. If React Native doesn't support a native feature that you need, you should be able to build it yourself.
If you plan to make changes in Java code, we recommend enabling Gradle Daemon to speed up builds.
This guide will use the Toast example. Let's say we would like to be able to create a toast message from JavaScript.
We start by creating a native module. A native module is a Java class that usually extends the ReactContextBaseJavaModule class and implements the functionality required by the JavaScript. Our goal here is to be able to write ToastExample.show('Awesome', ToastExample.SHORT); from JavaScript to display a short toast on the screen.
ReactContextBaseJavaModule requires that a method called getName is implemented. The purpose of this method is to return the string name of the NativeModule which represents this class in JavaScript. So here we will call this ToastExample so that we can access it through React.NativeModules.ToastExample in JavaScript.
An optional method called getConstants returns the constant values exposed to JavaScript. Its implementation is not required but is very useful to key pre-defined values that need to be communicated from JavaScript to Java in sync.
To expose a method to JavaScript a Java method must be annotated using @ReactMethod. The return type of bridge methods is always void. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).
The following argument types are supported for methods annotated with @ReactMethod and they directly map to their JavaScript equivalents
Read more about ReadableMap and ReadableArray
The last step within Java is to register the Module; this happens in the createNativeModules of your apps package. If a module is not registered it will not be available from JavaScript.
The package needs to be provided in the getPackages method of the MainApplication.java file. This file exists under the android folder in your react-native application directory. The path to this file is: android/app/src/main/java/com/your-app-name/MainApplication.java.
To make it simpler to access your new functionality from JavaScript, it is common to wrap the native module in a JavaScript module. This is not necessary but saves the consumers of your library the need to pull it off of NativeModules each time. This JavaScript file also becomes a good location for you to add any JavaScript side functionality.
Now, from your other JavaScript file you can call the method like this:
Native modules also support a special kind of argument - a callback. In most cases it is used to provide the function call result to JavaScript.
This method would be accessed in JavaScript using:
A native module is supposed to invoke its callback only once. It can, however, store the callback and invoke it later.
It is very important to highlight that the callback is not invoked immediately after the native function completes - remember that bridge communication is asynchronous, and this too is tied to the run loop.
Native modules can also fulfill a promise, which can simplify your code, especially when using ES2016's async/await syntax. When the last parameter of a bridged native method is a Promise, its corresponding JS method will return a JS Promise object.
Refactoring the above code to use a promise instead of callbacks looks like this:
The JavaScript counterpart of this method returns a Promise. This means you can use the await keyword within an async function to call it and wait for its result:
Native modules should not have any assumptions about what thread they are being called on, as the current assignment is subject to change in the future. If a blocking call is required, the heavy work should be dispatched to an internally managed worker thread, and any callbacks distributed from there.
Native modules can signal events to JavaScript without being invoked directly. The easiest way to do this is to use the RCTDeviceEventEmitter which can be obtained from the ReactContext as in the code snippet below.
JavaScript modules can then register to receive events by addListenerOn using the Subscribable mixin.
You can also directly use the DeviceEventEmitter module to listen for events.
startActivityForResult #You'll need to listen to onActivityResult if you want to get results from an activity you started with startActivityForResult. To do this, you must extend BaseActivityEventListener or implement ActivityEventListener. The former is preferred as it is more resilient to API changes. Then, you need to register the listener in the module's constructor,
Now you can listen to onActivityResult by implementing the following method:
We will implement a simple image picker to demonstrate this. The image picker will expose the method pickImage to JavaScript, which will return the path of the image when called.
Listening to the activity's LifeCycle events such as onResume, onPause etc. is very similar to how we implemented ActivityEventListener. The module must implement LifecycleEventListener. Then, you need to register a listener in the module's constructor,
Now you can listen to the activity's LifeCycle events by implementing the following methods:
Improve this page by sending a pull request!
Sometimes an app needs access to platform API, and React Native doesn't have a corresponding module yet. Maybe you want to reuse some existing Objective-C, Swift or C++ code without having to reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image processing, a database, or any number of advanced extensions.
We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform. This is a more advanced feature and we don't expect it to be part of the usual development process, however it is essential that it exists. If React Native doesn't support a native feature that you need, you should be able to build it yourself.
This is a more advanced guide that shows how to build a native module. It assumes the reader knows Objective-C or Swift and core libraries (Foundation, UIKit).
This guide will use the iOS Calendar API example. Let's say we would like to be able to access the iOS calendar from JavaScript.
A native module is just an Objective-C class that implements the RCTBridgeModule protocol. If you are wondering, RCT is an abbreviation of ReaCT.
In addition to implementing the RCTBridgeModule protocol, your class must also include the RCT_EXPORT_MODULE() macro. This takes an optional argument that specifies the name that the module will be accessible as in your JavaScript code (more on this later). If you do not specify a name, the JavaScript module name will match the Objective-C class name. If the Objective-C class name begins with RCT, the JavaScript module name will exclude the RCT prefix.
React Native will not expose any methods of CalendarManager to JavaScript unless explicitly told to. This is done using the RCT_EXPORT_METHOD() macro:
Now, from your JavaScript file you can call the method like this:
NOTE: JavaScript method names
The name of the method exported to JavaScript is the native method's name up to the first colon. React Native also defines a macro called
RCT_REMAP_METHOD()to specify the JavaScript method's name. This is useful when multiple native methods are the same up to the first colon and would have conflicting JavaScript names.
The CalendarManager module is instantiated on the Objective-C side using a [CalendarManager new] call. The return type of bridge methods is always void. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).
RCT_EXPORT_METHOD supports all standard JSON object types, such as:
NSString)NSInteger, float, double, CGFloat, NSNumber)BOOL, NSNumber)NSArray) of any types from this listNSDictionary) with string keys and values of any type from this listRCTResponseSenderBlock)But it also works with any type that is supported by the RCTConvert class (see RCTConvert for details). The RCTConvert helper functions all accept a JSON value as input and map it to a native Objective-C type or class.
In our CalendarManager example, we need to pass the event date to the native method. We can't send JavaScript Date objects over the bridge, so we need to convert the date to a string or number. We could write our native function like this:
or like this:
But by using the automatic type conversion feature, we can skip the manual conversion step completely, and just write:
You would then call this from JavaScript by using either:
or
And both values would get converted correctly to the native NSDate. A bad value, like an Array, would generate a helpful "RedBox" error message.
As CalendarManager.addEvent method gets more and more complex, the number of arguments will grow. Some of them might be optional. In this case it's worth considering changing the API a little bit to accept a dictionary of event attributes, like this:
and call it from JavaScript:
NOTE: About array and map
Objective-C doesn't provide any guarantees about the types of values in these structures. Your native module might expect an array of strings, but if JavaScript calls your method with an array containing numbers and strings, you'll get an
NSArraycontaining a mix ofNSNumberandNSString. For arrays,RCTConvertprovides some typed collections you can use in your method declaration, such asNSStringArray, orUIColorArray. For maps, it is the developer's responsibility to check the value types individually by manually callingRCTConverthelper methods.
WARNING
This section is more experimental than others because we don't have a solid set of best practices around callbacks yet.
Native modules also supports a special kind of argument- a callback. In most cases it is used to provide the function call result to JavaScript.
RCTResponseSenderBlock accepts only one argument - an array of parameters to pass to the JavaScript callback. In this case we use Node's convention to make the first parameter an error object (usually null when there is no error) and the rest are the results of the function.
A native module should invoke its callback exactly once. It's okay to store the callback and invoke it later. This pattern is often used to wrap iOS APIs that require delegates - see RCTAlertManager for an example. If the callback is never invoked, some memory is leaked. If both onSuccess and onFail callbacks are passed, you should only invoke one of them.
If you want to pass error-like objects to JavaScript, use RCTMakeError from RCTUtils.h. Right now this just passes an Error-shaped dictionary to JavaScript, but we would like to automatically generate real JavaScript Error objects in the future.
Native modules can also fulfill a promise, which can simplify your code, especially when using ES2016's async/await syntax. When the last parameters of a bridged native method are an RCTPromiseResolveBlock and RCTPromiseRejectBlock, its corresponding JS method will return a JS Promise object.
Refactoring the above code to use a promise instead of callbacks looks like this:
The JavaScript counterpart of this method returns a Promise. This means you can use the await keyword within an async function to call it and wait for its result:
The native module should not have any assumptions about what thread it is being called on. React Native invokes native modules methods on a separate serial GCD queue, but this is an implementation detail and might change. The - (dispatch_queue_t)methodQueue method allows the native module to specify which queue its methods should be run on. For example, if it needs to use a main-thread-only iOS API, it should specify this via:
Similarly, if an operation may take a long time to complete, the native module should not block and can specify it's own queue to run operations on. For example, the RCTAsyncLocalStorage module creates its own queue so the React queue isn't blocked waiting on potentially slow disk access:
The specified methodQueue will be shared by all of the methods in your module. If just one of your methods is long-running (or needs to be run on a different queue than the others for some reason), you can use dispatch_async inside the method to perform that particular method's code on another queue, without affecting the others:
NOTE: Sharing dispatch queues between modules
The
methodQueuemethod will be called once when the module is initialized, and then retained by the bridge, so there is no need to retain the queue yourself, unless you wish to make use of it within your module. However, if you wish to share the same queue between multiple modules then you will need to ensure that you retain and return the same queue instance for each of them; merely returning a queue of the same name for each won't work.
The bridge initializes any registered RCTBridgeModules automatically, however you may wish to instantiate your own module instances (so you may inject dependencies, for example).
You can do this by creating a class that implements the RCTBridgeDelegate Protocol, initializing an RCTBridge with the delegate as an argument and initialising a RCTRootView with the initialized bridge.
A native module can export constants that are immediately available to JavaScript at runtime. This is useful for communicating static data that would otherwise require a round-trip through the bridge.
JavaScript can use this value right away, synchronously:
Note that the constants are exported only at initialization time, so if you change constantsToExport values at runtime it won't affect the JavaScript environment.
Enums that are defined via NS_ENUM cannot be used as method arguments without first extending RCTConvert.
In order to export the following NS_ENUM definition:
You must create a class extension of RCTConvert like so:
You can then define methods and export your enum constants like this:
Your enum will then be automatically unwrapped using the selector provided (integerValue in the above example) before being passed to your exported method.
The native module can signal events to JavaScript without being invoked directly. The preferred way to do this is to subclass RCTEventEmitter, implement supportedEvents and call self sendEventWithName:
JavaScript code can subscribe to these events by creating a new NativeEventEmitter instance around your module.
For more examples of sending events to JavaScript, see RCTLocationObserver.
You will receive a warning if you expend resources unnecessarily by emitting an event while there are no listeners. To avoid this, and to optimize your module's workload (e.g. by unsubscribing from upstream notifications or pausing background tasks), you can override startObserving and stopObserving in your RCTEventEmitter subclass.
Swift doesn't have support for macros so exposing it to React Native requires a bit more setup but works relatively the same.
Let's say we have the same CalendarManager but as a Swift class:
NOTE: It is important to use the @objc modifiers to ensure the class and functions are exported properly to the Objective-C runtime.
Then create a private implementation file that will register the required information with the React Native bridge:
For those of you new to Swift and Objective-C, whenever you mix the two languages in an iOS project, you will also need an additional bridging file, known as a bridging header, to expose the Objective-C files to Swift. Xcode will offer to create this header file for you if you add your Swift file to your app through the Xcode File>New File menu option. You will need to import RCTBridgeModule.h in this header file.
You can also use RCT_EXTERN_REMAP_MODULE and RCT_EXTERN_REMAP_METHOD to alter the JavaScript name of the module or methods you are exporting. For more information see RCTBridgeModule.
Improve this page by sending a pull request!
Mobile apps are rarely made up of a single screen. Managing the presentation of, and transition between, multiple screens is typically handled by what is known as a navigator.
This guide covers the various navigation components available in React Native. +If you are just getting started with navigation, you will probably want to use React Navigation. React Navigation provides an easy to use navigation solution, with the ability to present common stack navigation and tabbed navigation patterns on both iOS and Android. As this is a JavaScript implementation, it provides the greatest amount of configurability as well as flexibility when integrating with state management libraries such as redux.
If you're only targeting iOS, you may want to also check out NavigatorIOS as a way of providing a native look and feel with minimal configuration, as it provides a wrapper around the native UINavigationController class. This component will not work on Android, however.
If you'd like to achieve a native look and feel on both iOS and Android, or you're integrating React Native into an app that already manages navigation natively, the following libraries provide native navigation on both platforms: native-navigation, react-native-navigation.
The community solution to navigation is a standalone library that allows developers to set up the screens of an app with just a few lines of code.
The first step is to install in your project:
Then you can quickly create an app with a home screen and a profile screen:
Each screen component can set navigation options such as the header title. It can use action creators on the navigation prop to link to other screens:
React Navigation routers make it easy to override navigation logic or integrate it into redux. Because routers can be nested inside each other, developers can override navigation logic for one area of the app without making widespread changes.
The views in React Navigation use native components and the Animated library to deliver 60fps animations that are run on the native thread. Plus, the animations and gestures can be easily customized.
For a complete intro to React Navigation, follow the React Navigation Getting Started Guide, or browse other docs such as the Intro to Navigators.
NavigatorIOS looks and feels just like UINavigationController, because it is actually built on top of it.

Like other navigation systems, NavigatorIOS uses routes to represent screens, with some important differences. The actual component that will be rendered can be specified using the component key in the route, and any props that should be passed to this component can be specified in passProps. A "navigator" object is automatically passed as a prop to the component, allowing you to call push and pop as needed.
As NavigatorIOS leverages native UIKit navigation, it will automatically render a navigation bar with a back button and title.
Check out the NavigatorIOS reference docs to learn more about this component.
Improve this page by sending a pull request!
NavigatorIOS is a wrapper around
+UINavigationController,
+enabling you to implement a navigation stack. It works exactly the same as it
+would on a native app using UINavigationController, providing the same
+animations and behavior from UIKit.
As the name implies, it is only available on iOS. Take a look at
+React Navigation for a cross-platform
+solution in JavaScript, or check out either of these components for native
+solutions: native-navigation,
+react-native-navigation.
To set up the navigator, provide the initialRoute prop with a route
+object. A route object is used to describe each scene that your app
+navigates to. initialRoute represents the first route in your navigator.
In this code, the navigator renders the component specified in initialRoute,
+which in this case is MyScene. This component will receive a route prop
+and a navigator prop representing the navigator. The navigator's navigation
+bar will render the title for the current scene, "My Initial Scene".
You can optionally pass in a passProps property to your initialRoute.
+NavigatorIOS passes this in as props to the rendered component:
You can then access the props passed in via {this.props.myProp}.
To trigger navigation functionality such as pushing or popping a view, you
+have access to a navigator object. The object is passed in as a prop to any
+component that is rendered by NavigatorIOS. You can then call the
+relevant methods to perform the navigation action you need:
You can also trigger navigator functionality from the NavigatorIOS
+component:
The code above adds a _handleNavigationRequest private method that is
+invoked from the NavigatorIOS component when the right navigation bar item
+is pressed. To get access to the navigator functionality, a reference to it
+is saved in the ref prop and later referenced to push a new scene into the
+navigation stack.
Props passed to NavigatorIOS will set the default configuration
+for the navigation bar. Props passed as properties to a route object will set
+the configuration for that route's navigation bar, overriding any props
+passed to the NavigatorIOS component.
In the example above the navigation bar color is changed when the new route +is pushed.
The style of the navigation bar. Supported values are 'default', 'black'.
+Use 'black' instead of setting barTintColor to black. This produces
+a navigation bar with the native iOS style with higher translucency.
The default background color of the navigation bar.
NavigatorIOS uses route objects to identify child views, their props,
+and navigation bar configuration. Navigation operations such as push
+operations expect routes to look like this the initialRoute.
Boolean value that indicates whether the interactive pop gesture is +enabled. This is useful for enabling/disabling the back swipe navigation +gesture.
If this prop is not provided, the default behavior is for the back swipe
+gesture to be enabled when the navigation bar is shown and disabled when
+the navigation bar is hidden. Once you've provided the
+interactivePopGestureEnabled prop, you can never restore the default
+behavior.
The default wrapper style for components in the navigator.
+A common use case is to set the backgroundColor for every scene.
Boolean value that indicates whether the navigation bar is hidden +by default.
Boolean value that indicates whether to hide the 1px hairline shadow +by default.
The default color used for the buttons in the navigation bar.
The default text color of the navigation bar title.
Boolean value that indicates whether the navigation bar is +translucent by default
Navigate forward to a new route.
| Name and Type | Description |
|---|---|
| route object | The new route to navigate to. |
Go back N scenes at once. When N=1, behavior matches pop().
| Name and Type | Description |
|---|---|
| n number | The number of scenes to pop. |
Pop back to the previous scene.
Replace a route in the navigation stack.
| Name and Type | Description |
|---|---|
| route object | The new route that will replace the specified one. |
| index number | The route into the stack that should be replaced. + If it is negative, it counts from the back of the stack. |
Replace the route for the current scene and immediately +load the view for the new route.
| Name and Type | Description |
|---|---|
| route object | The new route to navigate to. |
Replace the route/view for the previous scene.
| Name and Type | Description |
|---|---|
| route object | The new route to will replace the previous scene. |
Go back to the topmost item in the navigation stack.
Go back to the item for a particular route object.
| Name and Type | Description |
|---|---|
| route object | The new route to navigate to. |
Replaces the previous route/view and transitions back to it.
| Name and Type | Description |
|---|---|
| route object | The new route that replaces the previous scene. |
Replaces the top item and pop to it.
| Name and Type | Description |
|---|---|
| route object | The new route that will replace the topmost item. |
Improve this page by sending a pull request!
NetInfo exposes info about online/offline status
ConnectionType describes the type of connection the device is using to communicate with the network.
Cross platform values for ConnectionType:
+- none - device is offline
+- wifi - device is online and connected via wifi, or is the iOS simulator
+- cellular - device is connected via Edge, 3G, WiMax, or LTE
+- unknown - error case and the network status is unknown
Android-only values for ConnectionType:
+- bluetooth - device is connected via Bluetooth
+- ethernet - device is connected via Ethernet
+- wimax - device is connected via WiMAX
Cross platform values for EffectiveConnectionType:
+- 2g
+- 3g
+- 4g
+- unknown
To request network info, you need to add the following line to your
+app's AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Available on Android. Detect if the current active connection is metered or not. A network is +classified as metered when the user is sensitive to heavy data usage on that connection due to +monetary costs, data limitations or battery/performance issues.
Available on all platforms. Asynchronously fetch a boolean to determine +internet connectivity.
The following connectivity types are deprecated. They're used by the deprecated APIs fetch and the change event.
iOS connectivity types (deprecated):
+- none - device is offline
+- wifi - device is online and connected via wifi, or is the iOS simulator
+- cell - device is connected via Edge, 3G, WiMax, or LTE
+- unknown - error case and the network status is unknown
Android connectivity types (deprecated).
+- NONE - device is offline
+- BLUETOOTH - The Bluetooth data connection.
+- DUMMY - Dummy data connection.
+- ETHERNET - The Ethernet data connection.
+- MOBILE - The Mobile data connection.
+- MOBILE_DUN - A DUN-specific Mobile data connection.
+- MOBILE_HIPRI - A High Priority Mobile data connection.
+- MOBILE_MMS - An MMS-specific Mobile data connection.
+- MOBILE_SUPL - A SUPL-specific Mobile data connection.
+- VPN - A virtual network using one or more native bearers. Requires API Level 21
+- WIFI - The WIFI data connection.
+- WIMAX - The WiMAX data connection.
+- UNKNOWN - Unknown data connection.
The rest of the connectivity types are hidden by the Android API, but can be used if necessary.
Adds an event handler. Supported events:
connectionChange: Fires when the network status changes. The argument to the event
+handler is an object with keys:type: A ConnectionType (listed above)effectiveType: An EffectiveConnectionType (listed above)change: This event is deprecated. Listen to connectionChange instead. Fires when
+the network status changes. The argument to the event handler is one of the deprecated
+connectivity types listed above.Removes the listener for network status changes.
This function is deprecated. Use getConnectionInfo instead. Returns a promise that
+resolves with one of the deprecated connectivity types listed above.
Returns a promise that resolves to an object with type and effectiveType keys
+whose values are a ConnectionType and an EffectiveConnectionType, (described above),
+respectively.
An object with the same methods as above but the listener receives a +boolean which represents the internet connectivity. +Use this if you are only interested with whether the device has internet +connectivity.
Improve this page by sending a pull request!
Many mobile apps need to load resources from a remote URL. You may want to make a POST request to a REST API, or you may simply need to fetch a chunk of static content from another server.
React Native provides the Fetch API for your networking needs. Fetch will seem familiar if you have used XMLHttpRequest or other networking APIs before. You may refer to MDN's guide on Using Fetch for additional information.
In order to fetch content from an arbitrary URL, just pass the URL to fetch:
Fetch also takes an optional second argument that allows you to customize the HTTP request. You may want to specify additional headers, or make a POST request:
Take a look at the Fetch Request docs for a full list of properties.
The above examples show how you can make a request. In many cases, you will want to do something with the response.
Networking is an inherently asynchronous operation. Fetch methods will return a Promise that makes it straightforward to write code that works in an asynchronous manner:
You can also use the proposed ES2017 async/await syntax in a React Native app:
Don't forget to catch any errors that may be thrown by fetch, otherwise they will be dropped silently.
By default, iOS will block any request that's not encrypted using SSL. If you need to fetch from a cleartext URL (one that begins with
http) you will first need to add an App Transport Security exception. If you know ahead of time what domains you will need access to, it is more secure to add exceptions just for those domains; if the domains are not known until runtime you can disable ATS completely. Note however that from January 2017, Apple's App Store review will require reasonable justification for disabling ATS. See Apple's documentation for more information.
The XMLHttpRequest API is built in to React Native. This means that you can use third party libraries such as frisbee or axios that depend on it, or you can use the XMLHttpRequest API directly if you prefer.
The security model for XMLHttpRequest is different than on web as there is no concept of CORS in native apps.
React Native also supports WebSockets, a protocol which provides full-duplex communication channels over a single TCP connection.
If you've gotten here by reading linearly through the tutorial, then you are a pretty impressive human being. Congratulations. Next, you might want to check out all the cool stuff the community does with React Native.
Improve this page by sending a pull request!
PanResponder reconciles several touches into a single gesture. It makes
+single-touch gestures resilient to extra touches, and can be used to
+recognize simple multi-touch gestures.
By default, PanResponder holds an InteractionManager handle to block
+long-running JS events from interrupting active gestures.
It provides a predictable wrapper of the responder handlers provided by the
+gesture responder system.
+For each handler, it provides a new gestureState object alongside the
+native event object:
A native event is a synthetic touch event with the following form:
nativeEventchangedTouches - Array of all touch events that have changed since the last eventidentifier - The ID of the touchlocationX - The X position of the touch, relative to the elementlocationY - The Y position of the touch, relative to the elementpageX - The X position of the touch, relative to the root elementpageY - The Y position of the touch, relative to the root elementtarget - The node id of the element receiving the touch eventtimestamp - A time identifier for the touch, useful for velocity calculationtouches - Array of all current touches on the screenA gestureState object has the following:
stateID - ID of the gestureState- persisted as long as there at least
+ one touch on screenmoveX - the latest screen coordinates of the recently-moved touchmoveY - the latest screen coordinates of the recently-moved touchx0 - the screen coordinates of the responder granty0 - the screen coordinates of the responder grantdx - accumulated distance of the gesture since the touch starteddy - accumulated distance of the gesture since the touch startedvx - current velocity of the gesturevy - current velocity of the gesturenumberActiveTouches - Number of touches currently on screenTo see it in action, try the +PanResponder example in RNTester
@param {object} config Enhanced versions of all of the responder callbacks
+that provide not only the typical ResponderSyntheticEvent, but also the
+PanResponder gesture state. Simply replace the word Responder with
+PanResponder in each of the typical onResponder* callbacks. For
+example, the config object would look like:
onMoveShouldSetPanResponder: (e, gestureState) => {...}onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}onStartShouldSetPanResponder: (e, gestureState) => {...}onStartShouldSetPanResponderCapture: (e, gestureState) => {...}onPanResponderReject: (e, gestureState) => {...}onPanResponderGrant: (e, gestureState) => {...}onPanResponderStart: (e, gestureState) => {...}onPanResponderEnd: (e, gestureState) => {...}onPanResponderRelease: (e, gestureState) => {...}onPanResponderMove: (e, gestureState) => {...}onPanResponderTerminate: (e, gestureState) => {...}onPanResponderTerminationRequest: (e, gestureState) => {...}onShouldBlockNativeResponder: (e, gestureState) => {...}
In general, for events that have capture equivalents, we update the +gestureState once in the capture phase and can use it in the bubble phase +as well.
Be careful with onStartShould* callbacks. They only reflect updated
+gestureState for start/end events that bubble/capture to the Node.
+Once the node is the responder, you can rely on every start/end event
+being processed by the gesture and gestureState being updated
+accordingly. (numberActiveTouches) may not be totally accurate unless you
+are the responder.
Improve this page by sending a pull request!
A compelling reason for using React Native instead of WebView-based tools is to achieve 60 frames per second and a native look and feel to your apps. +Where possible, we would like for React Native to do the right thing and help you to focus on your app instead of performance optimization, +but there are areas where we're not quite there yet, +and others where React Native (similar to writing native code directly) cannot possibly determine the best way to optimize for you and so manual intervention will be necessary. +We try our best to deliver buttery-smooth UI performance by default, but sometimes that just isn't possible.
This guide is intended to teach you some basics to help you to troubleshoot performance issues, +as well as discuss common sources of problems and their suggested solutions.
Your grandparents' generation called movies "moving pictures" for a reason: +realistic motion in video is an illusion created by quickly changing static images at a consistent speed. We refer to each of these images as frames. +The number of frames that is displayed each second has a direct impact on how smooth and ultimately life-like a video (or user interface) seems to be. +iOS devices display 60 frames per second, which gives you and the UI system about 16.67ms to do all of the work needed to generate the static image (frame) that the user will see on the screen for that interval. +If you are unable to do the work necessary to generate that frame within the allotted 16.67ms, then you will "drop a frame" and the UI will appear unresponsive.
Now to confuse the matter a little bit, open up the developer menu in your app and toggle Show Perf Monitor.
+You will notice that there are two different frame rates.

For most React Native applications, your business logic will run on the JavaScript thread.
+This is where your React application lives, API calls are made, touch events are processed, etc...
+Updates to native-backed views are batched and sent over to the native side at the end of each iteration of the event loop,
+before the frame deadline (if all goes well).
+If the JavaScript thread is unresponsive for a frame, it will be considered a dropped frame.
+For example, if you were to call this.setState on the root component of a complex application and it resulted in re-rendering computationally expensive component subtrees,
+it's conceivable that this might take 200ms and result in 12 frames being dropped.
+Any animations controlled by JavaScript would appear to freeze during that time.
+If anything takes longer than 100ms, the user will feel it.
This often happens during Navigator transitions:
+when you push a new route, the JavaScript thread needs to render all of the components necessary for the scene in order to send over the proper commands to the native side to create the backing views.
+It's common for the work being done here to take a few frames and cause jank because the transition is controlled by the JavaScript thread.
+Sometimes components will do additional work on componentDidMount, which might result in a second stutter in the transition.
Another example is responding to touches:
+if you are doing work across multiple frames on the JavaScript thread, you might notice a delay in responding to TouchableOpacity, for example.
+This is because the JavaScript thread is busy and cannot process the raw touch events sent over from the main thread.
+As a result, TouchableOpacity cannot react to the touch events and command the native view to adjust its opacity.
Many people have noticed that performance of NavigatorIOS is better out of the box than Navigator.
+The reason for this is that the animations for the transitions are done entirely on the main thread,
+and so they are not interrupted by frame drops on the JavaScript thread.
Similarly, you can happily scroll up and down through a ScrollView when the JavaScript thread is locked up because the ScrollView lives on the main thread.
+The scroll events are dispatched to the JS thread, but their receipt is not necessary for the scroll to occur.
dev=true) #JavaScript thread performance suffers greatly when running in dev mode. +This is unavoidable: a lot more work needs to be done at runtime to provide you with good warnings and error messages, such as validating propTypes and various other assertions. Always make sure to test performance in release builds.
console.log statements #When running a bundled app, these statements can cause a big bottleneck in the JavaScript thread.
+This includes calls from debugging libraries such as redux-logger,
+so make sure to remove them before bundling.
+You can also use this babel plugin that removes all the console.* calls. You need to install it first with npm i babel-plugin-transform-remove-console --save, and then edit the .babelrc file under your project directory like this:
This will automatically remove all console.* calls in the release (production) versions of your project.
ListView initial rendering is too slow or scroll performance is bad for large lists #Use the new FlatList or SectionList component instead.
+Besides simplifying the API, the new list components also have significant performance enhancements,
+the main one being nearly constant memory usage for any number of rows.
If your FlatList is rendering slow, be sure that you've implemented
+getItemLayout to
+optimize rendering speed by skipping measurement of the rendered items.
If you are using a ListView, you must provide a rowHasChanged function that can reduce a lot of work by quickly determining whether or not a row needs to be re-rendered. If you are using immutable data structures, this would be as simple as a reference equality check.
Similarly, you can implement shouldComponentUpdate and indicate the exact conditions under which you would like the component to re-render. If you write pure components (where the return value of the render function is entirely dependent on props and state), you can leverage PureRenderMixin to do this for you. Once again, immutable data structures are useful to keep this fast -- if you have to do a deep comparison of a large list of objects, it may be that re-rendering your entire component would be quicker, and it would certainly require less code.
"Slow Navigator transitions" is the most common manifestation of this, but there are other times this can happen. Using InteractionManager can be a good approach, but if the user experience cost is too high to delay work during an animation, then you might want to consider LayoutAnimation.
The Animated API currently calculates each keyframe on-demand on the JavaScript thread unless you set useNativeDriver: true, while LayoutAnimation leverages Core Animation and is unaffected by JS thread and main thread frame drops.
One case where I have used this is for animating in a modal (sliding down from top and fading in a translucent overlay) while initializing and perhaps receiving responses for several network requests, rendering the contents of the modal, and updating the view where the modal was opened from. See the Animations guide for more information about how to use LayoutAnimation.
Caveats:
Animated.This is especially true when you have text with a transparent background positioned on top of an image,
+or any other situation where alpha compositing would be required to re-draw the view on each frame.
+You will find that enabling shouldRasterizeIOS or renderToHardwareTextureAndroid can help with this significantly.
Be careful not to overuse this or your memory usage could go through the roof. +Profile your performance and memory usage when using these props. +If you don't plan to move a view anymore, turn this property off.
On iOS, each time you adjust the width or height of an Image component it is re-cropped and scaled from the original image.
+This can be very expensive, especially for large images.
+Instead, use the transform: [{scale}] style property to animate the size.
+An example of when you might do this is when you tap an image and zoom it in to full screen.
Sometimes, if we do an action in the same frame that we are adjusting the opacity or highlight of a component that is responding to a touch,
+we won't see that effect until after the onPress function has returned.
+If onPress does a setState that results in a lot of work and a few frames dropped, this may occur.
+A solution to this is to wrap any action inside of your onPress handler in requestAnimationFrame:
As mentioned above, Navigator animations are controlled by the JavaScript thread.
+Imagine the "push from right" scene transition:
+each frame, the new scene is moved from the right to left,
+starting offscreen (let's say at an x-offset of 320) and ultimately settling when the scene sits at an x-offset of 0.
+Each frame during this transition, the JavaScript thread needs to send a new x-offset to the main thread.
+If the JavaScript thread is locked up, it cannot do this and so no update occurs on that frame and the animation stutters.
One solution to this is to allow for JavaScript-based animations to be offloaded to the main thread. +If we were to do the same thing as in the above example with this approach, +we might calculate a list of all x-offsets for the new scene when we are starting the transition and send them to the main thread to execute in an optimized way. +Now that the JavaScript thread is freed of this responsibility, +it's not a big deal if it drops a few frames while rendering the scene -- you probably won't even notice because you will be too distracted by the pretty transition.
Solving this is one of the main goals behind the new React Navigation library.
+The views in React Navigation use native components and the Animated library to deliver 60 FPS animations that are run on the native thread.
Use the built-in profiler to get detailed information about work done in the JavaScript thread and main thread side-by-side. +Access it by selecting Perf Monitor from the Debug menu.
For iOS, Instruments is an invaluable tool, and on Android you should learn to use systrace.
You can also use react-addons-perf to get insights into where React is spending time when rendering your components.
Another way to profile JavaScript is to use the Chrome profiler while debugging. +This won't give you accurate results as the code is running in Chrome but will give you a general idea of where bottlenecks might be.
But first, make sure that Development Mode is OFF! You should see __DEV__ === false, development-level warning are OFF, performance optimizations are ON in your application logs.
systrace #Android supports 10k+ different phones and is generalized to support software rendering: +the framework architecture and need to generalize across many hardware targets unfortunately means you get less for free relative to iOS. +But sometimes, there are things you can improve -- and many times it's not native code's fault at all!
The first step for debugging this jank is to answer the fundamental question of where your time is being spent during each 16ms frame.
+For that, we'll be using a standard Android profiling tool called systrace.
systrace is a standard Android marker-based profiling tool (and is installed when you install the Android platform-tools package).
+Profiled code blocks are surrounded by start/end markers which are then visualized in a colorful chart format.
+Both the Android SDK and React Native framework provide standard markers that you can visualize.
First, connect a device that exhibits the stuttering you want to investigate to your computer via USB and get it to the point right before the navigation/animation you want to profile.
+Run systrace as follows:
A quick breakdown of this command:
time is the length of time the trace will be collected in secondssched, gfx, and view are the android SDK tags (collections of markers) we care about: sched gives you information about what's running on each core of your phone, gfx gives you graphics info such as frame boundaries, and view gives you information about measure, layout, and draw passes-a <your_package_name> enables app-specific markers, specifically the ones built into the React Native framework. your_package_name can be found in the AndroidManifest.xml of your app and looks like com.example.appOnce the trace starts collecting, perform the animation or interaction you care about. At the end of the trace, systrace will give you a link to the trace which you can open in your browser.
After opening the trace in your browser (preferably Chrome), you should see something like this:

HINT: +Use the WASD keys to strafe and zoom
If your trace .html file isn't opening correctly, check your browser console for the following:

Since Object.observe was deprecated in recent browsers, you may have to open the file from the Google Chrome Tracing tool. You can do so by:
Enable VSync highlighting
Check this checkbox at the top right of the screen to highlight the 16ms frame boundaries:
You should see zebra stripes as in the screenshot above. +If you don't, try profiling on a different device: Samsung has been known to have issues displaying vsyncs while the Nexus series is generally pretty reliable.
Scroll until you see (part of) the name of your package.
+In this case, I was profiling com.facebook.adsmanager,
+which shows up as book.adsmanager because of silly thread name limits in the kernel.
On the left side, you'll see a set of threads which correspond to the timeline rows on the right.
+There are a few threads we care about for our purposes:
+the UI thread (which has your package name or the name UI Thread), mqt_js, and mqt_native_modules.
+If you're running on Android 5+, we also care about the Render Thread.
UI Thread.
+This is where standard android measure/layout/draw happens.
+The thread name on the right will be your package name (in my case book.adsmanager) or UI Thread.
+The events that you see on this thread should look something like this and have to do with Choreographer, traversals, and DispatchUI:

JS Thread.
+This is where JavaScript is executed.
+The thread name will be either mqt_js or <...> depending on how cooperative the kernel on your device is being.
+To identify it if it doesn't have a name, look for things like JSCall, Bridge.executeJSCall, etc:

Native Modules Thread.
+This is where native module calls (e.g. the UIManager) are executed.
+The thread name will be either mqt_native_modules or <...>.
+To identify it in the latter case, look for things like NativeCall, callJavaModuleMethod, and onBatchComplete:

Bonus: Render Thread.
+If you're using Android L (5.0) and up, you will also have a render thread in your application.
+This thread generates the actual OpenGL commands used to draw your UI.
+The thread name will be either RenderThread or <...>.
+To identify it in the latter case, look for things like DrawFrame and queueBuffer:

A smooth animation should look something like the following:

Each change in color is a frame -- remember that in order to display a frame, +all our UI work needs to be done by the end of that 16ms period. +Notice that no thread is working close to the frame boundary. +An application rendering like this is rendering at 60 FPS.
If you noticed chop, however, you might see something like this:

Notice that the JS thread is executing basically all the time, and across frame boundaries! +This app is not rendering at 60 FPS. +In this case, the problem lies in JS.
You might also see something like this:

In this case, the UI and render threads are the ones that have work crossing frame boundaries. +The UI that we're trying to render on each frame is requiring too much work to be done. +In this case, the problem lies in the native views being rendered.
At this point, you'll have some very helpful information to inform your next steps.
If you identified a JS problem,
+look for clues in the specific JS that you're executing.
+In the scenario above, we see RCTEventEmitter being called multiple times per frame.
+Here's a zoom-in of the JS thread from the trace above:

This doesn't seem right. +Why is it being called so often? +Are they actually different events? +The answers to these questions will probably depend on your product code. +And many times, you'll want to look into shouldComponentUpdate.
If you identified a native UI problem, there are usually two scenarios:
In the first scenario, you'll see a trace that has the UI thread and/or Render Thread looking like this:

Notice the long amount of time spent in DrawFrame that crosses frame boundaries. This is time spent waiting for the GPU to drain its command buffer from the previous frame.
To mitigate this, you should:
renderToHardwareTextureAndroid for complex, static content that is being animated/transformed (e.g. the Navigator slide/alpha animations)needsOffscreenAlphaCompositing, which is disabled by default, as it greatly increases the per-frame load on the GPU in most cases.If these don't help and you want to dig deeper into what the GPU is actually doing, you can check out Tracer for OpenGL ES.
In the second scenario, you'll see something more like this:

Notice that first the JS thread thinks for a bit, then you see some work done on the native modules thread, followed by an expensive traversal on the UI thread.
There isn't an easy way to mitigate this unless you're able to postpone creating new UI until after the interaction, or you are able to simplify the UI you're creating. The react native team is working on a infrastructure level solution for this that will allow new UI to be created and configured off the main thread, allowing the interaction to continue smoothly.
Improve this page by sending a pull request!
PermissionsAndroid provides access to Android M's new permissions model.
+Some permissions are granted by default when the application is installed
+so long as they appear in AndroidManifest.xml. However, "dangerous"
+permissions require a dialog prompt. You should use this module for those
+permissions.
On devices before SDK version 23, the permissions are automatically granted
+if they appear in the manifest, so check and request
+should always be true.
If a user has previously turned off a permission that you prompt for, the OS
+will advise your app to show a rationale for needing the permission. The
+optional rationale argument will show a dialog prompt only if
+necessary - otherwise the normal permission prompt will appear.
DEPRECATED - use check
Returns a promise resolving to a boolean value as to whether the specified +permissions has been granted
@deprecated
Returns a promise resolving to a boolean value as to whether the specified +permissions has been granted
DEPRECATED - use request
Prompts the user to enable a permission and returns a promise resolving to a +boolean value indicating whether the user allowed or denied the request
If the optional rationale argument is included (which is an object with a
+title and message), this function checks with the OS whether it is
+necessary to show a dialog explaining why the permission is needed
+(https://developer.android.com/training/permissions/requesting.html#explain)
+and then shows the system permission dialog
@deprecated
Prompts the user to enable a permission and returns a promise resolving to a +string value indicating whether the user allowed or denied the request
If the optional rationale argument is included (which is an object with a
+title and message), this function checks with the OS whether it is
+necessary to show a dialog explaining why the permission is needed
+(https://developer.android.com/training/permissions/requesting.html#explain)
+and then shows the system permission dialog
Prompts the user to enable multiple permissions in the same dialog and +returns an object with the permissions as keys and strings as values +indicating whether the user allowed or denied the request
Improve this page by sending a pull request!
Renders the native picker component on iOS and Android. Example:
Callback for when an item is selected. This is called with the following parameters:
+ - itemValue: the value prop of the item that was selected
+ - itemPosition: the index of the selected item in this picker
Value matching value of one of the items. Can be a string or an integer.
Used to locate this view in end-to-end tests.
If set to false, the picker will be disabled, i.e. the user will not be able to make a +selection.
On Android, specifies how to display the selection items when the user taps on the picker:
Prompt string for this picker, used on Android in dialog mode as the title of the dialog.
Style to apply to each of the item labels.
Improve this page by sending a pull request!
PixelRatio class gives access to the device pixel density.
You should get a higher resolution image if you are on a high pixel density +device. A good rule of thumb is to multiply the size of the image you display +by the pixel ratio.
In iOS, you can specify positions and dimensions for elements with arbitrary +precision, for example 29.674825. But, ultimately the physical display only +have a fixed number of pixels, for example 640×960 for iPhone 4 or 750×1334 +for iPhone 6. iOS tries to be as faithful as possible to the user value by +spreading one original pixel into multiple ones to trick the eye. The +downside of this technique is that it makes the resulting element look +blurry.
In practice, we found out that developers do not want this feature and they +have to work around it by doing manual rounding in order to avoid having +blurry elements. In React Native, we are rounding all the pixels +automatically.
We have to be careful when to do this rounding. You never want to work with +rounded and unrounded values at the same time as you're going to accumulate +rounding errors. Having even one rounding error is deadly because a one +pixel border may vanish or be twice as big.
In React Native, everything in JavaScript and within the layout engine works +with arbitrary precision numbers. It's only when we set the position and +dimensions of the native element on the main thread that we round. Also, +rounding is done relative to the root rather than the parent, again to avoid +accumulating rounding errors.
Returns the device pixel density. Some examples:
Returns the scaling factor for font sizes. This is the ratio that is used to calculate the +absolute font size, so any elements that heavily depend on that should use this to do +calculations.
If a font scale is not set, this returns the device pixel ratio.
Currently this is only implemented on Android and reflects the user preference set in +Settings > Display > Font size, on iOS it will always return the default pixel ratio. +@platform android
Converts a layout size (dp) to pixel size (px).
Guaranteed to return an integer number.
Rounds a layout size (dp) to the nearest layout size that corresponds to
+an integer number of pixels. For example, on a device with a PixelRatio
+of 3, PixelRatio.roundToNearestPixel(8.4) = 8.33, which corresponds to
+exactly (8.33 * 3) = 25 pixels.
// No-op for iOS, but used on the web. Should not be documented.
Improve this page by sending a pull request!
When building a cross-platform app, you'll want to re-use as much code as possible. Scenarios may arise where it makes sense for the code to be different, for example you may want to implement separate visual components for iOS and Android.
React Native provides two ways to easily organize your code and separate it by platform:
Platform module.Certain components may have properties that work on one platform only. All of these props are annotated with @platform and have a small badge next to them on the website.
React Native provides a module that detects the platform in which the app is running. You can use the detection logic to implement platform-specific code. Use this option when only small parts of a component are platform-specific.
Platform.OS will be ios when running on iOS and android when running on Android.
There is also a Platform.select method available, that given an object containing Platform.OS as keys, returns the value for the platform you are currently running on.
This will result in a container having flex: 1 on both platforms, a red background color on iOS, and a blue background color on Android.
Since it accepts any value, you can also use it to return platform specific component, like below:
On Android, the Platform module can also be used to detect the version of the Android Platform in which the app is running:
On iOS, the Version is a result of -[UIDevice systemVersion], which is a string with the current version of the operating system. An example of the system version is "10.3". For example, to detect the major version number on iOS:
When your platform-specific code is more complex, you should consider splitting the code out into separate files. React Native will detect when a file has a .ios. or .android. extension and load the relevant platform file when required from other components.
For example, say you have the following files in your project:
You can then require the component as follows:
React Native will automatically pick up the right file based on the running platform.
Improve this page by sending a pull request!
React component that wraps the Android-only ProgressBar. This component is used to indicate
+that the app is loading or there is some activity in the app.
Example:
If the progress bar will show indeterminate progress. Note that this +can only be false if styleAttr is Horizontal.
The progress value (between 0 and 1).
Style of the ProgressBar. One of:
Used to locate this view in end-to-end tests.
Improve this page by sending a pull request!
Use ProgressViewIOS to render a UIProgressView on iOS.
The progress value (between 0 and 1).
A stretchable image to display as the progress bar.
The tint color of the progress bar itself.
The progress bar style.
A stretchable image to display behind the progress bar.
The tint color of the progress bar track.
Improve this page by sending a pull request!
Most components can be customized when they are created, with different parameters. These creation parameters are called props.
For example, one basic React Native component is the Image. When you
+create an image, you can use a prop named source to control what image it shows.
Notice that {pic} is surrounded by braces, to embed the variable pic into JSX. You can put any JavaScript expression inside braces in JSX.
Your own components can also use props. This lets you make a single component
+that is used in many different places in your app, with slightly different
+properties in each place. Just refer to this.props in your render function. Here's an example:
Using name as a prop lets us customize the Greeting component, so we can reuse that component for each of our greetings. This example also uses the Greeting component in JSX, just like the built-in components. The power to do this is what makes React so cool - if you find yourself wishing that you had a different set of UI primitives to work with, you just invent new ones.
The other new thing going on here is the View component. A View is useful
+as a container for other components, to help control style and layout.
With props and the basic Text, Image, and View components, you can
+build a wide variety of static screens. To learn how to make your app change over time, you need to learn about State.
Improve this page by sending a pull request!
Handle push notifications for your app, including permission handling and +icon badge number.
To get up and running, configure your notifications with Apple +and your server-side system.
Manually link the PushNotificationIOS library
node_modules/react-native/Libraries/PushNotificationIOS/RCTPushNotification.xcodeprojLink Binary With Libraries: libRCTPushNotification.aFinally, to enable support for notification and register events you need to augment your AppDelegate.
At the top of your AppDelegate.m:
#import <React/RCTPushNotificationManager.h>
And then in your AppDelegate implementation add the following:
Schedules the localNotification for future presentation.
details is an object containing:
fireDate : The date and time when the system should deliver the notification.alertTitle : The text displayed as the title of the notification alert.alertBody : The message displayed in the notification alert.alertAction : The "action" displayed beneath an actionable notification. Defaults to "view";soundName : The sound played when the notification is fired (optional).isSilent : If true, the notification will appear without sound (optional).category : The category of this notification, required for actionable notifications (optional).userInfo : An optional object containing additional notification data.applicationIconBadgeNumber (optional) : The number to display as the app's icon badge. Setting the number to 0 removes the icon badge.repeatInterval : The interval to repeat as a string. Possible values: minute, hour, day, week, month, year.Cancels all scheduled localNotifications
Remove all delivered notifications from Notification Center
Provides you with a list of the app’s notifications that are still displayed in Notification Center
@param callback Function which receive an array of delivered notifications
A delivered notification is an object containing:
identifier : The identifier of this notification.title : The title of this notification.body : The body of this notification.category : The category of this notification, if has one.userInfo : An optional object containing additional notification data.thread-id : The thread identifier of this notification, if has one.Removes the specified notifications from Notification Center
@param identifiers Array of notification identifiers
Sets the badge number for the app icon on the home screen
Gets the current badge number for the app icon on the home screen
Cancel local notifications.
Optionally restricts the set of canceled notifications to those
+notifications whose userInfo fields match the corresponding fields
+in the userInfo argument.
Gets the local notifications that are currently scheduled.
Attaches a listener to remote or local notification events while the app is running +in the foreground or the background.
Valid events are:
notification : Fired when a remote notification is received. The
+handler will be invoked with an instance of PushNotificationIOS.localNotification : Fired when a local notification is received. The
+handler will be invoked with an instance of PushNotificationIOS.register: Fired when the user registers for remote notifications. The
+handler will be invoked with a hex string representing the deviceToken.registrationError: Fired when the user fails to register for remote
+notifications. Typically occurs when APNS is having issues, or the device
+is a simulator. The handler will be invoked with
+{message: string, code: number, details: any}.Removes the event listener. Do this in componentWillUnmount to prevent
+memory leaks
Requests notification permissions from iOS, prompting the user's +dialog box. By default, it will request all notification permissions, but +a subset of these can be requested by passing a map of requested +permissions. +The following permissions are supported:
alertbadgesoundIf a map is provided to the method, only the permissions with truthy values +will be requested.
This method returns a promise that will resolve when the user accepts, +rejects, or if the permissions were previously rejected. The promise +resolves to the current state of the permission.
Unregister for all remote notifications received via Apple Push Notification service.
You should call this method in rare circumstances only, such as when a new version of +the app removes support for all types of remote notifications. Users can temporarily +prevent apps from receiving remote notifications through the Notifications section of +the Settings app. Apps unregistered through this method can always re-register.
See what push permissions are currently enabled. callback will be
+invoked with a permissions object:
alert :booleanbadge :booleansound :booleanThis method returns a promise that resolves to either the notification
+object if the app was launched by a push notification, or null otherwise.
You will never need to instantiate PushNotificationIOS yourself.
+Listening to the notification event and invoking
+getInitialNotification is sufficient
This method is available for remote notifications that have been received via:
+application:didReceiveRemoteNotification:fetchCompletionHandler:
+https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/#//apple_ref/occ/intfm/UIApplicationDelegate/application:didReceiveRemoteNotification:fetchCompletionHandler:
Call this to execute when the remote notification handling is complete. When
+calling this block, pass in the fetch result value that best describes
+the results of your operation. You must call this handler and should do so
+as soon as possible. For a list of possible values, see PushNotificationIOS.FetchResult.
If you do not call this method your background remote notifications could +be throttled, to read more about it see the above documentation link.
An alias for getAlert to get the notification's main message string
Gets the sound string from the aps object
Gets the category string from the aps object
Gets the notification's main message from the aps object
Gets the content-available number from the aps object
Gets the badge count number from the aps object
Gets the data object on the notif
Improve this page by sending a pull request!
This component is used inside a ScrollView or ListView to add pull to refresh
+functionality. When the ScrollView is at scrollY: 0, swiping down
+triggers an onRefresh event.
Note: refreshing is a controlled prop, this is why it needs to be set to true
+in the onRefresh function otherwise the refresh indicator will stop immediately.
Called when the view starts refreshing.
Whether the view should be indicating an active refresh.
Whether the pull to refresh functionality is enabled.
Progress view top offset
Size of the refresh indicator, see RefreshControl.SIZE.
The title displayed under the refresh indicator.
Improve this page by sending a pull request!
It's always a good idea to test your app on an actual device before releasing it to your users. This document will guide you through the necessary steps to run your React Native app on a device and to get it ready for production.
If you used Create React Native App to set up your project, you can preview your app on a device by scanning the QR code with the Expo app. In order to build and run your app on a device, you will need to eject and install the native code dependencies from the Getting Started guide.
A Mac is required in order to build your app for iOS devices. Alternatively, you can refer to the Quick Start instructions to learn how to build your app using Create React Native App, which will allow you to run your app using the Expo client app.
Connect your iOS device to your Mac using a USB to Lightning cable. Navigate to the ios folder in your project, then open the .xcodeproj file within it using Xcode.
If this is your first time running an app on your iOS device, you may need to register your device for development. Open the Product menu from Xcode's menubar, then go to Destination. Look for and select your device from the list. Xcode will then register your device for development.
Register for an Apple developer account if you don't have one yet.
Select your project in the Xcode Project Navigator, then select your main target (it should share the same name as your project). Look for the "General" tab. Go to "Signing" and make sure your Apple developer account or team is selected under the Team dropdown.

Repeat this step for the Tests target in your project.
If everything is set up correctly, your device will be listed as the build target in the Xcode toolbar, and it will also appear in the Devices pane (⇧⌘2). You can now press the Build and run button (⌘R) or select Run from the Product menu. Your app will launch on your device shortly.

If you run into any issues, please take a look at Apple's Launching Your App on a Device docs.
Most Android devices can only install and run apps downloaded from Google Play, by default. You will need to enable USB Debugging on your device in order to install your app during development.
To enable USB debugging on your device, you will first need to enable the "Developer options" menu by going to Settings → About phone and then tapping the Build number row at the bottom seven times. You can then go back to Settings → Developer options to enable "USB debugging".
Let's now set up an Android device to run our React Native projects. Go ahead and plug in your device via USB to your development machine.
Next, check the manufacturer code by using lsusb (on mac, you must first install lsusb). lsusb should output something like this:
These lines represent the USB devices currently connected to your machine.
You want the line that represents your phone. If you're in doubt, try unplugging your phone and running the command again:
You'll see that after removing the phone, the line which has the phone model ("Motorola PCS" in this case) disappeared from the list. This is the line that we care about.
Bus 001 Device 003: ID 22b8:2e76 Motorola PCS
From the above line, you want to grab the first four digits from the device ID:
22b8:2e76
In this case, it's 22b8. That's the identifier for Motorola.
You'll need to input this into your udev rules in order to get up and running:
Make sure that you replace 22b8 with the identifier you get in the above command.
Now check that your device is properly connecting to ADB, the Android Debug Bridge, by running adb devices.
Seeing device in the right column means the device is connected. You must have only one device connected at a time.
Type the following in your command prompt to install and launch your app on the device:
If you get a "bridge configuration isn't available" error, see Using adb reverse.
Hint
You can also use the
React Native CLIto generate and run aReleasebuild (e.g.react-native run-android --variant=release).
You can also iterate quickly on a device using the development server. You only have to be on the same Wi-Fi network as your computer. Shake your device to open the Developer menu, then enable Live Reload. Your app will reload whenever your JavaScript code has changed.

If you have any issues, ensure that your Mac and device are on the same network and can reach each other. Many open wireless networks with captive portals are configured to prevent devices from reaching other devices on the network. You may use your device's Personal Hotspot feature in this case.
When trying to connect to the development server you might get a red screen with an error saying:
Connection to http://localhost:8081/debugger-proxy?role=client timed out. Are you running node proxy? If you are running on the device, check if you have the right IP address in
RCTWebSocketExecutor.m.
To solve this issue check the following points.
Make sure your laptop and your phone are on the same Wi-Fi network.
Make sure that the build script detected the IP address of your machine correctly (e.g. 10.0.1.123).

Open the Report navigator tab, select the last Build and search for xip.io. The IP address which gets embedded in the app should match your machines IP address plus the domain .xip.io (e.g. 10.0.1.123.xip.io)
React Native uses the wildcard DNS service xip.io to address your device. Some routers have security features to prevent DNS Servers to resolve anything in the local IP range.
Now check if you are able to resolve the xip.io address, by running nslookup.
If it doesn't resolve your local IP address either the xip.io service is down or more likely your router prevents it.
To still use xip.io behind your rooter:
You can also iterate quickly on a device by connecting to the development server running on your development machine. There are several ways of accomplishing this, depending on whether you have access to a USB cable or a Wi-Fi network.
You can use this method if your device is running Android 5.0 (Lollipop) or newer, it has USB debugging enabled, and it is connected via USB to your development machine.
Run the following in a command prompt:
You can now enable Live reloading from the Developer menu. Your app will reload whenever your JavaScript code has changed.
You can also connect to the development server over Wi-Fi. You'll first need to install the app on your device using a USB cable, but once that has been done you can debug wirelessly by following these instructions. You'll need your development machine's current IP address before proceeding.
You can find the IP address in System Preferences → Network.
Open the command prompt and type ipconfig to find your machine's IP address (more info).
Open a terminal and type /sbin/ifconfig to find your machine's IP address.
You can now enable Live reloading from the Developer menu. Your app will reload whenever your JavaScript code has changed.
You have built a great app using React Native, and you are now itching to release it in the App Store. The process is the same as any other native iOS app, with some additional considerations to take into account.
App Transport Security is a security feature introduced in iOS 9 that rejects all HTTP requests that are not sent over HTTPS. This can result in HTTP traffic being blocked, including the developer React Native server. ATS is disabled for localhost by default in React Native projects in order to make development easier.
You should re-enable ATS prior to building your app for production by removing the localhost entry from the NSExceptionDomains dictionary in your Info.plist file in the ios/ folder. You can also re-enable ATS from within Xcode by opening your target properties under the Info pane and editing the App Transport Security Settings entry.
If your application needs to access HTTP resources on production, see this post to learn how to configure ATS on your project.
Building an app for distribution in the App Store requires using the Release scheme in Xcode. Apps built for Release will automatically disable the in-app Developer menu, which will prevent your users from inadvertently accessing the menu in production. It will also bundle the JavaScript locally, so you can put the app on a device and test whilst not connected to the computer.
To configure your app to be built using the Release scheme, go to Product → Scheme → Edit Scheme. Select the Run tab in the sidebar, then set the Build Configuration dropdown to Release.

You can now build your app for release by tapping ⌘B or selecting Product → Build from the menu bar. Once built for release, you'll be able to distribute the app to beta testers and submit the app to the App Store.
You can also use the
React Native CLIto perform this operation using the option--configurationwith the valueRelease(e.g.react-native run-ios --configuration Release).
You have built a great app using React Native, and you are now itching to release it in the Play Store. The process is the same as any other native Android app, with some additional considerations to take into account. Follow the guide for generating a signed APK to learn more.
+Improve this page by sending a pull request!
Once you have your React Native project initialized, you can run react-native run-ios inside the newly created project directory. If everything is set up correctly, you should see your new app running in the iOS Simulator shortly.
You can specify the device the simulator should run with the --simulator flag, followed by the device name as a string. The default is "iPhone 6". If you wish to run your app on an iPhone 4s, just run react-native run-ios --simulator="iPhone 4s".
The device names correspond to the list of devices available in Xcode. You can check your available devices by running xcrun simctl list devices from the console.
Improve this page by sending a pull request!
Component that wraps platform ScrollView while providing +integration with touch locking "responder" system.
Keep in mind that ScrollViews must have a bounded height in order to work,
+since they contain unbounded-height children into a bounded container (via
+a scroll interaction). In order to bound the height of a ScrollView, either
+set the height of the view directly (discouraged) or make sure all parent
+views have bounded height. Forgetting to transfer {flex: 1} down the
+view stack can lead to errors here, which the element inspector makes
+easy to debug.
Doesn't yet support other contained responders from blocking this scroll +view from becoming the responder.
<ScrollView> vs <FlatList> - which one to use?
ScrollView simply renders all its react child components at once. That
+makes it very easy to understand and use.
On the other hand, this has a performance downside. Imagine you have a very +long list of items you want to display, maybe several screens worth of +content. Creating JS components and native views for everything all at once, +much of which may not even be shown, will contribute to slow rendering and +increased memory usage.
This is where FlatList comes into play. FlatList renders items lazily,
+just when they are about to appear, and removes items that scroll way off
+screen to save memory and processing time.
FlatList is also handy if you want to render separators between your items,
+multiple columns, infinite scroll loading, or any number of other features it
+supports out of the box.
These styles will be applied to the scroll view content container which +wraps all of the child views. Example:
When true, the scroll view's children are arranged horizontally in a row +instead of vertically in a column. The default value is false.
Determines whether the keyboard gets dismissed in response to a drag.
Cross platform
'none' (the default), drags do not dismiss the keyboard.'on-drag', the keyboard is dismissed when a drag begins.iOS Only
'interactive', the keyboard is dismissed interactively with the drag and moves in
+synchrony with the touch; dragging upwards cancels the dismissal.
+On android this is not supported and it will have the same behavior as 'none'.Determines when the keyboard should stay visible after a tap.
'never' (the default), tapping outside of the focused text input when the keyboard
+is up dismisses the keyboard. When this happens, children won't receive the tap.'always', the keyboard will not dismiss automatically, and the scroll view will not
+catch taps, but children of the scroll view can catch taps.'handled', the keyboard will not dismiss automatically when the tap was handled by
+a children, (or captured by an ancestor).false, deprecated, use 'never' insteadtrue, deprecated, use 'always' insteadCalled when scrollable content view of the ScrollView changes.
Handler function is passed the content width and content height as parameters:
+(contentWidth, contentHeight)
It's implemented using onLayout handler attached to the content container +which this ScrollView renders.
Called when the momentum scroll starts (scroll which occurs as the ScrollView glides to a stop).
Called when the momentum scroll ends (scroll which occurs as the ScrollView glides to a stop).
Fires at most once per frame during scrolling. The frequency of the
+events can be controlled using the scrollEventThrottle prop.
When true, the scroll view stops on multiples of the scroll view's size +when scrolling. This can be used for horizontal pagination. The default +value is false.
Note: Vertical pagination is not supported on Android.
A RefreshControl component, used to provide pull-to-refresh
+functionality for the ScrollView. Only works for vertical ScrollViews
+(horizontal prop must be false).
See RefreshControl.
Experimental: When true, offscreen child views (whose overflow value is
+hidden) are removed from their native backing superview when offscreen.
+This can improve scrolling performance on long lists. The default value is
+true.
When false, the view cannot be scrolled via touch interaction. +The default value is true.
Note that the view can be always be scrolled by calling scrollTo.
When true, shows a horizontal scroll indicator. +The default value is true.
When true, shows a vertical scroll indicator. +The default value is true.
An array of child indices determining which children get docked to the
+top of the screen when scrolling. For example, passing
+stickyHeaderIndices={[0]} will cause the first child to be fixed to the
+top of the scroll view. This property is not supported in conjunction
+with horizontal={true}.
(Android-only) Sets the elevation of a view, using Android's underlying +elevation API. +This adds a drop shadow to the item and affects z-order for overlapping views. +Only supported on Android 5.0+, has no effect on earlier versions.
Sometimes a scrollview takes up more space than its content fills. When this is +the case, this prop will fill the rest of the scrollview with a color to avoid setting +a background and creating unnecessary overdraw. This is an advanced optimization +that is not needed in the general case.
Used to override default value of overScroll mode.
Possible values:
'auto' - Default value, allow a user to over-scroll
+this view only if the content is large enough to meaningfully scroll.'always' - Always allow a user to over-scroll this view.'never' - Never allow a user to over-scroll this view.Tag used to log scroll performance on this scroll view. Will force +momentum events to be turned on (see sendMomentumEvents). This doesn't do +anything out of the box and you need to implement a custom native +FpsListener for it to be useful.
When true, ScrollView will emit updateChildFrames data in scroll events,
+otherwise will not compute or emit child frame data. This only exists
+to support legacy issues, onLayout should be used instead to retrieve
+frame data.
+The default value is false.
When true, the scroll view bounces horizontally when it reaches the end
+even if the content is smaller than the scroll view itself. The default
+value is true when horizontal={true} and false otherwise.
When true, the scroll view bounces vertically when it reaches the end
+even if the content is smaller than the scroll view itself. The default
+value is false when horizontal={true} and true otherwise.
Controls whether iOS should automatically adjust the content inset +for scroll views that are placed behind a navigation bar or +tab bar/ toolbar. The default value is true.
When true, the scroll view bounces when it reaches the end of the
+content if the content is larger then the scroll view along the axis of
+the scroll direction. When false, it disables all bouncing even if
+the alwaysBounce* props are true. The default value is true.
When true, gestures can drive zoom past min/max and the zoom will animate +to the min/max value at gesture end, otherwise the zoom will not exceed +the limits.
When false, once tracking starts, won't try to drag if the touch moves. +The default value is true.
When true, the scroll view automatically centers the content when the +content is smaller than the scroll view bounds; when the content is +larger than the scroll view, this property has no effect. The default +value is false.
The amount by which the scroll view content is inset from the edges
+of the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
This property specifies how the safe area insets are used to modify the +content area of the scroll view. The default value of this property is +"never". Available on iOS 11 and later.
Used to manually set the starting scroll offset.
+The default value is {x: 0, y: 0}.
A floating-point number that determines how quickly the scroll view
+decelerates after the user lifts their finger. You may also use string
+shortcuts "normal" and "fast" which match the underlying iOS settings
+for UIScrollViewDecelerationRateNormal and
+UIScrollViewDecelerationRateFast respectively.
'normal': 0.998 (the default)'fast': 0.99When true, the ScrollView will try to lock to only vertical or horizontal +scrolling while dragging. The default value is false.
The style of the scroll indicators.
'default' (the default), same as black.'black', scroll indicator is black. This style is good against a light background.'white', scroll indicator is white. This style is good against a dark background.The maximum allowed zoom scale. The default value is 1.0.
The minimum allowed zoom scale. The default value is 1.0.
When true, ScrollView allows use of pinch gestures to zoom in and out. +The default value is true.
This controls how often the scroll event will be fired while scrolling +(as a time interval in ms). A lower number yields better accuracy for code +that is tracking the scroll position, but can lead to scroll performance +problems due to the volume of information being send over the bridge. +You will not notice a difference between values set between 1-16 as the +JS run loop is synced to the screen refresh rate. If you do not need precise +scroll position tracking, set this value higher to limit the information +being sent across the bridge. The default value is zero, which results in +the scroll event being sent only once each time the view is scrolled.
The amount by which the scroll view indicators are inset from the edges
+of the scroll view. This should normally be set to the same value as
+the contentInset. Defaults to {0, 0, 0, 0}.
When true, the scroll view scrolls to top when the status bar is tapped. +The default value is true.
When snapToInterval is set, snapToAlignment will define the relationship
+of the snapping to the scroll view.
'start' (the default) will align the snap at the left (horizontal) or top (vertical)'center' will align the snap in the center'end' will align the snap at the right (horizontal) or bottom (vertical)When set, causes the scroll view to stop at multiples of the value of
+snapToInterval. This can be used for paginating through children
+that have lengths smaller than the scroll view. Typically used in
+combination with snapToAlignment and decelerationRate="fast".
+Overrides less configurable pagingEnabled prop.
The current scale of the scroll view content. The default value is 1.0.
Scrolls to a given x, y offset, either immediately or with a smooth animation.
Example:
scrollTo({x: 0, y: 0, animated: true})
Note: The weird function signature is due to the fact that, for historical reasons, +the function also accepts separate arguments as an alternative to the options object. +This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED.
If this is a vertical ScrollView scrolls to the bottom. +If this is a horizontal ScrollView scrolls to the right.
Use scrollToEnd({animated: true}) for smooth animated scrolling,
+scrollToEnd({animated: false}) for immediate scrolling.
+If no options are passed, animated defaults to true.
Deprecated, use scrollTo instead.
Displays the scroll indicators momentarily.
Improve this page by sending a pull request!
A performant interface for rendering sectioned lists, supporting the most handy features:
If you don't need section support and want a simpler interface, use
+<FlatList>.
Simple Examples:
This is a convenience wrapper around <VirtualizedList>,
+and thus inherits its props (as well as those of ScrollView) that aren't explicitly listed
+here, along with the following caveats:
PureComponent which means that it will not re-render if props remain shallow-
+equal. Make sure that everything your renderItem function depends on is passed as a prop
+(e.g. extraData) that is not === after updates, otherwise your UI may not update on
+changes. This includes the data prop and parent component state.key prop on each item and uses that for the React key.
+Alternatively, you can provide a custom keyExtractor prop.Scrolls to the item at the specified sectionIndex and itemIndex (within the section)
+positioned in the viewable area such that viewPosition 0 places it at the top (and may be
+covered by a sticky header), 1 at the bottom, and 0.5 centered in the middle. viewOffset is a
+fixed number of pixels to offset the final target position, e.g. to compensate for sticky
+headers.
Note: cannot scroll to locations outside the render window without specifying the
+getItemLayout prop.
Tells the list an interaction has occured, which should trigger viewability calculations, e.g.
+if waitForInteractions is true and the user has not scrolled. This is typically called by
+taps on items or by navigation actions.
Displays the scroll indicators momentarily.
Improve this page by sending a pull request!
Use SegmentedControlIOS to render a UISegmentedControl iOS.
The selected index can be changed on the fly by assigning the +selectIndex prop to a state variable, then changing that variable. +Note that the state variable would need to be updated as the user +selects a value and changes the index, as shown in the example below.
If false the user won't be able to interact with the control. +Default value is true.
If true, then selecting a segment won't persist visually.
+The onValueChange callback will still work as expected.
Callback that is called when the user taps a segment; +passes the event as an argument
Callback that is called when the user taps a segment; +passes the segment's value as an argument
The index in props.values of the segment to be (pre)selected.
Accent color of the control.
The labels for the control's segment buttons, in order.
Improve this page by sending a pull request!
Open a dialog to share text content.
In iOS, Returns a Promise which will be invoked an object containing action, activityType.
+If the user dismissed the dialog, the Promise will still be resolved with action being Share.dismissedAction
+and all the other keys being undefined.
In Android, Returns a Promise which always be resolved with action being Share.sharedAction.
message - a message to sharetitle - title of the messageurl - an URL to shareAt least one of URL and message is required.
excludedActivityTypestintColordialogTitleThe content was successfully shared.
The dialog has been dismissed. +@platform ios
Improve this page by sending a pull request!
Android requires that all apps be digitally signed with a certificate before they can be installed, so to distribute your Android application via Google Play store, you'll need to generate a signed release APK. The Signing Your Applications page on Android Developers documentation describes the topic in detail. This guide covers the process in brief, as well as lists the steps required to packaging the JavaScript bundle.
You can generate a private signing key using keytool. On Windows keytool must be run from C:\Program Files\Java\jdkx.x.x_x\bin.
This command prompts you for passwords for the keystore and key, and to provide the Distinguished Name fields for your key. It then generates the keystore as a file called my-release-key.keystore.
The keystore contains a single key, valid for 10000 days. The alias is a name that you will use later when signing your app, so remember to take note of the alias.
Note: Remember to keep your keystore file private and never commit it to version control.
my-release-key.keystore file under the android/app directory in your project folder.~/.gradle/gradle.properties and add the following (replace ***** with the correct keystore password, alias and key password),These are going to be global gradle variables, which we can later use in our gradle config to sign our app.
Note about saving the keystore:
Once you publish the app on the Play Store, you will need to republish your app under a different package name (losing all downloads and ratings) if you want to change the signing key at any point. So backup your keystore and don't forget the passwords.
Note about security: If you are not keen on storing your passwords in plaintext and you are running OSX, you can also store your credentials in the Keychain Access app. Then you can skip the two last rows in ~/.gradle/gradle.properties.
Edit the file android/app/build.gradle in your project folder and add the signing config,
Simply run the following in a terminal:
Gradle's assembleRelease will bundle all the JavaScript needed to run your app into the APK. If you need to change the way the JavaScript bundle and/or drawable resources are bundled (e.g. if you changed the default file/folder names or the general structure of the project), have a look at android/app/build.gradle to see how you can update it to reflect these changes.
The generated APK can be found under android/app/build/outputs/apk/app-release.apk, and is ready to be distributed.
Before uploading the release build to the Play Store, make sure you test it thoroughly. First uninstall any previous version of the app you already have installed. Install it on the device using:
Note that --variant=release is only available if you've set up signing as described above.
You can kill any running packager instances, all your framework and JavaScript code is bundled in the APK's assets.
Proguard is a tool that can slightly reduce the size of the APK. It does this by stripping parts of the React Native Java bytecode (and its dependencies) that your app is not using.
IMPORTANT: Make sure to thoroughly test your app if you've enabled Proguard. Proguard often requires configuration specific to each native library you're using. See app/proguard-rules.pro.
To enable Proguard, edit android/app/build.gradle:
Improve this page by sending a pull request!
A component used to select a single value from a range of values.
If true the user won't be able to move the slider. +Default value is false.
The color used for the track to the right of the button. +Overrides the default blue gradient image on iOS.
Initial maximum value of the slider. Default value is 1.
The color used for the track to the left of the button. +Overrides the default blue gradient image on iOS.
Initial minimum value of the slider. Default value is 0.
Callback that is called when the user releases the slider, +regardless if the value has changed. The current value is passed +as an argument to the callback handler.
Callback continuously called while the user is dragging the slider.
Step value of the slider. The value should be +between 0 and (maximumValue - minimumValue). +Default value is 0.
Used to style and layout the Slider. See StyleSheet.js and
+ViewStylePropTypes.js for more info.
Used to locate this view in UI automation tests.
Initial value of the slider. The value should be between minimumValue +and maximumValue, which default to 0 and 1 respectively. +Default value is 0.
This is not a controlled component, you don't need to update the +value during dragging.
Assigns a maximum track image. Only static images are supported. The +leftmost pixel of the image will be stretched to fill the track.
Assigns a minimum track image. Only static images are supported. The +rightmost pixel of the image will be stretched to fill the track.
Sets an image for the thumb. Only static images are supported.
Assigns a single image for the track. Only static images are supported. +The center pixel of the image will be stretched to fill the track.
Improve this page by sending a pull request!
There are two types of data that control a component: props and state. props are set by the parent and they are fixed throughout the lifetime of a component. For data that is going to change, we have to use state.
In general, you should initialize state in the constructor, and then call setState when you want to change it.
For example, let's say we want to make text that blinks all the time. The text itself gets set once when the blinking component gets created, so the text itself is a prop. The "whether the text is currently on or off" changes over time, so that should be kept in state.
In a real application, you probably won't be setting state with a timer. You might set state when you have new data arrive from the server, or from user input. You can also use a state container like Redux to control your data flow. In that case you would use Redux to modify your state rather than calling setState directly.
When setState is called, BlinkApp will re-render its Component. By calling setState within the Timer, the component will re-render every time the Timer ticks.
State works the same way as it does in React, so for more details on handling state, you can look at the React.Component API. +At this point, you might be annoyed that most of our examples so far use boring default black text. To make things more beautiful, you will have to learn about Style.
Improve this page by sending a pull request!
Component to control the app status bar.
It is possible to have multiple StatusBar components mounted at the same
+time. The props will be merged in the order the StatusBar components were
+mounted. One use case is to specify status bar styles per route using Navigator.
For cases where using a component is not ideal, there is also an imperative +API exposed as static functions on the component. It is however not recommended +to use the static API and the component for the same prop because any value +set by the static API will get overriden by the one set by the component in +the next render.
currentHeight (Android only) The height of the status bar.
If the transition between status bar property changes should be animated. +Supported for backgroundColor, barStyle and hidden.
Sets the color of the status bar text.
If the status bar is hidden.
If the status bar is translucent. +When translucent is set to true, the app will draw under the status bar. +This is useful when using a semi transparent status bar color.
If the network activity indicator should be visible.
The transition effect when showing and hiding the status bar using the hidden
+prop. Defaults to 'fade'.
Show or hide the status bar
| Name and Type | Description |
|---|---|
| hidden boolean | Hide the status bar. |
| [animation] | Optional animation when + changing the status bar hidden property. |
Set the status bar style
| Name and Type | Description |
|---|---|
| style | Status bar style to set |
| [animated] boolean | Animate the style change. |
Control the visibility of the network activity indicator
| Name and Type | Description |
|---|---|
| visible boolean | Show the indicator. |
Set the background color for the status bar
| Name and Type | Description |
|---|---|
| color string | Background color. |
| [animated] boolean | Animate the style change. |
Control the translucency of the status bar
| Name and Type | Description |
|---|---|
| translucent boolean | Set as translucent. |
Status bar style
| Value | Description |
|---|---|
| default | Default status bar style (dark for iOS, light for Android) |
| light-content | Dark background, white texts and icons |
| dark-content | Light background, dark texts and icons |
Status bar animation
| Value | Description |
|---|---|
| none | No animation |
| fade | Fade animation |
| slide | Slide animation |
Improve this page by sending a pull request!
Use StatusBar for mutating the status bar.
Improve this page by sending a pull request!
With React Native, you don't use a special language or syntax for defining styles. You just style your application using JavaScript. All of the core components accept a prop named style. The style names and values usually match how CSS works on the web, except names are written using camel casing, e.g backgroundColor rather than background-color.
The style prop can be a plain old JavaScript object. That's the simplest and what we usually use for example code. You can also pass an array of styles - the last style in the array has precedence, so you can use this to inherit styles.
As a component grows in complexity, it is often cleaner to use StyleSheet.create to define several styles in one place. Here's an example:
One common pattern is to make your component accept a style prop which in
+turn is used to style subcomponents. You can use this to make styles "cascade" the way they do in CSS.
There are a lot more ways to customize text style. Check out the Text component reference for a complete list.
Now you can make your text beautiful. The next step in becoming a style master is to learn how to control component size.
Improve this page by sending a pull request!
A StyleSheet is an abstraction similar to CSS StyleSheets
Create a new StyleSheet:
Use a StyleSheet:
Code quality:
Performance:
WARNING: EXPERIMENTAL. Breaking changes will probably happen a lot and will +not be reliably announced. The whole thing might be deleted, who knows? Use +at your own risk.
Sets a function to use to pre-process a style property value. This is used +internally to process color and transform values. You should not use this +unless you really know what you are doing and have exhausted other options.
Creates a StyleSheet style reference from the given object.
This is defined as the width of a thin line on the platform. It can be +used as the thickness of a border or division between two elements. +Example:
This constant will always be a round number of pixels (so a line defined +by it look crisp) and will try to match the standard width of a thin line +on the underlying platform. However, you should not rely on it being a +constant size, because on different platforms and screen densities its +value may be calculated differently.
A line with hairline width may not be visible if your simulator is downscaled.
A very common pattern is to create overlays with position absolute and zero positioning,
+so absoluteFill can be used for convenience and to reduce duplication of these repeated
+styles.
Sometimes you may want absoluteFill but with a couple tweaks - absoluteFillObject can be
+used to create a customized entry in a StyleSheet, e.g.:
const styles = StyleSheet.create({ + wrapper: { + ...StyleSheet.absoluteFillObject, + top: 10, + backgroundColor: 'transparent', + }, + });
Flattens an array of style objects, into one aggregated style object. +Alternatively, this method can be used to lookup IDs, returned by +StyleSheet.register.
NOTE: Exercise caution as abusing this can tax you in terms of +optimizations.
IDs enable optimizations through the bridge and memory in general. Refering +to style objects directly will deprive you of these optimizations.
Example:
Alternative use:
This method internally uses StyleSheetRegistry.getStyleByID(style)
+to resolve style objects represented by IDs. Thus, an array of style
+objects (instances of StyleSheet.create), are individually resolved to,
+their respective objects, merged as one and then returned. This also explains
+the alternative use.
Improve this page by sending a pull request!
Renders a boolean input.
This is a controlled component that requires an onValueChange callback that
+updates the value prop in order for the component to reflect user actions.
+If the value prop is not updated, the component will continue to render
+the supplied value prop instead of the expected result of any user actions.
@keyword checkbox +@keyword toggle
If true the user won't be able to toggle the switch. +Default value is false.
Invoked with the new value when the value changes.
Used to locate this view in end-to-end tests.
Border color on iOS and background color on Android when the switch is turned off.
The value of the switch. If true the switch will be turned on. +Default value is false.
Improve this page by sending a pull request!
beginEvent/endEvent for starting and then ending a profile within the same call stack frame
beginAsyncEvent/endAsyncEvent for starting and then ending a profile where the end can either +occur on another thread or out of the current stack frame, eg await +the returned cookie variable should be used as input into the endAsyncEvent call to end the profile
counterEvent registers the value to the profileName on the systrace timeline
Relay profiles use await calls, so likely occur out of current stack frame +therefore async variant of profiling is used
This is not called by default due to perf overhead but it's useful +if you want to find traces which spend too much time in JSON.
Measures multiple methods of a class. For example, you can do: +Systrace.measureMethods(JSON, 'JSON', ['parse', 'stringify']);
@param object +@param objectName +@param methodNames Map from method names to method display names.
Returns an profiled version of the input function. For example, you can: +JSON.parse = Systrace.measure('JSON', 'parse', JSON.parse);
@param objName +@param fnName +@param {function} func +@return {function} replacement function
Improve this page by sending a pull request!
Little red bubble that sits at the top right of the icon.
A custom icon for the tab. It is ignored when a system icon is defined.
Callback when this tab is being selected, you should change the state of your +component to set selected={true}.
If set to true it renders the image as original, +it defaults to being displayed as a template
It specifies whether the children are visible or not. If you see a +blank content, you probably forgot to add a selected one.
A custom icon when the tab is selected. It is ignored when a system +icon is defined. If left empty, the icon will be tinted in blue.
React style object.
Items comes with a few predefined system icons. Note that if you are +using them, the title and selectedIcon will be overridden with the +system ones.
Text that appears under the icon. It is ignored when a system icon +is defined.
(Apple TV only)* When set to true, this view will be focusable +and navigable using the Apple TV remote.
Improve this page by sending a pull request!
The style of the tab bar. Supported values are 'default', 'black'.
+Use 'black' instead of setting barTintColor to black. This produces
+a tab bar with the native iOS style with higher translucency.
Specifies tab bar item positioning. Available values are:
+- fill - distributes items across the entire width of the tab bar
+- center - centers item in the available tab bar space
+- auto (default) - distributes items dynamically according to the
+user interface idiom. In a horizontally compact environment (e.g. iPhone 5)
+this value defaults to fill, in a horizontally regular one (e.g. iPad)
+it defaults to center.
A Boolean value that indicates whether the tab bar is translucent
Improve this page by sending a pull request!
This document is about testing your changes to React Native as a contributor. If you're interested in testing a React Native app, check out the React Native Tutorial on the Jest website.
The React Native repo has several tests you can run to verify you haven't caused a regression with your PR. These tests are run with the Travis and Circle continuous integration systems, which will automatically annotate pull requests with the test results.
Whenever you are fixing a bug or adding new functionality to React Native, you should add a test that covers it. Depending on the change you're making, there are different types of tests that may be appropriate.
Jest tests are JavaScript-only tests run on the command line with node. You can run the existing React Native jest tests with:
It's a good idea to add a Jest test when you are working on a change that only modifies JavaScript code.
The tests themselves live in the __tests__ directories of the files they test. See TouchableHighlight-test.js for a basic example.
You should also make sure your code passes Flow tests. These can be run using:
The Android unit tests do not run in an emulator. They just use a normal Java installation. The default macOS Java install is insufficient, you may need to install Java 8 (JDK8). You can type javac -version in a terminal to see what version you have:
The version string 1.8.x_xxx corresponds to JDK 8.
You also need to install the Buck build tool.
To run the Android unit tests:
It's a good idea to add an Android unit test whenever you are working on code that can be tested by Java code alone. The Android unit tests live under ReactAndroid/src/tests, so you can browse through that directory for good examples of tests.
To run the integration tests, you need to install the Android NDK. See Prerequisites.
You also need to install the Buck build tool.
We recommend running the Android integration tests in an emulator, although you can also use a real Android device. It's a good idea to keep the emulator running with a visible window. That way if your tests stall, you can look at the emulator to debug.
Some devices and some emulator configurations may not work with the tests. We do maintain an emulator configuration that works, as the standard for testing. To run this emulator config:
Once you have an emulator running, to run the integration tests:
The integration tests should only take a few minutes to run on a modern developer machine.
It's a good idea to add an Android integration test whenever you are working on code that needs both JavaScript and Java to be tested in conjunction. The Android integration tests live under ReactAndroid/src/androidTest, so you can browse through that directory for good examples of tests.
React Native provides facilities to make it easier to test integrated components that require both native and JS components to communicate across the bridge. The two main components are RCTTestRunner and RCTTestModule. RCTTestRunner sets up the ReactNative environment and provides facilities to run the tests as XCTestCases in Xcode (runTest:module is the simplest method). RCTTestModule is exported to JS as NativeModules.TestModule.
The tests themselves are written in JS, and must call TestModule.markTestCompleted() when they are done, otherwise the test will timeout and fail. Test failures are primarily indicated by throwing a JS exception. It is also possible to test error conditions with runTest:module:initialProps:expectErrorRegex: or runTest:module:initialProps:expectErrorBlock: which will expect an error to be thrown and verify the error matches the provided criteria.
See the following for example usage and integration points:
You can run integration tests locally with cmd+U in the IntegrationTest and RNTester apps in Xcode, or by running the following in the command line on macOS:
Your Xcode install will come with a variety of Simulators running the latest OS. You may need to manually create a new Simulator to match what the
XCODE_DESTINATIONparam in the test script.
A common type of integration test is the snapshot test. These tests render a component, and verify snapshots of the screen against reference images using TestModule.verifySnapshot(), using the FBSnapshotTestCase library behind the scenes. Reference images are recorded by setting recordMode = YES on the RCTTestRunner, then running the tests. Snapshots will differ slightly between 32 and 64 bit, and various OS versions, so it's recommended that you enforce tests are run with the correct configuration. It's also highly recommended that all network data be mocked out, along with other potentially troublesome dependencies. See SimpleSnapshotTest for a basic example.
If you make a change that affects a snapshot test in a PR, such as adding a new example case to one of the examples that is snapshotted, you'll need to re-record the snapshot reference image. To do this, simply change to _runner.recordMode = YES; in RNTester/RNTesterSnapshotTests.m, re-run the failing tests, then flip record back to NO and submit/update your PR and wait to see if the Travis build passes.
The same tests discussed above for iOS will also run on tvOS. In the RNTester Xcode project, select the RNTester-tvOS target, and you can follow the same steps above to run the tests in Xcode.
You can run Apple TV unit and integration tests locally by running the following in the command line on macOS:
Finally, make sure end-to-end tests run successfully by executing the following script:
The React Native website is hosted on GitHub pages and is automatically generated from Markdown sources as well as comments in the JavaScript source files. It's always a good idea to check that the website is generated properly whenever you edit the docs.
Then open http://localhost:8079/react-native/index.html in your browser.
Improve this page by sending a pull request!
A React component for displaying text.
Text supports nesting, styling, and touch handling.
In the following example, the nested title and body text will inherit the
+fontFamily from styles.baseText, but the title provides its own
+additional styles. The title and body willstack on top of each other on
+account of the literal newlines:
Both iOS and Android allow you to display formatted text by annotating
+ranges of a string with specific formatting like bold or colored text
+(NSAttributedString on iOS, SpannableString on Android). In practice,
+this is very tedious. For React Native, we decided to use web paradigm for
+this where you can nest text to achieve the same effect.
Behind the scenes, React Native converts this to a flat NSAttributedString
+or SpannableString that contains the following information:
On iOS, you can nest views within your Text component. Here's an example:
In order to use this feature, you must give the view a
widthand aheight.
The <Text> element is special relative to layout: everything inside is no
+longer using the flexbox layout but using text layout. This means that
+elements inside of a <Text> are no longer rectangles, but wrap when they
+see the end of the line.
On the web, the usual way to set a font family and size for the entire +document is to take advantage of inherited CSS properties like so:
All elements in the document will inherit this font unless they or one of +their parents specifies a new rule.
In React Native, we are more strict about it: you must wrap all the text
+nodes inside of a <Text> component. You cannot have a text node directly
+under a <View>.
You also lose the ability to set up a default font for an entire subtree.
+The recommended way to use consistent fonts and sizes across your
+application is to create a component MyAppText that includes them and use
+this component across your app. You can also use this component to make more
+specific components like MyAppHeaderText for other kinds of text.
Assuming that MyAppText is a component that simply renders out its
+children into a Text component with styling, then MyAppHeaderText can be
+defined as follows:
Composing MyAppText in this way ensures that we get the styles from a
+top-level component, but leaves us the ability to add / override them in
+specific use cases.
React Native still has the concept of style inheritance, but limited to text +subtrees. In this case, the second part will be both bold and red.
We believe that this more constrained way to style text will yield better +apps:
(Developer) React components are designed with strong isolation in mind: +You should be able to drop a component anywhere in your application, +trusting that as long as the props are the same, it will look and behave the +same way. Text properties that could inherit from outside of the props would +break this isolation.
(Implementor) The implementation of React Native is also simplified. We do
+not need to have a fontFamily field on every single element, and we do not
+need to potentially traverse the tree up to the root every time we display a
+text node. The style inheritance is only encoded inside of the native Text
+component and doesn't leak to other components or the system itself.
When set to true, indicates that the view is an accessibility element. The default value
+for a Text element is true.
See the +Accessibility guide +for more information.
Specifies whether fonts should scale to respect Text Size accessibility settings. The
+default is true.
When numberOfLines is set, this prop defines how text will be truncated.
+numberOfLines must be set in conjunction with this prop.
This can be one of the following values:
head - The line is displayed so that the end fits in the container and the missing text
+at the beginning of the line is indicated by an ellipsis glyph. e.g., "...wxyz"middle - The line is displayed so that the beginning and end fit in the container and the
+missing text in the middle is indicated by an ellipsis glyph. "ab...yz"tail - The line is displayed so that the beginning fits in the container and the
+missing text at the end of the line is indicated by an ellipsis glyph. e.g., "abcd..."clip - Lines are not drawn past the edge of the text container.The default is tail.
clipis working only for iOS
Used to locate this view from native code.
Used to truncate the text with an ellipsis after computing the text +layout, including line wrapping, such that the total number of lines +does not exceed this number.
This prop is commonly used with ellipsizeMode.
Invoked on mount and layout changes with
{nativeEvent: {layout: {x, y, width, height}}}
This function is called on long press.
e.g., onLongPress={this.increaseSize}>
This function is called on press.
e.g., onPress={() => console.log('1st')}
When the scroll view is disabled, this defines how far your touch may +move off of the button, before deactivating the button. Once deactivated, +try moving it back and you'll see that the button is once again +reactivated! Move it back and forth several times while the scroll view +is disabled. Ensure you pass in a constant to reduce memory allocations.
Lets the user select text, to use the native copy and paste functionality.
Specifies font weight. The values 'normal' and 'bold' are supported for +most fonts. Not all fonts have a variant for each of the numeric values, +in that case the closest one is chosen.
Specifies text alignment. The value 'justify' is only supported on iOS and
+fallbacks to left on Android.
Set to false to remove extra font padding intended to make space for certain ascenders / descenders.
+With some fonts, this padding can make text look slightly misaligned when centered vertically.
+For best results also set textAlignVertical to center. Default is true.
Used to locate this view in end-to-end tests.
Specifies the disabled state of the text view for testing purposes
Set text break strategy on Android API Level 23+, possible values are simple, highQuality, balanced
+The default value is highQuality.
Specifies whether font should be scaled down automatically to fit given style constraints.
Specifies smallest possible scale a font can reach when adjustsFontSizeToFit is enabled. (values 0.01-1.0).
When true, no visual change is made when text is pressed down. By
+default, a gray oval highlights the text on press down.
Improve this page by sending a pull request!
A foundational component for inputting text into the app via a +keyboard. Props provide configurability for several features, such as +auto-correction, auto-capitalization, placeholder text, and different keyboard +types, such as a numeric keypad.
The simplest use case is to plop down a TextInput and subscribe to the
+onChangeText events to read the user input. There are also other events,
+such as onSubmitEditing and onFocus that can be subscribed to. A simple
+example:
Two methods exposed via the native element are .focus() and .blur() that +will focus or blur the TextInput programmatically.
Note that some props are only available with multiline={true/false}.
+Additionally, border styles that apply to only one side of the element
+(e.g., borderBottomColor, borderLeftWidth, etc.) will not be applied if
+multiline=false. To achieve the same effect, you can wrap your TextInput
+in a View:
TextInput has by default a border at the bottom of its view. This border
+has its padding set by the background image provided by the system, and it
+cannot be changed. Solutions to avoid this is to either not set height
+explicitly, case in which the system will take care of displaying the border
+in the correct position, or to not display the border by setting
+underlineColorAndroid to transparent.
Note that on Android performing text selection in input can change
+app's activity windowSoftInputMode param to adjustResize.
+This may cause issues with components that have position: 'absolute'
+while keyboard is active. To avoid this behavior either specify windowSoftInputMode
+in AndroidManifest.xml ( https://developer.android.com/guide/topics/manifest/activity-element.html )
+or control this param programmatically with native code.
Can tell TextInput to automatically capitalize certain characters.
characters: all characters.words: first letter of each word.sentences: first letter of each sentence (default).none: don't auto capitalize anything.If false, disables auto-correct. The default value is true.
If true, focuses the input on componentDidMount.
+The default value is false.
If true, the text field will blur when submitted.
+The default value is true for single-line fields and false for
+multiline fields. Note that for multiline fields, setting blurOnSubmit
+to true means that pressing return will blur the field and trigger the
+onSubmitEditing event instead of inserting a newline into the field.
If true, caret is hidden. The default value is false.
Provides an initial value that will change when the user starts typing. +Useful for simple use-cases where you do not want to deal with listening +to events and updating the value prop to keep the controlled state in sync.
If false, text is not editable. The default value is true.
Determines which keyboard to open, e.g.numeric.
The following values work across platforms:
defaultnumericemail-addressphone-padIf autogrow is true, limits the height that the TextInput box can grow
+to. Once it reaches this height, the TextInput becomes scrollable.
Limits the maximum number of characters that can be entered. Use this +instead of implementing the logic in JS to avoid flicker.
If true, the text input can be multiple lines.
+The default value is false.
Callback that is called when the text input is blurred.
Callback that is called when the text input's text changes.
Callback that is called when the text input's text changes. +Changed text is passed as an argument to the callback handler.
Callback that is called when the text input's content size changes.
+This will be called with
+{ nativeEvent: { contentSize: { width, height } } }.
Only called for multiline text inputs.
Callback that is called when text input ends.
Callback that is called when the text input is focused.
Invoked on mount and layout changes with {x, y, width, height}.
Invoked on content scroll with { nativeEvent: { contentOffset: { x, y } } }.
+May also contain other properties from ScrollEvent but on Android contentSize
+is not provided for performance reasons.
Callback that is called when the text input selection is changed.
+This will be called with
+{ nativeEvent: { selection: { start, end } } }.
Callback that is called when the text input's submit button is pressed.
+Invalid if multiline={true} is specified.
The string that will be rendered before text input has been entered.
Determines how the return key should look. On Android you can also use
+returnKeyLabel.
Cross platform
The following values work across platforms:
donegonextsearchsendAndroid Only
The following values work on Android only:
nonepreviousiOS Only
The following values work on iOS only:
defaultemergency-callgooglejoinrouteyahooIf true, the text input obscures the text entered so that sensitive text
+like passwords stay secure. The default value is false.
If true, all text will automatically be selected on focus.
The start and end of the text input's selection. Set start and end to +the same value to position the cursor.
Note that not all Text styles are supported, +see Issue#7070 +for more detail.
The value to show for the text input. TextInput is a controlled
+component, which means the native value will be forced to match this
+value prop if provided. For most uses, this works great, but in some
+cases this may cause flickering - one common cause is preventing edits
+by keeping value the same. In addition to simply setting the same value,
+either set editable={false}, or set/update maxLength to prevent
+unwanted edits without flicker.
If true, will increase the height of the textbox if need be. If false, +the textbox will become scrollable once the height is reached. The +default value is false.
When false, if there is a small amount of space available around a text input
+(e.g. landscape orientation on a phone), the OS may choose to have the user edit
+the text inside of a full screen text input mode. When true, this feature is
+disabled and users will always edit the text directly inside of the text input.
+Defaults to false.
If defined, the provided image resource will be rendered on the left.
+The image resource must be inside /android/app/src/main/res/drawable and referenced
+like
Padding between the inline image, if any, and the text input itself.
Sets the number of lines for a TextInput. Use it with multiline set to
+true to be able to fill the lines.
Sets the return key to the label. Use it instead of returnKeyType.
Set text break strategy on Android API Level 23+, possible values are simple, highQuality, balanced
+The default value is simple.
When the clear button should appear on the right side of the text view.
If true, clears the text field automatically when editing begins.
Determines the types of data converted to clickable URLs in the text input.
+Only valid if multiline={true} and editable={false}.
+By default no data types are detected.
You can provide one type or an array of many types.
Possible values for dataDetectorTypes are:
'phoneNumber''link''address''calendarEvent''none''all'If true, the keyboard disables the return key when there is no text and
+automatically enables it when there is text. The default value is false.
Determines the color of the keyboard.
Callback that is called when a key is pressed.
+This will be called with { nativeEvent: { key: keyValue } }
+where keyValue is 'Enter' or 'Backspace' for respective keys and
+the typed-in character otherwise including ' ' for space.
+Fires before onChange callbacks.
An instance of DocumentSelectionState, this is some state that is responsible for
+maintaining selection information for a document.
Some functionality that can be performed with this instance is:
blur()focus()update()You can reference
DocumentSelectionStatein +vendor/document/selection/DocumentSelectionState.js
If false, disables spell-check style (i.e. red underlines).
+The default value is inherited from autoCorrect.
Improve this page by sending a pull request!
Specifies font weight. The values 'normal' and 'bold' are supported for +most fonts. Not all fonts have a variant for each of the numeric values, +in that case the closest one is chosen.
Specifies text alignment. The value 'justify' is only supported on iOS and
+fallbacks to left on Android.
Set to false to remove extra font padding intended to make space for certain ascenders / descenders.
+With some fonts, this padding can make text look slightly misaligned when centered vertically.
+For best results also set textAlignVertical to center. Default is true.
Improve this page by sending a pull request!
Opens the standard Android time picker dialog.
Opens the standard Android time picker dialog.
The available keys for the options object are:
+ hour (0-23) - the hour to show, defaults to the current time
+ minute (0-59) - the minute to show, defaults to the current time
+ * is24Hour (boolean) - If true, the picker uses the 24-hour format. If false,
+ the picker shows an AM/PM chooser. If undefined, the default for the current locale
+ is used.
Returns a Promise which will be invoked an object containing action, hour (0-23),
+minute (0-59) if the user picked a time. If the user dismissed the dialog, the Promise will
+still be resolved with action being TimePickerAndroid.dismissedAction and all the other keys
+being undefined. Always check whether the action before reading the values.
A time has been selected.
The dialog has been dismissed.
Improve this page by sending a pull request!
Timers are an important part of an application and React Native implements the browser timers.
requestAnimationFrame(fn) is not the same as setTimeout(fn, 0) - the former will fire after all the frame has flushed, whereas the latter will fire as quickly as possible (over 1000x per second on a iPhone 5S).
setImmediate is executed at the end of the current JavaScript execution block, right before sending the batched response back to native. Note that if you call setImmediate within a setImmediate callback, it will be executed right away, it won't yield back to native in between.
The Promise implementation uses setImmediate as its asynchronicity primitive.
One reason why well-built native apps feel so smooth is by avoiding expensive operations during interactions and animations. In React Native, we currently have a limitation that there is only a single JS execution thread, but you can use InteractionManager to make sure long-running work is scheduled to start after any interactions/animations have completed.
Applications can schedule tasks to run after interactions with the following:
Compare this to other scheduling alternatives:
The touch handling system considers one or more active touches to be an 'interaction' and will delay runAfterInteractions() callbacks until all touches have ended or been cancelled.
InteractionManager also allows applications to register animations by creating an interaction 'handle' on animation start, and clearing it upon completion:
We found out that the primary cause of fatals in apps created with React Native was due to timers firing after a component was unmounted. To solve this recurring issue, we introduced TimerMixin. If you include TimerMixin, then you can replace your calls to setTimeout(fn, 500) with this.setTimeout(fn, 500) (just prepend this.) and everything will be properly cleaned up for you when the component unmounts.
This library does not ship with React Native - in order to use it on your project, you will need to install it with npm i react-timer-mixin --save from your project directory.
This will eliminate a lot of hard work tracking down bugs, such as crashes caused by timeouts firing after a component has been unmounted.
Keep in mind that if you use ES6 classes for your React components there is no built-in API for mixins. To use TimerMixin with ES6 classes, we recommend react-mixin.
Improve this page by sending a pull request!
This exposes the native ToastAndroid module as a JS module. This has a function 'show' +which takes the following parameters:
There is also a function showWithGravity to specify the layout gravity. May be
+ToastAndroid.TOP, ToastAndroid.BOTTOM, ToastAndroid.CENTER.
The 'showWithGravityWithOffset' function adds on the ability to specify offset +These offset values will translate to pixels.
Basic usage:
Improve this page by sending a pull request!
React component that wraps the Android-only Toolbar widget. A Toolbar can display a logo,
+navigation icon (e.g. hamburger menu), a title & subtitle and a list of actions. The title and
+subtitle are expanded so the logo and navigation icons are displayed on the left, title and
+subtitle in the middle and the actions on the right.
If the toolbar has an only child, it will be displayed between the title and actions.
Although the Toolbar supports remote images for the logo, navigation and action icons, this
+should only be used in DEV mode where require('./some_icon.png') translates into a packager
+URL. In release mode you should always use a drawable resource for these icons. Using
+require('./some_icon.png') will do this automatically for you, so as long as you don't
+explicitly use e.g. {uri: 'http://...'}, you will be good.
Example:
Sets possible actions on the toolbar as part of the action menu. These are displayed as icons +or text on the right side of the widget. If they don't fit they are placed in an 'overflow' +menu.
This property takes an array of objects, where each object has the following keys:
title: required, the title of this actionicon: the icon for this action, e.g. require('./some_icon.png')show: when to show this action as an icon or hide it in the overflow menu: always,
+ifRoom or nevershowWithText: boolean, whether to show text alongside the icon or notSets the content inset for the toolbar ending edge.
The content inset affects the valid area for Toolbar content other than +the navigation button and menu. Insets define the minimum margin for +these components and can be used to effectively align Toolbar content +along well-known gridlines.
Sets the content inset for the toolbar starting edge.
The content inset affects the valid area for Toolbar content other than +the navigation button and menu. Insets define the minimum margin for +these components and can be used to effectively align Toolbar content +along well-known gridlines.
Sets the toolbar logo.
Sets the navigation icon.
Callback that is called when an action is selected. The only argument that is passed to the +callback is the position of the action in the actions array.
Callback called when the icon is selected.
Sets the overflow icon.
Used to set the toolbar direction to RTL. +In addition to this property you need to add
android:supportsRtl="true"
to your application AndroidManifest.xml and then call
+setLayoutDirection(LayoutDirection.RTL) in your MainActivity
+onCreate method.
Sets the toolbar subtitle.
Used to locate this view in end-to-end tests.
Sets the toolbar title.
Improve this page by sending a pull request!
A wrapper for making views respond properly to touches. +On press down, the opacity of the wrapped view is decreased, which allows +the underlay color to show through, darkening or tinting the view.
The underlay comes from wrapping the child in a new View, which can affect +layout, and sometimes cause unwanted visual artifacts if not used correctly, +for example if the backgroundColor of the wrapped view isn't explicitly set +to an opaque color.
TouchableHighlight must have one child (not zero or more than one). +If you wish to have several child components, wrap them in a View.
Example:
Determines what the opacity of the wrapped view should be when touch is +active.
Called immediately after the underlay is hidden
Called immediately after the underlay is shown
(Apple TV only) TV preferred focus (see documentation for the View component).
(Apple TV only) Object with properties to control Apple TV parallax effects.
enabled: If true, parallax effects are enabled. Defaults to true. +shiftDistanceX: Defaults to 2.0. +shiftDistanceY: Defaults to 2.0. +tiltAngle: Defaults to 0.05. +magnification: Defaults to 1.0.
Improve this page by sending a pull request!
A wrapper for making views respond properly to touches (Android only). +On Android this component uses native state drawable to display touch +feedback.
At the moment it only supports having a single View instance as a child +node, as it's implemented by replacing that View with another instance of +RCTView node with some additional properties set.
Background drawable of native feedback touchable can be customized with
+background property.
Example:
Determines the type of background drawable that's going to be used to
+display feedback. It takes an object with type property and extra data
+depending on the type. It's recommended to use one of the static
+methods to generate that dictionary.
Set to true to add the ripple effect to the foreground of the view, instead of the +background. This is useful if one of your child views has a background of its own, or you're +e.g. displaying images, and you don't want the ripple to be covered by them.
Check TouchableNativeFeedback.canUseNativeForeground() first, as this is only available on +Android 6.0 and above. If you try to use this on older versions you will get a warning and +fallback to background.
Creates an object that represents android theme's default background for +selectable elements (?android:attr/selectableItemBackground).
Creates an object that represent android theme's default background for borderless +selectable elements (?android:attr/selectableItemBackgroundBorderless). +Available on android API level 21+.
Creates an object that represents ripple drawable with specified color (as a
+string). If property borderless evaluates to true the ripple will
+render outside of the view bounds (see native actionbar buttons as an
+example of that behavior). This background type is available on Android
+API level 21+.
| Name and Type | Description |
|---|---|
| color string | The ripple color |
| borderless boolean | If the ripple can render outside it's bounds |
Improve this page by sending a pull request!
A wrapper for making views respond properly to touches. +On press down, the opacity of the wrapped view is decreased, dimming it.
Opacity is controlled by wrapping the children in an Animated.View, which is +added to the view hiearchy. Be aware that this can affect layout.
Example:
Determines what the opacity of the wrapped view should be when touch is +active. Defaults to 0.2.
Apple TV parallax effects
Animate the touchable to a new opacity.
Improve this page by sending a pull request!
Do not use unless you have a very good reason. All elements that +respond to press should have a visual feedback when touched.
TouchableWithoutFeedback supports only one child. +If you wish to have several child components, wrap them in a View.
Delay in ms, from onPressIn, before onLongPress is called.
Delay in ms, from the start of the touch, before onPressIn is called.
Delay in ms, from the release of the touch, before onPressOut is called.
If true, disable all interactions for this component.
This defines how far your touch can start away from the button. This is
+added to pressRetentionOffset when moving off of the button.
+ NOTE
+The touch area never extends past the parent view bounds and the Z-index
+of sibling views always takes precedence if a touch hits two overlapping
+views.
Invoked on mount and layout changes with
{nativeEvent: {layout: {x, y, width, height}}}
Called when the touch is released, but not if cancelled (e.g. by a scroll +that steals the responder lock).
Called as soon as the touchable element is pressed and invoked even before onPress. +This can be useful when making network requests.
Called as soon as the touch is released even before onPress.
When the scroll view is disabled, this defines how far your touch may +move off of the button, before deactivating the button. Once deactivated, +try moving it back and you'll see that the button is once again +reactivated! Move it back and forth several times while the scroll view +is disabled. Ensure you pass in a constant to reduce memory allocations.
Improve this page by sending a pull request!
Deprecated. Use the transform prop instead.
transform accepts an array of transformation objects. Each object specifies
+the property that will be transformed as the key, and the value to use in the
+transformation. Objects should not be combined. Use a single key/value pair
+per object.
The rotate transformations require a string so that the transform may be +expressed in degrees (deg) or radians (rad). For example:
transform([{ rotateX: '45deg' }, { rotateZ: '0.785398rad' }])
The skew transformations require a string so that the transform may be +expressed in degrees (deg). For example:
transform([{ skewX: '45deg' }])
Deprecated. Use the transform prop instead.
Improve this page by sending a pull request!
These are some common issues you may run into while setting up React Native. If you encounter something that is not listed here, try searching for the issue in GitHub.
The React Native packager runs on port 8081. If another process is already using that port, you can either terminate that process, or change the port that the packager uses.
Run the following command on a Mac to find the id for the process that is listening on port 8081:
Then run the following to terminate the process:
On Windows you can find the process using port 8081 using Resource Monitor and stop it using Task Manager.
You can configure the packager to use a port other than 8081 by using the port parameter:
You will also need to update your applications to load the JavaScript bundle from the new port. If running on device from Xcode, you can do this by updating occurrences of 8081 to your chosen port in the node_modules/react-native/React/React.xcodeproj/project.pbxproj file.
If you encounter an error such as npm WARN locking Error: EACCES while using the React Native CLI, try running the following:
If you added React Native manually to your project, make sure you have included all the relevant dependencies that you are using, like RCTText.xcodeproj, RCTImage.xcodeproj. Next, the binaries built by these dependencies have to be linked to your app binary. Use the Linked Frameworks and Binaries section in the Xcode project settings. More detailed steps are here: Linking Libraries.
If you are using CocoaPods, verify that you have added React along with the subspecs to the Podfile. For example, if you were using the <Text />, <Image /> and fetch() APIs, you would need to add these in your Podfile:
Next, make sure you have run pod install and that a Pods/ directory has been created in your project with React installed. CocoaPods will instruct you to use the generated .xcworkspace file henceforth to be able to use these installed dependencies.
In the project's build settings, User Search Header Paths and Header Search Paths are two configs that specify where Xcode should look for #import header files specified in the code. For Pods, CocoaPods uses a default array of specific folders to look in. Verify that this particular config is not overwritten, and that none of the folders configured are too large. If one of the folders is a large folder, Xcode will attempt to recursively search the entire directory and throw above error at some point.
To revert the User Search Header Paths and Header Search Paths build settings to their defaults set by CocoaPods - select the entry in the Build Settings panel, and hit delete. It will remove the custom override and return to the CocoaPod defaults.
React Native implements a polyfill for WebSockets. These polyfills are initialized as part of the react-native module that you include in your application through import React from 'react'. If you load another module that requires WebSockets, such as Firebase, be sure to load/require it after react-native:
If you encounter a ShellCommandUnresponsiveException exception such as:
Try downgrading your Gradle version to 1.2.3 in android/build.gradle.
If you run into issues where running react-native init hangs in your system, try running it again in verbose mode and refering to #2797 for common causes:
Issue caused by the number of directories inotify (used by watchman on Linux) can monitor. To solve it, just run this command in your terminal window
Improve this page by sending a pull request!
React Native is like React, but it uses native components instead of web components as building blocks. So to understand the basic structure of a React Native app, you need to understand some of the basic React concepts, like JSX, components, state, and props. If you already know React, you still need to learn some React-Native-specific stuff, like the native components. This
+tutorial is aimed at all audiences, whether you have React experience or not.
Let's do this thing.
In accordance with the ancient traditions of our people, we must first build an app that does nothing except say "Hello world". Here it is:
If you are feeling curious, you can play around with sample code directly in the web simulators. You can also paste it into your App.js file to create a real app on your local machine.
Some of the things in here might not look like JavaScript to you. Don't panic. This is the future.
First of all, ES2015 (also known as ES6) is a set of improvements to JavaScript that is now part of the official standard, but not yet supported by all browsers, so often it isn't used yet in web development. React Native ships with ES2015 support, so you can use this stuff without worrying about compatibility. import, from, class, extends, and the () => syntax in the example above are all ES2015 features. If you aren't familiar with ES2015, you can probably pick it up just by reading through sample code like this tutorial has. If you want, this page has a good overview of ES2015 features.
The other unusual thing in this code example is <Text>Hello world!</Text>. This is JSX - a syntax for embedding XML within JavaScript. Many frameworks use a special templating language which lets you embed code inside markup language. In React, this is reversed. JSX lets you write your markup language inside code. It looks like HTML on the web, except instead of web things like <div> or <span>, you use React components. In this case, <Text>
+is a built-in component that just displays some text.
So this code is defining HelloWorldApp, a new Component. When you're building a React Native app, you'll be making new components a lot. Anything you see on the screen is some sort of component. A component can be pretty simple - the only thing that's required is a render function which returns some JSX to render.
Good point. To make components do more interesting things, you need to learn about Props.
Improve this page by sending a pull request!
Though you may have installed the react-native-cli via npm as a separate module, it is a shell for accessing the CLI embedded
+in the React Native of each project. Your commands and their effects are dependent on the version of the module of react-native
+in context of the project. This guide will give a brief overview of the CLI in the module.
React Native has a local-cli folder with a file named
+cliEntry.js. Here, the commands are read
+from commands.js and added as possible CLI commands. E.G. the react-native link command, exists in the
+react-native/local-cli/link folder, and is
+required in commands.js, which will register it as a documented command to be exposed to the CLI.
At the end of each command entry is an export. The export is an object with a function to perform, description of the command, and the command name. The object structure for the link command looks like so:
The command name identifies the parameters that a command would expect. When the command parameter is surrounded by greater-than, less-than symbols < >, this indicates that the parameter is expected. When a parameter is surrounded by brackets [ ], this indicates that the parameter is optional.
Improve this page by sending a pull request!
Upgrading to new versions of React Native will give you access to more APIs, views, developer tools and other goodies. Upgrading requires a small amount of effort, but we try to make it easy for you. The instructions are a bit different depending on whether you used create-react-native-app or react-native init to create your project.
Upgrading your Create React Native App project to a new version of React Native requires updating the react-native, react, and expo package versions in your package.json file. Please refer to this document to find out what versions are supported. You will also need to set the correct sdkVersion in your app.json file.
See the CRNA user guide for up-to-date information about upgrading your project.
Because React Native projects built with native code are essentially made up of an Android project, an iOS project, and a JavaScript project, upgrading can be rather tricky. Here's what you need to do to upgrade from an older version of React Native.
The module react-native-git-upgrade provides a one-step operation to upgrade the source files with a minimum of conflicts. Under the hood, it consists in 2 phases:
IMPORTANT: You don't have to install the new version of the
react-nativepackage, it will be installed automatically.
While your project does not have to be handled by the Git versioning system -- you can use Mercurial, SVN, or nothing -- you will still need to install Git on your system in order to use react-native-git-upgrade. Git will also need to be available in the PATH.
react-native-git-upgrade module #The react-native-git-upgrade module provides a CLI and must be installed globally:
Run the following command to start the process of upgrading to the latest version:
You may specify a React Native version by passing an argument:
react-native-git-upgrade X.Y
The templates are upgraded in a optimized way. You still may encounter conflicts but only where the Git 3-way merge have failed, depending on the version and how you modified your sources.
Conflicted files include delimiters which make very clear where the changes come from. For example:
You can think of "ours" as "your team" and "theirs" as "the React Native dev team".
Use this only in case the above didn't work.
react-native dependency #Note the latest version of the react-native npm package from here (or use npm info react-native to check).
Now install that version of react-native in your project with npm install --save:
If you saw a warning about the peerDependency, also upgrade react by running:
The new npm package may contain updates to the files that are normally generated when you
+run react-native init, like the iOS and the Android sub-projects.
You may consult rn-diff to see if there were changes in the project template files. +In case there weren't any, simply rebuild the project and continue developing. In case of minor changes, you may update your project manually and rebuild.
If there were major changes, run this in a terminal to get these:
This will check your files against the latest template and perform the following:
Some upgrades require manual steps, e.g. 0.13 to 0.14, or 0.28 to 0.29. Be sure to check the release notes when upgrading so that you can identify any manual changes your particular project may require.
Improve this page by sending a pull request!
React Native provides a suite of components for presenting lists of data. Generally, you'll want to use either FlatList or SectionList.
The FlatList component displays a scrolling list of changing, but similarly structured, data. FlatList works well for long lists of data, where the number of items might change over time. Unlike the more generic ScrollView, the FlatList only renders elements that are currently showing on the screen, not all the elements at once.
The FlatList component requires two props: data and renderItem. data is the source of information for the list. renderItem takes one item from the source and returns a formatted component to render.
This example creates a simple FlatList of hardcoded data. Each item in the data props is rendered as a Text component. The FlatListBasics component then renders the FlatList and all Text components.
If you want to render a set of data broken into logical sections, maybe with section headers, similar to UITableViews on iOS, then a SectionList is the way to go.
One of the most common uses for a list view is displaying data that you fetch from a server. To do that, you will need to learn about networking in React Native.
Improve this page by sending a pull request!
The ScrollView is a generic scrolling container that can host multiple components and views. The scrollable items need not be homogenous, and you can scroll both vertically and horizontally (by setting the horizontal property).
This example creates a vertical ScrollView with both images and text mixed together.
ScrollViews can be configured to allow paging through views using swiping gestures by using the pagingEnabled props. Swiping horizontally between views can also be implemented on Android using the ViewPagerAndroid component.
A ScrollView with a single item can be used to allow the user to zoom content. Set up the maximumZoomScale and minimumZoomScale props and your user will be able to use pinch and expand gestures to zoom in and out.
The ScrollView works best to present a small amount of things of a limited size. All the elements and views of a ScrollView are rendered, even if they are not currently shown on the screen. If you have a long list of more items that can fit on the screen, you should use a FlatList instead. So let's learn about list views next.
Improve this page by sending a pull request!
The Vibration API is exposed at Vibration.vibrate().
+The vibration is asynchronous so this method will return immediately.
There will be no effect on devices that do not support Vibration, eg. the simulator.
Note for Android:
+add <uses-permission android:name="android.permission.VIBRATE"/> to AndroidManifest.xml
Since the vibration duration in iOS is not configurable, so there are some differences with Android.
+In Android, if pattern is a number, it specified the vibration duration in ms. If pattern
+is an array, those odd indices is the vibration duration, while the even one are the separation time.
In iOS, invoking vibrate(duration) will just ignore the duration and vibrate for a fixed time. While the
+pattern array is used to define the duration between each vibration. See below example for more.
Repeatable vibration is also supported, the vibration will repeat with defined pattern until cancel() is called.
Example:
Trigger a vibration with specified pattern.
| Name and Type | Description |
|---|---|
| pattern number | Array<number> | Vibration pattern, accept a number or an array of number. Default to 400ms. |
| repeat boolean | Optional. Repeat vibration pattern until cancel(), default to false. |
Stop vibration
Improve this page by sending a pull request!
NOTE: VibrationIOS is being deprecated. Use Vibration instead.
The Vibration API is exposed at VibrationIOS.vibrate(). On iOS, calling this
+function will trigger a one second vibration. The vibration is asynchronous
+so this method will return immediately.
There will be no effect on devices that do not support Vibration, eg. the iOS +simulator.
Vibration patterns are currently unsupported.
@deprecated
Improve this page by sending a pull request!
The most fundamental component for building a UI, View is a container that supports layout with
+flexbox, style,
+some touch handling, and
+accessibility controls. View maps directly to the
+native view equivalent on whatever platform React Native is running on, whether that is a
+UIView, <div>, android.view, etc.
View is designed to be nested inside other views and can have 0 to many children of any type.
This example creates a View that wraps two colored boxes and a text component in a row with
+padding.
Views are designed to be used withStyleSheetfor clarity +and performance, although inline styles are also supported.
For View responder props (e.g., onResponderMove), the synthetic touch event passed to them
+are of the following form:
nativeEventchangedTouches - Array of all touch events that have changed since the last event.identifier - The ID of the touch.locationX - The X position of the touch, relative to the element.locationY - The Y position of the touch, relative to the element.pageX - The X position of the touch, relative to the root element.pageY - The Y position of the touch, relative to the root element.target - The node id of the element receiving the touch event.timestamp - A time identifier for the touch, useful for velocity calculation.touches - Array of all current touches on the screen.Overrides the text that's read by the screen reader when the user interacts
+with the element. By default, the label is constructed by traversing all the
+children and accumulating all the Text nodes separated by space.
When true, indicates that the view is an accessibility element. By default,
+all the touchable elements are accessible.
This defines how far a touch event can start away from the view. +Typical interface guidelines recommend touch targets that are at least +30 - 40 points/density-independent pixels.
For example, if a touchable view has a height of 20 the touchable height can be extended to
+40 with hitSlop={{top: 10, bottom: 10, left: 0, right: 0}}
The touch area never extends past the parent view bounds and the Z-index +of sibling views always takes precedence if a touch hits two overlapping +views.
Used to locate this view from native classes.
This disables the 'layout-only view removal' optimization for this view!
When accessible is true, the system will try to invoke this function
+when the user performs accessibility tap gesture.
Invoked on mount and layout changes with:
{nativeEvent: { layout: {x, y, width, height}}}
This event is fired immediately once the layout has been calculated, but +the new layout may not yet be reflected on the screen at the time the +event is received, especially if a layout animation is in progress.
When accessible is true, the system will invoke this function when the
+user performs the magic tap gesture.
Does this view want to "claim" touch responsiveness? This is called for every touch move on
+the View when it is not the responder.
View.props.onMoveShouldSetResponder: (event) => [true | false], where event is a
+synthetic touch event as described above.
If a parent View wants to prevent a child View from becoming responder on a move,
+it should have this handler which returns true.
View.props.onMoveShouldSetResponderCapture: (event) => [true | false], where event is a
+synthetic touch event as described above.
The View is now responding for touch events. This is the time to highlight and show the user +what is happening.
View.props.onResponderGrant: (event) => {}, where event is a synthetic touch event as
+described above.
The user is moving their finger.
View.props.onResponderMove: (event) => {}, where event is a synthetic touch event as
+described above.
Another responder is already active and will not release it to that View asking to be
+the responder.
View.props.onResponderReject: (event) => {}, where event is a synthetic touch event as
+described above.
Fired at the end of the touch.
View.props.onResponderRelease: (event) => {}, where event is a synthetic touch event as
+described above.
The responder has been taken from the View. Might be taken by other views after a call to
+onResponderTerminationRequest, or might be taken by the OS without asking (e.g., happens
+with control center/ notification center on iOS)
View.props.onResponderTerminate: (event) => {}, where event is a synthetic touch event as
+described above.
Some other View wants to become responder and is asking this View to release its
+responder. Returning true allows its release.
View.props.onResponderTerminationRequest: (event) => {}, where event is a synthetic touch
+event as described above.
Does this view want to become responder on the start of a touch?
View.props.onStartShouldSetResponder: (event) => [true | false], where event is a
+synthetic touch event as described above.
If a parent View wants to prevent a child View from becoming responder on a touch start,
+it should have this handler which returns true.
View.props.onStartShouldSetResponderCapture: (event) => [true | false], where event is a
+synthetic touch event as described above.
Controls whether the View can be the target of touch events.
'auto': The View can be the target of touch events.'none': The View is never the target of touch events.'box-none': The View is never the target of touch events but it's
+subviews can be. It behaves like if the view had the following classes
+in CSS:'box-only': The view can be the target of touch events but it's
+subviews cannot be. It behaves like if the view had the following classes
+in CSS:Since
pointerEventsdoes not affect layout/appearance, and we are +already deviating from the spec by adding additional modes, we opt to not +includepointerEventsonstyle. On some platforms, we would need to +implement it as aclassNameanyways. Usingstyleor not is an +implementation detail of the platform.
This is a special performance property exposed by RCTView and is useful
+for scrolling content when there are many subviews, most of which are
+offscreen. For this property to be effective, it must be applied to a
+view that contains many subviews that extend outside its bound. The
+subviews must also have overflow: hidden, as should the containing view
+(or one of its superviews).
Used to locate this view in end-to-end tests.
This disables the 'layout-only view removal' optimization for this view!
Indicates to accessibility services to treat UI component like a +native one. Works for Android only.
Possible values are one of:
'none''button''radiobutton_checked''radiobutton_unchecked'Indicates to accessibility services whether the user should be notified +when this view changes. Works for Android API >= 19 only. +Possible values:
'none' - Accessibility services should not announce changes to this view.'polite'- Accessibility services should announce changes to this view.'assertive' - Accessibility services should interrupt ongoing speech to immediately announce changes to this view.See the Android View docs
+for reference.
Views that are only used to layout their children or otherwise don't draw
+anything may be automatically removed from the native hierarchy as an
+optimization. Set this property to false to disable this optimization and
+ensure that this View exists in the native view hierarchy.
Controls how view is important for accessibility which is if it +fires accessibility events and if it is reported to accessibility services +that query the screen. Works for Android only.
Possible values:
'auto' - The system determines whether the view is important for accessibility -
+default (recommended).'yes' - The view is important for accessibility.'no' - The view is not important for accessibility.'no-hide-descendants' - The view is not important for accessibility,
+nor are any of its descendant views.See the Android importantForAccessibility docs
+for reference.
Whether this View needs to rendered offscreen and composited with an alpha
+in order to preserve 100% correct colors and blending behavior. The default
+(false) falls back to drawing the component and its children with an alpha
+applied to the paint used to draw each element instead of rendering the full
+component offscreen and compositing it back with an alpha value. This default
+may be noticeable and undesired in the case where the View you are setting
+an opacity on has multiple overlapping elements (e.g. multiple overlapping
+Views, or text and a background).
Rendering offscreen to preserve correct alpha behavior is extremely +expensive and hard to debug for non-native developers, which is why it is +not turned on by default. If you do need to enable this property for an +animation, consider combining it with renderToHardwareTextureAndroid if the +view contents are static (i.e. it doesn't need to be redrawn each frame). +If that property is enabled, this View will be rendered off-screen once, +saved in a hardware texture, and then composited onto the screen with an alpha +each frame without having to switch rendering targets on the GPU.
Whether this View should render itself (and all of its children) into a
+single hardware texture on the GPU.
On Android, this is useful for animations and interactions that only +modify opacity, rotation, translation, and/or scale: in those cases, the +view doesn't have to be redrawn and display lists don't need to be +re-executed. The texture can just be re-used and re-composited with +different parameters. The downside is that this can use up limited video +memory, so this prop should be set back to false at the end of the +interaction/animation.
Provides additional traits to screen reader. By default no traits are +provided unless specified otherwise in element.
You can provide one trait or an array of many traits.
Possible values for AccessibilityTraits are:
'none' - The element has no traits.'button' - The element should be treated as a button.'link' - The element should be treated as a link.'header' - The element is a header that divides content into sections.'search' - The element should be treated as a search field.'image' - The element should be treated as an image.'selected' - The element is selected.'plays' - The element plays sound.'key' - The element should be treated like a keyboard key.'text' - The element should be treated as text.'summary' - The element provides app summary information.'disabled' - The element is disabled.'frequentUpdates' - The element frequently changes its value.'startsMedia' - The element starts a media session.'adjustable' - The element allows adjustment over a range of values.'allowsDirectInteraction' - The element allows direct touch interaction for VoiceOver users.'pageTurn' - Informs VoiceOver that it should scroll to the next page when it finishes reading the contents of the element.See the Accessibility guide +for more information.
A value indicating whether VoiceOver should ignore the elements
+within views that are siblings of the receiver.
+Default is false.
See the Accessibility guide +for more information.
Whether this View should be rendered as a bitmap before compositing.
On iOS, this is useful for animations and interactions that do not +modify this component's dimensions nor its children; for example, when +translating the position of a static view, rasterization allows the +renderer to reuse a cached bitmap of a static view and quickly composite +it during each frame.
Rasterization incurs an off-screen drawing pass and the bitmap consumes +memory. Test and measure when using this property.
Improve this page by sending a pull request!
Container that allows to flip left and right between child views. Each
+child view of the ViewPagerAndroid will be treated as a separate page
+and will be stretched to fill the ViewPagerAndroid.
It is important all children are <View>s and not composite components.
+You can set style properties like padding or backgroundColor for each
+child.
Example:
Index of initial page that should be selected. Use setPage method to
+update the page, and onPageSelected to monitor page changes
Determines whether the keyboard gets dismissed in response to a drag. + - 'none' (the default), drags do not dismiss the keyboard. + - 'on-drag', the keyboard is dismissed when a drag begins.
Executed when transitioning between pages (ether because of animation for
+the requested page change or when user is swiping/dragging between pages)
+The event.nativeEvent object for this callback will carry following data:
+ - position - index of first page from the left that is currently visible
+ - offset - value from range [0,1) describing stage between page transitions.
+ Value x means that (1 - x) fraction of the page at "position" index is
+ visible, and x fraction of the next page is visible.
Function called when the page scrolling state has changed. +The page scrolling state can be in 3 states: +- idle, meaning there is no interaction with the page scroller happening at the time +- dragging, meaning there is currently an interaction with the page scroller +- settling, meaning that there was an interaction with the page scroller, and the + page scroller is now finishing it's closing or opening animation
This callback will be called once ViewPager finish navigating to selected page
+(when user swipes between pages). The event.nativeEvent object passed to this
+callback will have following fields:
+ - position - index of page that has been selected
Blank space to show between pages. This is only visible while scrolling, pages are still +edge-to-edge.
Whether enable showing peekFraction or not. If this is true, the preview of +last and next page will show in current screen. Defaults to false.
When false, the content does not scroll. +The default value is true.
Improve this page by sending a pull request!
Overrides the text that's read by the screen reader when the user interacts
+with the element. By default, the label is constructed by traversing all the
+children and accumulating all the Text nodes separated by space.
When true, indicates that the view is an accessibility element. By default,
+all the touchable elements are accessible.
This defines how far a touch event can start away from the view. +Typical interface guidelines recommend touch targets that are at least +30 - 40 points/density-independent pixels.
For example, if a touchable view has a height of 20 the touchable height can be extended to
+40 with hitSlop={{top: 10, bottom: 10, left: 0, right: 0}}
The touch area never extends past the parent view bounds and the Z-index +of sibling views always takes precedence if a touch hits two overlapping +views.
Used to locate this view from native classes.
This disables the 'layout-only view removal' optimization for this view!
When accessible is true, the system will try to invoke this function
+when the user performs accessibility tap gesture.
Invoked on mount and layout changes with:
{nativeEvent: { layout: {x, y, width, height}}}
This event is fired immediately once the layout has been calculated, but +the new layout may not yet be reflected on the screen at the time the +event is received, especially if a layout animation is in progress.
When accessible is true, the system will invoke this function when the
+user performs the magic tap gesture.
Does this view want to "claim" touch responsiveness? This is called for every touch move on
+the View when it is not the responder.
View.props.onMoveShouldSetResponder: (event) => [true | false], where event is a
+synthetic touch event as described above.
If a parent View wants to prevent a child View from becoming responder on a move,
+it should have this handler which returns true.
View.props.onMoveShouldSetResponderCapture: (event) => [true | false], where event is a
+synthetic touch event as described above.
The View is now responding for touch events. This is the time to highlight and show the user +what is happening.
View.props.onResponderGrant: (event) => {}, where event is a synthetic touch event as
+described above.
The user is moving their finger.
View.props.onResponderMove: (event) => {}, where event is a synthetic touch event as
+described above.
Another responder is already active and will not release it to that View asking to be
+the responder.
View.props.onResponderReject: (event) => {}, where event is a synthetic touch event as
+described above.
Fired at the end of the touch.
View.props.onResponderRelease: (event) => {}, where event is a synthetic touch event as
+described above.
The responder has been taken from the View. Might be taken by other views after a call to
+onResponderTerminationRequest, or might be taken by the OS without asking (e.g., happens
+with control center/ notification center on iOS)
View.props.onResponderTerminate: (event) => {}, where event is a synthetic touch event as
+described above.
Some other View wants to become responder and is asking this View to release its
+responder. Returning true allows its release.
View.props.onResponderTerminationRequest: (event) => {}, where event is a synthetic touch
+event as described above.
Does this view want to become responder on the start of a touch?
View.props.onStartShouldSetResponder: (event) => [true | false], where event is a
+synthetic touch event as described above.
If a parent View wants to prevent a child View from becoming responder on a touch start,
+it should have this handler which returns true.
View.props.onStartShouldSetResponderCapture: (event) => [true | false], where event is a
+synthetic touch event as described above.
Controls whether the View can be the target of touch events.
'auto': The View can be the target of touch events.'none': The View is never the target of touch events.'box-none': The View is never the target of touch events but it's
+subviews can be. It behaves like if the view had the following classes
+in CSS:'box-only': The view can be the target of touch events but it's
+subviews cannot be. It behaves like if the view had the following classes
+in CSS:Since
pointerEventsdoes not affect layout/appearance, and we are +already deviating from the spec by adding additional modes, we opt to not +includepointerEventsonstyle. On some platforms, we would need to +implement it as aclassNameanyways. Usingstyleor not is an +implementation detail of the platform.
This is a special performance property exposed by RCTView and is useful
+for scrolling content when there are many subviews, most of which are
+offscreen. For this property to be effective, it must be applied to a
+view that contains many subviews that extend outside its bound. The
+subviews must also have overflow: hidden, as should the containing view
+(or one of its superviews).
Used to locate this view in end-to-end tests.
This disables the 'layout-only view removal' optimization for this view!
Indicates to accessibility services to treat UI component like a +native one. Works for Android only.
Possible values are one of:
'none''button''radiobutton_checked''radiobutton_unchecked'Indicates to accessibility services whether the user should be notified +when this view changes. Works for Android API >= 19 only. +Possible values:
'none' - Accessibility services should not announce changes to this view.'polite'- Accessibility services should announce changes to this view.'assertive' - Accessibility services should interrupt ongoing speech to immediately announce changes to this view.See the Android View docs
+for reference.
Views that are only used to layout their children or otherwise don't draw
+anything may be automatically removed from the native hierarchy as an
+optimization. Set this property to false to disable this optimization and
+ensure that this View exists in the native view hierarchy.
Controls how view is important for accessibility which is if it +fires accessibility events and if it is reported to accessibility services +that query the screen. Works for Android only.
Possible values:
'auto' - The system determines whether the view is important for accessibility -
+default (recommended).'yes' - The view is important for accessibility.'no' - The view is not important for accessibility.'no-hide-descendants' - The view is not important for accessibility,
+nor are any of its descendant views.See the Android importantForAccessibility docs
+for reference.
Whether this View needs to rendered offscreen and composited with an alpha
+in order to preserve 100% correct colors and blending behavior. The default
+(false) falls back to drawing the component and its children with an alpha
+applied to the paint used to draw each element instead of rendering the full
+component offscreen and compositing it back with an alpha value. This default
+may be noticeable and undesired in the case where the View you are setting
+an opacity on has multiple overlapping elements (e.g. multiple overlapping
+Views, or text and a background).
Rendering offscreen to preserve correct alpha behavior is extremely +expensive and hard to debug for non-native developers, which is why it is +not turned on by default. If you do need to enable this property for an +animation, consider combining it with renderToHardwareTextureAndroid if the +view contents are static (i.e. it doesn't need to be redrawn each frame). +If that property is enabled, this View will be rendered off-screen once, +saved in a hardware texture, and then composited onto the screen with an alpha +each frame without having to switch rendering targets on the GPU.
Whether this View should render itself (and all of its children) into a
+single hardware texture on the GPU.
On Android, this is useful for animations and interactions that only +modify opacity, rotation, translation, and/or scale: in those cases, the +view doesn't have to be redrawn and display lists don't need to be +re-executed. The texture can just be re-used and re-composited with +different parameters. The downside is that this can use up limited video +memory, so this prop should be set back to false at the end of the +interaction/animation.
Provides additional traits to screen reader. By default no traits are +provided unless specified otherwise in element.
You can provide one trait or an array of many traits.
Possible values for AccessibilityTraits are:
'none' - The element has no traits.'button' - The element should be treated as a button.'link' - The element should be treated as a link.'header' - The element is a header that divides content into sections.'search' - The element should be treated as a search field.'image' - The element should be treated as an image.'selected' - The element is selected.'plays' - The element plays sound.'key' - The element should be treated like a keyboard key.'text' - The element should be treated as text.'summary' - The element provides app summary information.'disabled' - The element is disabled.'frequentUpdates' - The element frequently changes its value.'startsMedia' - The element starts a media session.'adjustable' - The element allows adjustment over a range of values.'allowsDirectInteraction' - The element allows direct touch interaction for VoiceOver users.'pageTurn' - Informs VoiceOver that it should scroll to the next page when it finishes reading the contents of the element.See the Accessibility guide +for more information.
A value indicating whether VoiceOver should ignore the elements
+within views that are siblings of the receiver.
+Default is false.
See the Accessibility guide +for more information.
Whether this View should be rendered as a bitmap before compositing.
On iOS, this is useful for animations and interactions that do not +modify this component's dimensions nor its children; for example, when +translating the position of a static view, rasterization allows the +renderer to reuse a cached bitmap of a static view and quickly composite +it during each frame.
Rasterization incurs an off-screen drawing pass and the bitmap consumes +memory. Test and measure when using this property.
Improve this page by sending a pull request!
(Android-only) Sets the elevation of a view, using Android's underlying +elevation API. +This adds a drop shadow to the item and affects z-order for overlapping views. +Only supported on Android 5.0+, has no effect on earlier versions.
Improve this page by sending a pull request!
Base implementation for the more convenient <FlatList>
+and <SectionList> components, which are also better
+documented. In general, this should only really be used if you need more flexibility than
+FlatList provides, e.g. for use with immutable data instead of plain arrays.
Virtualization massively improves memory consumption and performance of large lists by +maintaining a finite render window of active items and replacing all items outside of the render +window with appropriately sized blank space. The window adapts to scrolling behavior, and items +are rendered incrementally with low-pri (after any running interactions) if they are far from the +visible area, or with hi-pri otherwise to minimize the potential of seeing blank space.
Some caveats:
PureComponent which means that it will not re-render if props remain shallow-
+equal. Make sure that everything your renderItem function depends on is passed as a prop
+(e.g. extraData) that is not === after updates, otherwise your UI may not update on
+changes. This includes the data prop and parent component state.key prop on each item and uses that for the React key.
+Alternatively, you can provide a custom keyExtractor prop.Scroll to a specific content pixel offset in the list.
Param offset expects the offset to scroll to.
+In case of horizontal is true, the offset is the x-value,
+in any other case the offset is the y-value.
Param animated (true by default) defines whether the list
+should do an animation while scrolling.
Improve this page by sending a pull request!
WebView renders web content in a native view.
You can use this component to navigate back and forth in the web view's +history and configure various properties for the web content.
Controls whether to adjust the content inset for web views that are
+placed behind a navigation bar, tab bar, or toolbar. The default value
+is true.
The amount by which the web view content is inset from the edges of +the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.
DeprecatedUse the source prop instead.
Function that accepts a string that will be passed to the WebView and +executed immediately as JavaScript.
Set this to provide JavaScript that will be injected into the web page +when the view loads.
Boolean that determines whether HTML5 audio and video requires the user
+to tap them before they start playing. The default value is true.
Function that is invoked when the WebView load fails.
Function that is invoked when the WebView has finished loading.
Function that is invoked when the WebView load succeeds or fails.
Function that is invoked when the WebView starts loading.
A function that is invoked when the webview calls window.postMessage.
+Setting this property will inject a postMessage global into your
+webview, but will still call pre-existing values of postMessage.
window.postMessage accepts one argument, data, which will be
+available on the event object, event.nativeEvent.data. data
+must be a string.
Function that is invoked when the WebView loading starts or ends.
Function that returns a view to show if there's an error.
Function that returns a loading indicator.
Boolean that controls whether the web content is scaled to fit
+the view and enables the user to change the scale. The default value
+is true.
Loads static html or a uri (with optional headers) in the WebView.
Boolean value that forces the WebView to show the loading view
+on the first load.
The style to apply to the WebView.
DeprecatedUse the source prop instead.
Boolean value to control whether DOM Storage is enabled. Used only in +Android.
Boolean value to enable JavaScript in the WebView. Used on Android only
+as JavaScript is enabled by default on iOS. The default value is true.
Specifies the mixed content mode. i.e WebView will allow a secure origin to load content from any other origin.
Possible values for mixedContentMode are:
'never' (default) - WebView will not allow a secure origin to load content from an insecure origin.'always' - WebView will allow a secure origin to load content from any other origin, even if that origin is insecure.'compatibility' - WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content.Boolean value to enable third party cookies in the WebView. Used on
+Android Lollipop and above only as third party cookies are enabled by
+default on Android Kitkat and below and on iOS. The default value is true.
Sets the user-agent for the WebView.
Boolean that determines whether HTML5 videos play inline or use the
+native full-screen controller. The default value is false.
NOTE : In order for video to play inline, not only does this
+property need to be set to true, but the video element in the HTML
+document must also include the webkit-playsinline attribute.
Boolean value that determines whether the web view bounces
+when it reaches the edge of the content. The default value is true.
Determines the types of data converted to clickable URLs in the web view’s content. +By default only phone numbers are detected.
You can provide one type or an array of many types.
Possible values for dataDetectorTypes are:
'phoneNumber''link''address''calendarEvent''none''all'A floating-point number that determines how quickly the scroll view
+decelerates after the user lifts their finger. You may also use the
+string shortcuts "normal" and "fast" which match the underlying iOS
+settings for UIScrollViewDecelerationRateNormal and
+UIScrollViewDecelerationRateFast respectively:
Function that allows custom handling of any web view requests. Return
+true from the function to continue loading the request and false
+to stop loading.
Boolean value that determines whether scrolling is enabled in the
+WebView. The default value is true.
Improve this page by sending a pull request!
React Native lets you build mobile apps using only JavaScript. It uses the same design as React, letting you compose a rich mobile UI from declarative components.
With React Native, you don't build a “mobile web app”, an “HTML5 app”, or a “hybrid app”. You build a real mobile app that's indistinguishable from an app built using Objective-C or Java. React Native uses the same fundamental UI building blocks as regular iOS and Android apps. You just put those building blocks together using JavaScript and React.
React Native lets you build your app faster. Instead of recompiling, you can reload your app instantly. With Hot Reloading, you can even run new code while retaining your application state. Give it a try - it's a magical experience.

React Native combines smoothly with components written in Objective-C, Java, or Swift. It's simple to drop down to native code if you need to optimize a few aspects of your application. It's also easy to build part of your app in React Native, and part of your app using native code directly - that's how the Facebook app works.
Thousands of apps are using React Native, from established Fortune 500 companies to hot new startups. If you're curious to see what can be accomplished with React Native, check out these apps!