mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Deploy website
Deploy website version based on 202d3868d7bcab9e98e802ab148ba08bd0d7ef34
This commit is contained in:
@@ -49,10 +49,10 @@
|
||||
<p>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.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitylabel-ios-android"></a><a href="#accessibilitylabel-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityLabel (iOS, Android)</h4>
|
||||
<p>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.</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View:</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel={'Tap me!'}
|
||||
accessibilityLabel="Tap me!"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Press me!</Text>
|
||||
@@ -60,7 +60,55 @@
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>In the above example, the <code>accessibilityLabel</code> on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityhint-ios-android"></a><a href="#accessibilityhint-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityHint (iOS, Android)</h4>
|
||||
<p>An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label.</p>
|
||||
<p>To use, set the <code>accessibilityHint</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel="Go back"
|
||||
accessibilityHint="Navigates to the previous screen"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Back</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>iOS In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for accessibilityHint in the <a href="https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint">iOS Developer Docs</a></p>
|
||||
<p>Android In the above example, Talkback will read the hint after the label. At this time, hints cannot be turned off on Android.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityignoresinvertcolorsios"></a><a href="#accessibilityignoresinvertcolorsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityIgnoresInvertColors(iOS)</h4>
|
||||
<p>Inverting screen colors is an Accessibility feature that makes the iPhone and iPad easier on the eyes for some people with a sensitivity to brightness, easier to distinguish for some people with color blindness, and easier to make out for some people with low vision. However, sometimes you have views such as photos that you don't want to be inverted. In this case, you can set this property to be false so that these specific views won't have their colors inverted.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityrole-ios-android"></a><a href="#accessibilityrole-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityRole (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> Accessibility Role and Accessibility States are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. To use, set the <code>accessibilityRole</code> property to one of the following strings:</p>
|
||||
<ul>
|
||||
<li><strong>none</strong> Used when the element has no role.</li>
|
||||
<li><strong>button</strong> Used when the element should be treated as a button.</li>
|
||||
<li><strong>link</strong> Used when the element should be treated as a link.</li>
|
||||
<li><strong>search</strong> Used when the text field element should also be treated as a search field.</li>
|
||||
<li><strong>image</strong> Used when the element should be treated as an image. Can be combined with button or link, for example.</li>
|
||||
<li><strong>keyboardkey</strong> Used when the element acts as a keyboard key.</li>
|
||||
<li><strong>text</strong> Used when the element should be treated as static text that cannot change.</li>
|
||||
<li><strong>adjustable</strong> Used when an element can be "adjusted" (e.g. a slider).</li>
|
||||
<li><strong>imagebutton</strong> Used when the element should be treated as a button and is also an image.</li>
|
||||
<li><strong>header</strong> Used when an element acts as a header for a content section (e.g. the title of a navigation bar).</li>
|
||||
<li><strong>summary</strong> Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitystate-ios-android"></a><a href="#accessibilitystate-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityState (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityRole</code> and <code>accessibilityStates</code> are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. The state of the element can be set either to <code>selected</code> or <code>disabled</code> or both:</p>
|
||||
<ul>
|
||||
<li><strong>selected</strong> Used when the element is in a selected state. For example, a button is selected.</li>
|
||||
<li><strong>disabled</strong> Used when the element is disabled and cannot be interacted with.</li>
|
||||
</ul>
|
||||
<p>To use, set the <code>accessibilityState</code> to an array containing either <code>selected</code>, <code>disabled</code>, or both.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitytraits-ios"></a><a href="#accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityTraits (iOS)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> <code>accessibilityTraits</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>accessibilityTraits</code>.</p>
|
||||
<p>To use, set the <code>accessibilityTraits</code> property to one of (or an array of) accessibility trait strings:</p>
|
||||
<ul>
|
||||
@@ -93,6 +141,9 @@
|
||||
<h4><a class="anchor" aria-hidden="true" id="onmagictap-ios"></a><a href="#onmagictap-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>onMagicTap (iOS)</h4>
|
||||
<p>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 <code>onMagicTap</code> function, the system will traverse up the view hierarchy until it finds a view that does.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitycomponenttype-android"></a><a href="#accessibilitycomponenttype-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityComponentType (Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityComponentType</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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. We support 'none', ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’.</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableWithoutFeedback accessibilityComponentType=”button”
|
||||
onPress={this._onPress}>
|
||||
@@ -155,7 +206,7 @@ _onPress: <span class="hljs-function"><span class="hljs-keyword">function</span>
|
||||
}
|
||||
|
||||
<CustomRadioButton
|
||||
accessibleComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
accessibilityComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
onPress={<span class="hljs-keyword">this</span>._onPress}/>
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
<p>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.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitylabel-ios-android"></a><a href="#accessibilitylabel-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityLabel (iOS, Android)</h4>
|
||||
<p>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.</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View:</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel={'Tap me!'}
|
||||
accessibilityLabel="Tap me!"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Press me!</Text>
|
||||
@@ -60,7 +60,55 @@
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>In the above example, the <code>accessibilityLabel</code> on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityhint-ios-android"></a><a href="#accessibilityhint-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityHint (iOS, Android)</h4>
|
||||
<p>An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label.</p>
|
||||
<p>To use, set the <code>accessibilityHint</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel="Go back"
|
||||
accessibilityHint="Navigates to the previous screen"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Back</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>iOS In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for accessibilityHint in the <a href="https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint">iOS Developer Docs</a></p>
|
||||
<p>Android In the above example, Talkback will read the hint after the label. At this time, hints cannot be turned off on Android.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityignoresinvertcolorsios"></a><a href="#accessibilityignoresinvertcolorsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityIgnoresInvertColors(iOS)</h4>
|
||||
<p>Inverting screen colors is an Accessibility feature that makes the iPhone and iPad easier on the eyes for some people with a sensitivity to brightness, easier to distinguish for some people with color blindness, and easier to make out for some people with low vision. However, sometimes you have views such as photos that you don't want to be inverted. In this case, you can set this property to be false so that these specific views won't have their colors inverted.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityrole-ios-android"></a><a href="#accessibilityrole-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityRole (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> Accessibility Role and Accessibility States are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. To use, set the <code>accessibilityRole</code> property to one of the following strings:</p>
|
||||
<ul>
|
||||
<li><strong>none</strong> Used when the element has no role.</li>
|
||||
<li><strong>button</strong> Used when the element should be treated as a button.</li>
|
||||
<li><strong>link</strong> Used when the element should be treated as a link.</li>
|
||||
<li><strong>search</strong> Used when the text field element should also be treated as a search field.</li>
|
||||
<li><strong>image</strong> Used when the element should be treated as an image. Can be combined with button or link, for example.</li>
|
||||
<li><strong>keyboardkey</strong> Used when the element acts as a keyboard key.</li>
|
||||
<li><strong>text</strong> Used when the element should be treated as static text that cannot change.</li>
|
||||
<li><strong>adjustable</strong> Used when an element can be "adjusted" (e.g. a slider).</li>
|
||||
<li><strong>imagebutton</strong> Used when the element should be treated as a button and is also an image.</li>
|
||||
<li><strong>header</strong> Used when an element acts as a header for a content section (e.g. the title of a navigation bar).</li>
|
||||
<li><strong>summary</strong> Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitystate-ios-android"></a><a href="#accessibilitystate-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityState (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityRole</code> and <code>accessibilityStates</code> are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. The state of the element can be set either to <code>selected</code> or <code>disabled</code> or both:</p>
|
||||
<ul>
|
||||
<li><strong>selected</strong> Used when the element is in a selected state. For example, a button is selected.</li>
|
||||
<li><strong>disabled</strong> Used when the element is disabled and cannot be interacted with.</li>
|
||||
</ul>
|
||||
<p>To use, set the <code>accessibilityState</code> to an array containing either <code>selected</code>, <code>disabled</code>, or both.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitytraits-ios"></a><a href="#accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityTraits (iOS)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> <code>accessibilityTraits</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>accessibilityTraits</code>.</p>
|
||||
<p>To use, set the <code>accessibilityTraits</code> property to one of (or an array of) accessibility trait strings:</p>
|
||||
<ul>
|
||||
@@ -93,6 +141,9 @@
|
||||
<h4><a class="anchor" aria-hidden="true" id="onmagictap-ios"></a><a href="#onmagictap-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>onMagicTap (iOS)</h4>
|
||||
<p>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 <code>onMagicTap</code> function, the system will traverse up the view hierarchy until it finds a view that does.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitycomponenttype-android"></a><a href="#accessibilitycomponenttype-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityComponentType (Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityComponentType</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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. We support 'none', ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’.</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableWithoutFeedback accessibilityComponentType=”button”
|
||||
onPress={this._onPress}>
|
||||
@@ -155,7 +206,7 @@ _onPress: <span class="hljs-function"><span class="hljs-keyword">function</span>
|
||||
}
|
||||
|
||||
<CustomRadioButton
|
||||
accessibleComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
accessibilityComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
onPress={<span class="hljs-keyword">this</span>._onPress}/>
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For Apple TV · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.10"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For Apple TV · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For TV Devices · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.10"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For TV Devices · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
@@ -33,7 +33,7 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For Apple TV</h1></header><article><div><span><style>
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For TV Devices</h1></header><article><div><span><style>
|
||||
.toggler li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -151,20 +151,20 @@
|
||||
<ul>
|
||||
<li><p><em>General support for tvOS</em>: 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.</p></li>
|
||||
<li><p><em>Common codebase</em>: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.</p></li>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
@@ -222,7 +222,7 @@
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, make a long press on the play/pause button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
<ul>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For Apple TV · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.10"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For Apple TV · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For TV Devices · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.10"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For TV Devices · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
@@ -33,7 +33,7 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For Apple TV</h1></header><article><div><span><style>
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For TV Devices</h1></header><article><div><span><style>
|
||||
.toggler li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -151,20 +151,20 @@
|
||||
<ul>
|
||||
<li><p><em>General support for tvOS</em>: 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.</p></li>
|
||||
<li><p><em>Common codebase</em>: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.</p></li>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
@@ -222,7 +222,7 @@
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, make a long press on the play/pause button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
<ul>
|
||||
|
||||
@@ -63,10 +63,10 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
</code></pre>
|
||||
<h4><a class="anchor" aria-hidden="true" id="download-links-for-android-ndk"></a><a href="#download-links-for-android-ndk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download links for Android NDK</h4>
|
||||
<ol>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip</a></li>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip</a></li>
|
||||
</ol>
|
||||
<p>You can find further instructions on the <a href="https://developer.android.com/ndk/index.html">official page</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="building-the-source"></a><a href="#building-the-source" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Building the source</h3>
|
||||
@@ -79,7 +79,7 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
<p>Add <code>gradle-download-task</code> as dependency in <code>android/build.gradle</code>:</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
<span class="hljs-keyword">dependencies</span> {
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:1.3.1'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:2.3.3'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'de.undercouch:gradle-download-task:3.1.2'</span>
|
||||
|
||||
<span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Do not place your application dependencies here; they belong</span>
|
||||
|
||||
@@ -63,10 +63,10 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
</code></pre>
|
||||
<h4><a class="anchor" aria-hidden="true" id="download-links-for-android-ndk"></a><a href="#download-links-for-android-ndk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download links for Android NDK</h4>
|
||||
<ol>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip</a></li>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip</a></li>
|
||||
</ol>
|
||||
<p>You can find further instructions on the <a href="https://developer.android.com/ndk/index.html">official page</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="building-the-source"></a><a href="#building-the-source" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Building the source</h3>
|
||||
@@ -79,7 +79,7 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
<p>Add <code>gradle-download-task</code> as dependency in <code>android/build.gradle</code>:</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
<span class="hljs-keyword">dependencies</span> {
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:1.3.1'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:2.3.3'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'de.undercouch:gradle-download-task:3.1.2'</span>
|
||||
|
||||
<span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Do not place your application dependencies here; they belong</span>
|
||||
|
||||
@@ -94,11 +94,11 @@ YellowBox.ignoreWarnings([<span class="hljs-string">'Warning: ...'</span>]);
|
||||
<p>Note: if you prefer to avoid global installations, you can add <code>react-devtools</code> as a project dependency. Add the <code>react-devtools</code> package to your project using <code>npm install --save-dev react-devtools</code>, then add <code>"react-devtools": "react-devtools"</code> to the <code>scripts</code> section in your <code>package.json</code>, and then run <code>npm run react-devtools</code> from your project folder to open the DevTools.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" aria-hidden="true" id="integration-with-react-native-inspector"></a><a href="#integration-with-react-native-inspector" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Integration with React Native Inspector</h3>
|
||||
<p>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:</p>
|
||||
<p>Open the in-app developer menu and choose "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:</p>
|
||||
<p><img src="/react-native/docs/assets/Inspector.gif" alt="React Native Inspector"></p>
|
||||
<p>However, when <code>react-devtools</code> 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:</p>
|
||||
<p><img src="/react-native/docs/assets/ReactDevToolsInspector.gif" alt="React DevTools Inspector Integration"></p>
|
||||
<p>You can choose "Hide Inspector" in the same menu to exit this mode.</p>
|
||||
<p>You can choose "Toggle Inspector" in the same menu to exit this mode.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inspecting-component-instances"></a><a href="#inspecting-component-instances" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inspecting Component Instances</h3>
|
||||
<p>When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.</p>
|
||||
<p>First, follow the instructions for debugging in Chrome to open the Chrome console.</p>
|
||||
|
||||
@@ -94,11 +94,11 @@ YellowBox.ignoreWarnings([<span class="hljs-string">'Warning: ...'</span>]);
|
||||
<p>Note: if you prefer to avoid global installations, you can add <code>react-devtools</code> as a project dependency. Add the <code>react-devtools</code> package to your project using <code>npm install --save-dev react-devtools</code>, then add <code>"react-devtools": "react-devtools"</code> to the <code>scripts</code> section in your <code>package.json</code>, and then run <code>npm run react-devtools</code> from your project folder to open the DevTools.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" aria-hidden="true" id="integration-with-react-native-inspector"></a><a href="#integration-with-react-native-inspector" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Integration with React Native Inspector</h3>
|
||||
<p>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:</p>
|
||||
<p>Open the in-app developer menu and choose "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:</p>
|
||||
<p><img src="/react-native/docs/assets/Inspector.gif" alt="React Native Inspector"></p>
|
||||
<p>However, when <code>react-devtools</code> 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:</p>
|
||||
<p><img src="/react-native/docs/assets/ReactDevToolsInspector.gif" alt="React DevTools Inspector Integration"></p>
|
||||
<p>You can choose "Hide Inspector" in the same menu to exit this mode.</p>
|
||||
<p>You can choose "Toggle Inspector" in the same menu to exit this mode.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inspecting-component-instances"></a><a href="#inspecting-component-instances" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inspecting Component Instances</h3>
|
||||
<p>When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.</p>
|
||||
<p>First, follow the instructions for debugging in Chrome to open the Chrome console.</p>
|
||||
|
||||
@@ -72,7 +72,7 @@ render() {
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js">NativeMethodsMixin.js</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react-native/blob/master/Libraries/Renderer/oss/ReactNativeRenderer-prod.js">NativeMethodsMixin</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="composite-components-and-setnativeprops"></a><a href="#composite-components-and-setnativeprops" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Composite components and setNativeProps</h2>
|
||||
<p>Composite components are not backed by a native view, so you cannot call <code>setNativeProps</code> on them. Consider this example:</p>
|
||||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||||
|
||||
@@ -72,7 +72,7 @@ render() {
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js">NativeMethodsMixin.js</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react-native/blob/master/Libraries/Renderer/oss/ReactNativeRenderer-prod.js">NativeMethodsMixin</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="composite-components-and-setnativeprops"></a><a href="#composite-components-and-setnativeprops" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Composite components and setNativeProps</h2>
|
||||
<p>Composite components are not backed by a native view, so you cannot call <code>setNativeProps</code> on them. Consider this example:</p>
|
||||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<p>A useful tool to visualize cubic bezier curves can be found at <a href="http://cubic-bezier.com/">http://cubic-bezier.com/</a></p>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="in"></a><a href="#in" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>in()</code></h3>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span>(easing)
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span> easing;
|
||||
</code></pre>
|
||||
<p>Runs an easing function forwards.</p>
|
||||
<hr>
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<p>A useful tool to visualize cubic bezier curves can be found at <a href="http://cubic-bezier.com/">http://cubic-bezier.com/</a></p>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="in"></a><a href="#in" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>in()</code></h3>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span>(easing)
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span> easing;
|
||||
</code></pre>
|
||||
<p>Runs an easing function forwards.</p>
|
||||
<hr>
|
||||
|
||||
@@ -105,11 +105,11 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
<span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
|
||||
<span class="hljs-attr">flexDirection</span>: <span class="hljs-string">'column'</span>,
|
||||
<span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'stretch'</span>,
|
||||
}}>
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
|
||||
<View style={{height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{height: 100, backgroundColor: 'steelblue'}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'stretch'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%20100%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
|
||||
<h4><a class="anchor" aria-hidden="true" id="going-deeper"></a><a href="#going-deeper" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Going Deeper</h4>
|
||||
<p>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 <a href="/react-native/docs/0.10/layout-props">here</a>.</p>
|
||||
|
||||
@@ -105,11 +105,11 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
<span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
|
||||
<span class="hljs-attr">flexDirection</span>: <span class="hljs-string">'column'</span>,
|
||||
<span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'stretch'</span>,
|
||||
}}>
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
|
||||
<View style={{height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{height: 100, backgroundColor: 'steelblue'}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'stretch'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%20100%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
|
||||
<h4><a class="anchor" aria-hidden="true" id="going-deeper"></a><a href="#going-deeper" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Going Deeper</h4>
|
||||
<p>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 <a href="/react-native/docs/0.10/layout-props">here</a>.</p>
|
||||
|
||||
@@ -260,7 +260,7 @@ npm start
|
||||
</blockquote>
|
||||
<p>Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="2-install-the-android-sdk"></a><a href="#2-install-the-android-sdk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Install the Android SDK</h4>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 6.0 (Marshmallow)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 8.0 (Oreo)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png" alt="Android Studio Welcome"></p>
|
||||
@@ -270,11 +270,9 @@ npm start
|
||||
<blockquote>
|
||||
<p>The SDK Manager can also be found within the Android Studio "Preferences" dialog, under <strong>Appearance & Behavior</strong> → <strong>System Settings</strong> → <strong>Android SDK</strong>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>Android 6.0 (Marshmallow)</code> entry, then make sure the following items are all checked:</p>
|
||||
<p>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 <code>Android 8.0 (Oreo)</code> entry, then make sure the following items are all checked:</p>
|
||||
<ul>
|
||||
<li><code>Google APIs</code></li>
|
||||
<li><code>Android SDK Platform 23</code></li>
|
||||
<li><code>Intel x86 Atom_64 System Image</code></li>
|
||||
<li><code>Android SDK Platform 26</code></li>
|
||||
<li><code>Google APIs Intel x86 Atom_64 System Image</code></li>
|
||||
</ul>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -282,11 +280,11 @@ npm start
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerWindows.png" alt="Android SDK Manager"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>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 <code>23.0.1</code> is selected.</p>
|
||||
<p>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 <code>26.0.3</code> is selected.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>Finally, click "Apply" to download and install the Android SDK and related build tools.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -303,12 +301,14 @@ npm start
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native linux android" /></p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">ANDROID_HOME</span>=<span class="hljs-variable">$HOME</span>/Android/Sdk
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native mac linux android" /></p>
|
||||
<blockquote>
|
||||
@@ -351,7 +351,7 @@ npm start
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-physical-device"></a><a href="#using-a-physical-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a physical device</h3>
|
||||
<p>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 <a href="/react-native/docs/0.10/running-on-device">here</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-virtual-device"></a><a href="#using-a-virtual-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a virtual device</h3>
|
||||
<p>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:</p>
|
||||
<p>If you use Android Studio to open <code>./AwesomeProject/android</code>, 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:</p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioAVD.png" alt="Android Studio AVD Manager"></p>
|
||||
<p>If you have just installed Android Studio, you will likely need to <a href="https://developer.android.com/studio/run/managing-avds.html">create a new AVD</a>. Select "Create Virtual Device...", then pick any Phone from the list and click "Next".</p>
|
||||
<p><block class="native windows android" /></p>
|
||||
@@ -359,7 +359,7 @@ npm start
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedCreateAVDMacOS.png" alt="Android Studio AVD Manager"></p>
|
||||
<p><block class="native mac windows linux android" /></p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Marshmallow</strong> API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.</p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Oreo</strong> API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.</p>
|
||||
<p><block class="native linux android" /></p>
|
||||
<blockquote>
|
||||
<p>We recommend configuring <a href="https://developer.android.com/studio/run/emulator-acceleration.html#vm-linux">VM acceleration</a> on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.</p>
|
||||
|
||||
@@ -260,7 +260,7 @@ npm start
|
||||
</blockquote>
|
||||
<p>Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="2-install-the-android-sdk"></a><a href="#2-install-the-android-sdk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Install the Android SDK</h4>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 6.0 (Marshmallow)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 8.0 (Oreo)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png" alt="Android Studio Welcome"></p>
|
||||
@@ -270,11 +270,9 @@ npm start
|
||||
<blockquote>
|
||||
<p>The SDK Manager can also be found within the Android Studio "Preferences" dialog, under <strong>Appearance & Behavior</strong> → <strong>System Settings</strong> → <strong>Android SDK</strong>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>Android 6.0 (Marshmallow)</code> entry, then make sure the following items are all checked:</p>
|
||||
<p>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 <code>Android 8.0 (Oreo)</code> entry, then make sure the following items are all checked:</p>
|
||||
<ul>
|
||||
<li><code>Google APIs</code></li>
|
||||
<li><code>Android SDK Platform 23</code></li>
|
||||
<li><code>Intel x86 Atom_64 System Image</code></li>
|
||||
<li><code>Android SDK Platform 26</code></li>
|
||||
<li><code>Google APIs Intel x86 Atom_64 System Image</code></li>
|
||||
</ul>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -282,11 +280,11 @@ npm start
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerWindows.png" alt="Android SDK Manager"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>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 <code>23.0.1</code> is selected.</p>
|
||||
<p>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 <code>26.0.3</code> is selected.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>Finally, click "Apply" to download and install the Android SDK and related build tools.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -303,12 +301,14 @@ npm start
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native linux android" /></p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">ANDROID_HOME</span>=<span class="hljs-variable">$HOME</span>/Android/Sdk
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native mac linux android" /></p>
|
||||
<blockquote>
|
||||
@@ -351,7 +351,7 @@ npm start
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-physical-device"></a><a href="#using-a-physical-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a physical device</h3>
|
||||
<p>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 <a href="/react-native/docs/0.10/running-on-device">here</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-virtual-device"></a><a href="#using-a-virtual-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a virtual device</h3>
|
||||
<p>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:</p>
|
||||
<p>If you use Android Studio to open <code>./AwesomeProject/android</code>, 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:</p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioAVD.png" alt="Android Studio AVD Manager"></p>
|
||||
<p>If you have just installed Android Studio, you will likely need to <a href="https://developer.android.com/studio/run/managing-avds.html">create a new AVD</a>. Select "Create Virtual Device...", then pick any Phone from the list and click "Next".</p>
|
||||
<p><block class="native windows android" /></p>
|
||||
@@ -359,7 +359,7 @@ npm start
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedCreateAVDMacOS.png" alt="Android Studio AVD Manager"></p>
|
||||
<p><block class="native mac windows linux android" /></p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Marshmallow</strong> API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.</p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Oreo</strong> API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.</p>
|
||||
<p><block class="native linux android" /></p>
|
||||
<blockquote>
|
||||
<p>We recommend configuring <a href="https://developer.android.com/studio/run/emulator-acceleration.html#vm-linux">VM acceleration</a> on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.</p>
|
||||
|
||||
@@ -99,14 +99,14 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Button Basics"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
@@ -194,14 +194,14 @@ AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
<span class="hljs-attr">padding</span>: <span class="hljs-number">20</span>,
|
||||
<span class="hljs-attr">color</span>: <span class="hljs-string">'white'</span>
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
<span class="hljs-comment">// skip this line if using Create React Native App</span>
|
||||
AppRegistry.registerComponent(<span class="hljs-string">'AwesomeProject'</span>, () => Touchables);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Touchables"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-platform="android"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
@@ -99,14 +99,14 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Button Basics"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
@@ -194,14 +194,14 @@ AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
<span class="hljs-attr">padding</span>: <span class="hljs-number">20</span>,
|
||||
<span class="hljs-attr">color</span>: <span class="hljs-string">'white'</span>
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
<span class="hljs-comment">// skip this line if using Create React Native App</span>
|
||||
AppRegistry.registerComponent(<span class="hljs-string">'AwesomeProject'</span>, () => Touchables);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Touchables"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-platform="android"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<span class="hljs-comment">// do stuff</span>
|
||||
};
|
||||
</code></pre>
|
||||
<p>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).</p>
|
||||
<p>You can do anything in your task such as network requests, timers and so on, as long as it doesn't touch UI. 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).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="the-java-api"></a><a href="#the-java-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>The Java API</h2>
|
||||
<p>Yes, this does still require some native code, but it's pretty thin. You need to extend <code>HeadlessJsTaskService</code> and override <code>getTaskConfig</code>, e.g.:</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyTaskService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HeadlessJsTaskService</span> </span>{
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<span class="hljs-comment">// do stuff</span>
|
||||
};
|
||||
</code></pre>
|
||||
<p>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).</p>
|
||||
<p>You can do anything in your task such as network requests, timers and so on, as long as it doesn't touch UI. 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).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="the-java-api"></a><a href="#the-java-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>The Java API</h2>
|
||||
<p>Yes, this does still require some native code, but it's pretty thin. You need to extend <code>HeadlessJsTaskService</code> and override <code>getTaskConfig</code>, e.g.:</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyTaskService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HeadlessJsTaskService</span> </span>{
|
||||
|
||||
@@ -121,7 +121,7 @@ var icon = this.props.active
|
||||
style={{
|
||||
<span class="hljs-attr">width</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">height</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">resizeMode</span>: Image.resizeMode.contain,
|
||||
<span class="hljs-attr">resizeMode</span>: <span class="hljs-string">'contain'</span>,
|
||||
}}
|
||||
source={{
|
||||
<span class="hljs-attr">uri</span>:
|
||||
|
||||
@@ -121,7 +121,7 @@ var icon = this.props.active
|
||||
style={{
|
||||
<span class="hljs-attr">width</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">height</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">resizeMode</span>: Image.resizeMode.contain,
|
||||
<span class="hljs-attr">resizeMode</span>: <span class="hljs-string">'contain'</span>,
|
||||
}}
|
||||
source={{
|
||||
<span class="hljs-attr">uri</span>:
|
||||
|
||||
@@ -46,20 +46,15 @@
|
||||
<li>Fellow developers write and publish React Native modules to npm and open source them on GitHub.</li>
|
||||
<li>Making modules helps grow the React Native ecosystem and community. We recommend writing modules for your use cases and sharing them on npm.</li>
|
||||
<li>Read the guides on Native Modules (<a href="/react-native/docs/0.10/native-modules-ios">iOS</a>, <a href="/react-native/docs/0.10/native-modules-android">Android</a>) and Native UI Components (<a href="/react-native/docs/0.10/native-components-ios">iOS</a>, <a href="/react-native/docs/0.10/native-components-android">Android</a>) if you are interested in extending native functionality.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a>.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a> or <a href="https://native.directory/">Native Directory</a> to find what the community has been creating.</li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="development-tools"></a><a href="#development-tools" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Development Tools</h2>
|
||||
<p><a href="https://nuclide.io/">Nuclide</a> 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. <a href="https://code.visualstudio.com/">VS Code</a> is another IDE that is popular with JavaScript developers.</p>
|
||||
<p><a href="https://github.com/infinitered/ignite">Ignite</a> 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.</p>
|
||||
<p><a href="https://microsoft.github.io/code-push/">CodePush</a> 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.</p>
|
||||
<p><a href="https://appcenter.ms/">App Center</a> 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 App Center a try.</p>
|
||||
<p><a href="https://docs.expo.io">Expo</a> 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.</p>
|
||||
<p><a href="https://yogalayout.com/">Yoga</a> is a stand-alone layout engine that extends beyond React Native and allows product engineers to build layouts quickly for multiple platforms with a highly optimized open source layout engine designed with speed, size, and ease of use in mind.</p>
|
||||
<p>The <a href="/react-native/docs/0.10/debugging#react-developer-tools">React Developer Tools</a> are great for debugging React and React Native apps.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="where-react-native-people-hang-out"></a><a href="#where-react-native-people-hang-out" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Where React Native People Hang Out</h2>
|
||||
<p>The <a href="https://discuss.reactjs.org/">forum at discuss.reactjs.org</a> is a great place for discussion about best practices and application architecture as well as the future of React Native.</p>
|
||||
<p><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux</a> 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.</p>
|
||||
<p>The <a href="https://twitter.com/reactjs">React Twitter account</a> covers both React and React Native. Follow the React Native <a href="https://twitter.com/reactnative">Twitter account</a> and <a href="/react-native/blog/">blog</a> to find out what's happening in the world of React Native.</p>
|
||||
<p>There are a lot of <a href="http://www.meetup.com/topics/react-native/">React Native Meetups</a> that happen around the world. Often there is React Native content in React meetups as well.</p>
|
||||
<p>Sometimes we have React conferences. We posted the <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS3fZ46IGFirdqKTIxlws7e0">videos from React.js Conf 2017</a>, <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY">React.js Conf 2016</a>, and <a href="https://www.youtube.com/watch?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr&v=KVZ-P-ZI6W4">React.js Conf 2015</a>. We'll probably have more conferences in the future, too. Stay tuned. You can also find a list of dedicated React Native conferences <a href="http://www.awesome-react-native.com/#conferences">here</a>.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/network">← Networking</a><a class="docs-next button" href="/react-native/docs/0.10/components-and-apis">Components and APIs →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -46,20 +46,15 @@
|
||||
<li>Fellow developers write and publish React Native modules to npm and open source them on GitHub.</li>
|
||||
<li>Making modules helps grow the React Native ecosystem and community. We recommend writing modules for your use cases and sharing them on npm.</li>
|
||||
<li>Read the guides on Native Modules (<a href="/react-native/docs/0.10/native-modules-ios">iOS</a>, <a href="/react-native/docs/0.10/native-modules-android">Android</a>) and Native UI Components (<a href="/react-native/docs/0.10/native-components-ios">iOS</a>, <a href="/react-native/docs/0.10/native-components-android">Android</a>) if you are interested in extending native functionality.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a>.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a> or <a href="https://native.directory/">Native Directory</a> to find what the community has been creating.</li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="development-tools"></a><a href="#development-tools" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Development Tools</h2>
|
||||
<p><a href="https://nuclide.io/">Nuclide</a> 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. <a href="https://code.visualstudio.com/">VS Code</a> is another IDE that is popular with JavaScript developers.</p>
|
||||
<p><a href="https://github.com/infinitered/ignite">Ignite</a> 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.</p>
|
||||
<p><a href="https://microsoft.github.io/code-push/">CodePush</a> 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.</p>
|
||||
<p><a href="https://appcenter.ms/">App Center</a> 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 App Center a try.</p>
|
||||
<p><a href="https://docs.expo.io">Expo</a> 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.</p>
|
||||
<p><a href="https://yogalayout.com/">Yoga</a> is a stand-alone layout engine that extends beyond React Native and allows product engineers to build layouts quickly for multiple platforms with a highly optimized open source layout engine designed with speed, size, and ease of use in mind.</p>
|
||||
<p>The <a href="/react-native/docs/0.10/debugging#react-developer-tools">React Developer Tools</a> are great for debugging React and React Native apps.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="where-react-native-people-hang-out"></a><a href="#where-react-native-people-hang-out" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Where React Native People Hang Out</h2>
|
||||
<p>The <a href="https://discuss.reactjs.org/">forum at discuss.reactjs.org</a> is a great place for discussion about best practices and application architecture as well as the future of React Native.</p>
|
||||
<p><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux</a> 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.</p>
|
||||
<p>The <a href="https://twitter.com/reactjs">React Twitter account</a> covers both React and React Native. Follow the React Native <a href="https://twitter.com/reactnative">Twitter account</a> and <a href="/react-native/blog/">blog</a> to find out what's happening in the world of React Native.</p>
|
||||
<p>There are a lot of <a href="http://www.meetup.com/topics/react-native/">React Native Meetups</a> that happen around the world. Often there is React Native content in React meetups as well.</p>
|
||||
<p>Sometimes we have React conferences. We posted the <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS3fZ46IGFirdqKTIxlws7e0">videos from React.js Conf 2017</a>, <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY">React.js Conf 2016</a>, and <a href="https://www.youtube.com/watch?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr&v=KVZ-P-ZI6W4">React.js Conf 2015</a>. We'll probably have more conferences in the future, too. Stay tuned. You can also find a list of dedicated React Native conferences <a href="http://www.awesome-react-native.com/#conferences">here</a>.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/network">← Networking</a><a class="docs-next button" href="/react-native/docs/0.10/components-and-apis">Components and APIs →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -99,25 +99,21 @@
|
||||
}
|
||||
</code></pre>
|
||||
<h2><a class="anchor" aria-hidden="true" id="5-implement-the-javascript-module"></a><a href="#5-implement-the-javascript-module" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>5. Implement the JavaScript module</h2>
|
||||
<p>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 <code>propTypes</code>.</p>
|
||||
<p>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. It is recommended for you to document the component interface in this module (e.g. using Flow, TypeScript, or plain old comments).</p>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-comment">// ImageView.js</span>
|
||||
|
||||
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">'prop-types'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent, ViewPropTypes} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
|
||||
<span class="hljs-keyword">var</span> iface = {
|
||||
<span class="hljs-attr">name</span>: <span class="hljs-string">'ImageView'</span>,
|
||||
<span class="hljs-attr">propTypes</span>: {
|
||||
<span class="hljs-attr">src</span>: PropTypes.string,
|
||||
<span class="hljs-attr">borderRadius</span>: PropTypes.number,
|
||||
<span class="hljs-attr">resizeMode</span>: PropTypes.oneOf([<span class="hljs-string">'cover'</span>, <span class="hljs-string">'contain'</span>, <span class="hljs-string">'stretch'</span>]),
|
||||
...ViewPropTypes, <span class="hljs-comment">// include the default view properties</span>
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>, iface);
|
||||
<span class="hljs-comment">/**
|
||||
* Composes `View`.
|
||||
*
|
||||
* - src: string
|
||||
* - borderRadius: number
|
||||
* - resizeMode: 'cover' | 'contain' | 'stretch'
|
||||
*/</span>
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>);
|
||||
</code></pre>
|
||||
<p><code>requireNativeComponent</code> 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 <code>name</code> for use in debug messages and must declare the <code>propTypes</code> reflected by the Native View. The <code>propTypes</code> 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 <code>iface</code> to <code>requireNativeComponent</code>. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<p>The <code>requireNativeComponent</code> function takes the name of the native view. Note that if your component needs to do anything more sophisticated (e.g. custom event handling), you should wrap the native component in another React component. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<h1><a class="anchor" aria-hidden="true" id="events"></a><a href="#events" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Events</h1>
|
||||
<p>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 <code>getId()</code> method.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyCustomView</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">View</span> </span>{
|
||||
@@ -173,11 +169,8 @@ MyCustomView.propTypes = {
|
||||
...
|
||||
};
|
||||
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`, MyCustomView, {
|
||||
nativeOnly: {onChange: true}
|
||||
});
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`);
|
||||
</span></code></pre>
|
||||
<p>Note the use of <code>nativeOnly</code> 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, <code>Switch</code> has a custom <code>onChange</code> handler for the raw native event, and exposes an <code>onValueChange</code> handler property that is invoked with just the boolean value rather than the raw event (similar to <code>onChangeMessage</code> 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 <code>propTypes</code>, but if you don't you'll get an error. The solution is simply to call them out via the <code>nativeOnly</code> option.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/native-modules-android">← Native Modules</a><a class="docs-next button" href="/react-native/docs/0.10/headless-js-android">Headless JS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -99,25 +99,21 @@
|
||||
}
|
||||
</code></pre>
|
||||
<h2><a class="anchor" aria-hidden="true" id="5-implement-the-javascript-module"></a><a href="#5-implement-the-javascript-module" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>5. Implement the JavaScript module</h2>
|
||||
<p>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 <code>propTypes</code>.</p>
|
||||
<p>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. It is recommended for you to document the component interface in this module (e.g. using Flow, TypeScript, or plain old comments).</p>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-comment">// ImageView.js</span>
|
||||
|
||||
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">'prop-types'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent, ViewPropTypes} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
|
||||
<span class="hljs-keyword">var</span> iface = {
|
||||
<span class="hljs-attr">name</span>: <span class="hljs-string">'ImageView'</span>,
|
||||
<span class="hljs-attr">propTypes</span>: {
|
||||
<span class="hljs-attr">src</span>: PropTypes.string,
|
||||
<span class="hljs-attr">borderRadius</span>: PropTypes.number,
|
||||
<span class="hljs-attr">resizeMode</span>: PropTypes.oneOf([<span class="hljs-string">'cover'</span>, <span class="hljs-string">'contain'</span>, <span class="hljs-string">'stretch'</span>]),
|
||||
...ViewPropTypes, <span class="hljs-comment">// include the default view properties</span>
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>, iface);
|
||||
<span class="hljs-comment">/**
|
||||
* Composes `View`.
|
||||
*
|
||||
* - src: string
|
||||
* - borderRadius: number
|
||||
* - resizeMode: 'cover' | 'contain' | 'stretch'
|
||||
*/</span>
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>);
|
||||
</code></pre>
|
||||
<p><code>requireNativeComponent</code> 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 <code>name</code> for use in debug messages and must declare the <code>propTypes</code> reflected by the Native View. The <code>propTypes</code> 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 <code>iface</code> to <code>requireNativeComponent</code>. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<p>The <code>requireNativeComponent</code> function takes the name of the native view. Note that if your component needs to do anything more sophisticated (e.g. custom event handling), you should wrap the native component in another React component. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<h1><a class="anchor" aria-hidden="true" id="events"></a><a href="#events" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Events</h1>
|
||||
<p>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 <code>getId()</code> method.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyCustomView</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">View</span> </span>{
|
||||
@@ -173,11 +169,8 @@ MyCustomView.propTypes = {
|
||||
...
|
||||
};
|
||||
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`, MyCustomView, {
|
||||
nativeOnly: {onChange: true}
|
||||
});
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`);
|
||||
</span></code></pre>
|
||||
<p>Note the use of <code>nativeOnly</code> 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, <code>Switch</code> has a custom <code>onChange</code> handler for the raw native event, and exposes an <code>onValueChange</code> handler property that is invoked with just the boolean value rather than the raw event (similar to <code>onChangeMessage</code> 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 <code>propTypes</code>, but if you don't you'll get an error. The solution is simply to call them out via the <code>nativeOnly</code> option.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/native-modules-android">← Native Modules</a><a class="docs-next button" href="/react-native/docs/0.10/headless-js-android">Headless JS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -137,7 +137,13 @@ R<span class="hljs-function"><span class="hljs-title">eadableArray</span> -><
|
||||
}
|
||||
</code></pre>
|
||||
<p>The package needs to be provided in the <code>getPackages</code> method of the <code>MainApplication.java</code> file. This file exists under the android folder in your react-native application directory. The path to this file is: <code>android/app/src/main/java/com/your-app-name/MainApplication.java</code>.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<pre><code class="hljs css language-java"><span class="hljs-comment">// MainApplication.java</span>
|
||||
|
||||
...
|
||||
<span class="hljs-keyword">import</span> com.your-app-name.CustomToastPackage; <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
...
|
||||
|
||||
<span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<span class="hljs-keyword">return</span> Arrays.<ReactPackage>asList(
|
||||
<span class="hljs-keyword">new</span> MainReactPackage(),
|
||||
<span class="hljs-keyword">new</span> CustomToastPackage()); <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
|
||||
@@ -137,7 +137,13 @@ R<span class="hljs-function"><span class="hljs-title">eadableArray</span> -><
|
||||
}
|
||||
</code></pre>
|
||||
<p>The package needs to be provided in the <code>getPackages</code> method of the <code>MainApplication.java</code> file. This file exists under the android folder in your react-native application directory. The path to this file is: <code>android/app/src/main/java/com/your-app-name/MainApplication.java</code>.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<pre><code class="hljs css language-java"><span class="hljs-comment">// MainApplication.java</span>
|
||||
|
||||
...
|
||||
<span class="hljs-keyword">import</span> com.your-app-name.CustomToastPackage; <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
...
|
||||
|
||||
<span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<span class="hljs-keyword">return</span> Arrays.<ReactPackage>asList(
|
||||
<span class="hljs-keyword">new</span> MainReactPackage(),
|
||||
<span class="hljs-keyword">new</span> CustomToastPackage()); <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/navigation.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Navigating Between Screens</h1></header><article><div><span><p>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.</p>
|
||||
<p>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 <a href="/react-native/docs/0.10/navigation#react-navigation">React Navigation</a>. 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 <a href="https://reactnavigation.org/docs/redux-integration.html">redux</a>.</p>
|
||||
<p>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 <a href="/react-native/docs/0.10/navigation#react-navigation">React Navigation</a>. 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.</p>
|
||||
<p>If you're only targeting iOS, you may want to also check out <a href="/react-native/docs/0.10/navigation#navigatorios">NavigatorIOS</a> as a way of providing a native look and feel with minimal configuration, as it provides a wrapper around the native <code>UINavigationController</code> class. This component will not work on Android, however.</p>
|
||||
<p>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: <a href="http://airbnb.io/native-navigation/">native-navigation</a>, <a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<p>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 library provides native navigation on both platforms:<a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="react-navigation"></a><a href="#react-navigation" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>React Navigation</h2>
|
||||
<p>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.</p>
|
||||
<p>The first step is to install in your project:</p>
|
||||
@@ -72,7 +72,7 @@ export <span class="hljs-keyword">default</span> App;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>React Navigation routers make it easy to override navigation logic. Because routers can be nested inside each other, developers can override navigation logic for one area of the app without making widespread changes.</p>
|
||||
<p>The views in React Navigation use native components and the <a href="/react-native/docs/0.10/animated"><code>Animated</code></a> library to deliver 60fps animations that are run on the native thread. Plus, the animations and gestures can be easily customized.</p>
|
||||
<p>For a complete intro to React Navigation, follow the <a href="https://reactnavigation.org/docs/getting-started.html">React Navigation Getting Started Guide</a>, or browse other docs such as the <a href="https://expo.io/@react-navigation/NavigationPlayground">Intro to Navigators</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="navigatorios"></a><a href="#navigatorios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>NavigatorIOS</h2>
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/navigation.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Navigating Between Screens</h1></header><article><div><span><p>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.</p>
|
||||
<p>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 <a href="/react-native/docs/0.10/navigation#react-navigation">React Navigation</a>. 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 <a href="https://reactnavigation.org/docs/redux-integration.html">redux</a>.</p>
|
||||
<p>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 <a href="/react-native/docs/0.10/navigation#react-navigation">React Navigation</a>. 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.</p>
|
||||
<p>If you're only targeting iOS, you may want to also check out <a href="/react-native/docs/0.10/navigation#navigatorios">NavigatorIOS</a> as a way of providing a native look and feel with minimal configuration, as it provides a wrapper around the native <code>UINavigationController</code> class. This component will not work on Android, however.</p>
|
||||
<p>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: <a href="http://airbnb.io/native-navigation/">native-navigation</a>, <a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<p>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 library provides native navigation on both platforms:<a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="react-navigation"></a><a href="#react-navigation" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>React Navigation</h2>
|
||||
<p>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.</p>
|
||||
<p>The first step is to install in your project:</p>
|
||||
@@ -72,7 +72,7 @@ export <span class="hljs-keyword">default</span> App;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>React Navigation routers make it easy to override navigation logic. Because routers can be nested inside each other, developers can override navigation logic for one area of the app without making widespread changes.</p>
|
||||
<p>The views in React Navigation use native components and the <a href="/react-native/docs/0.10/animated"><code>Animated</code></a> library to deliver 60fps animations that are run on the native thread. Plus, the animations and gestures can be easily customized.</p>
|
||||
<p>For a complete intro to React Navigation, follow the <a href="https://reactnavigation.org/docs/getting-started.html">React Navigation Getting Started Guide</a>, or browse other docs such as the <a href="https://expo.io/@react-navigation/NavigationPlayground">Intro to Navigators</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="navigatorios"></a><a href="#navigatorios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>NavigatorIOS</h2>
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<span class="hljs-tag"><<span class="hljs-name">FlatList</span>
|
||||
<span class="hljs-attr">data</span>=<span class="hljs-string">{this.state.dataSource}</span>
|
||||
<span class="hljs-attr">renderItem</span>=<span class="hljs-string">{({item})</span> =></span> <span class="hljs-tag"><<span class="hljs-name">Text</span>></span>{item.title}, {item.releaseYear}<span class="hljs-tag"></<span class="hljs-name">Text</span>></span>}
|
||||
keyExtractor={(item, index) => index}
|
||||
keyExtractor={({id}, index) => id}
|
||||
/>
|
||||
<span class="hljs-tag"></<span class="hljs-name">View</span>></span>
|
||||
);
|
||||
@@ -136,7 +136,7 @@
|
||||
</span></code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Fetch Example"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(item%2C%20index)%20%3D%3E%20index%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(%7Bid%7D%2C%20index)%20%3D%3E%20id%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<span class="hljs-tag"><<span class="hljs-name">FlatList</span>
|
||||
<span class="hljs-attr">data</span>=<span class="hljs-string">{this.state.dataSource}</span>
|
||||
<span class="hljs-attr">renderItem</span>=<span class="hljs-string">{({item})</span> =></span> <span class="hljs-tag"><<span class="hljs-name">Text</span>></span>{item.title}, {item.releaseYear}<span class="hljs-tag"></<span class="hljs-name">Text</span>></span>}
|
||||
keyExtractor={(item, index) => index}
|
||||
keyExtractor={({id}, index) => id}
|
||||
/>
|
||||
<span class="hljs-tag"></<span class="hljs-name">View</span>></span>
|
||||
);
|
||||
@@ -136,7 +136,7 @@
|
||||
</span></code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Fetch Example"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(item%2C%20index)%20%3D%3E%20index%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(%7Bid%7D%2C%20index)%20%3D%3E%20id%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
+43
-87
@@ -185,10 +185,10 @@
|
||||
<p><img src="/react-native/docs/assets/SystraceBadCreateUI.png" alt="Creating Views"></p>
|
||||
<p>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.</p>
|
||||
<p>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 an 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.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="unbundling-inline-requires"></a><a href="#unbundling-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Unbundling + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider unbundling and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the unbundle feature of the packager and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="ram-bundles-inline-requires"></a><a href="#ram-bundles-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RAM bundles + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider the Random Access Modules (RAM) bundle format, and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the RAM format and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="loading-javascript"></a><a href="#loading-javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loading JavaScript</h3>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind unbundling is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind RAM bundles is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inline-requires"></a><a href="#inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inline Requires</h3>
|
||||
<p>Inline requires delay the requiring of a module or file until that file is actually needed. A basic example would look like this:</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="veryexpensivejs"></a><a href="#veryexpensivejs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>VeryExpensive.js</h4>
|
||||
@@ -237,48 +237,50 @@ export <span class="hljs-keyword">default</span> <span class="hljs-class"><span
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Even without unbundling inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-unbundling"></a><a href="#enable-unbundling" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable Unbundling</h3>
|
||||
<p>On iOS unbundling will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable unbundling in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/packager/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="unbundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<p>Even without the RAM format, inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-the-ram-format"></a><a href="#enable-the-ram-format" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable the RAM format</h3>
|
||||
<p>On iOS using the RAM format will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable the RAM format in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/scripts/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="ram-bundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>On Android enable unbundling by editing your android/app/build.gradle file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<p>On Android enable the RAM format by editing your <code>android/app/build.gradle</code> file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
]
|
||||
</code></pre>
|
||||
<p>Use the following lines on Android if you want to use a single indexed file:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-unbundle"</span>]
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-ram-bundle"</span>]
|
||||
]
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="configure-preloading-and-inline-requires"></a><a href="#configure-preloading-and-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure Preloading and Inline Requires</h3>
|
||||
<p>Now that we have unbundled our code, there is overhead for calling require. require now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<p>Now that we have a RAM bundle, there is overhead for calling <code>require</code>. <code>require</code> now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-a-packager-config-file"></a><a href="#adding-a-packager-config-file" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding a packager config file</h3>
|
||||
<p>Create a folder in your project called packager, and create a single file named config.js. Add the following:</p>
|
||||
<pre><code class="hljs">const<span class="hljs-built_in"> config </span>= {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
transformer: {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports =<span class="hljs-built_in"> config;
|
||||
</span></code></pre>
|
||||
<p>In Xcode, in the build phase, include <code>export BUNDLE_CONFIG="packager/config.js"</code>.</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_CONFIG</span>=<span class="hljs-string">"packager/config.js"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>Edit your android/app/build.gradle file to include <code>bundleConfig: "packager/config.js",</code>.</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
bundleConfig: <span class="hljs-string">"packager/config.js"</span>
|
||||
]
|
||||
</code></pre>
|
||||
@@ -304,7 +306,7 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
waitingModuleNames.length
|
||||
);
|
||||
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/moduleNames.js</span>
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/modulePaths.js</span>
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`module.exports = <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(loadedModuleNames.sort())}</span>;`</span>);
|
||||
</code></pre>
|
||||
<p>When you run your app, you can look in the console and see how many modules have been loaded, and how many are waiting. You may want to read the moduleNames and see if there are any surprises. Note that inline requires are invoked the first time the imports are referenced. You may need to investigate and refactor to ensure only the modules you want are loaded on startup. Note that you can change the Systrace object on require to help debug problematic requires.</p>
|
||||
@@ -314,84 +316,38 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named packager/moduleNames.js.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="transforming-to-module-paths"></a><a href="#transforming-to-module-paths" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Transforming to Module Paths</h3>
|
||||
<p>The loaded module names get us part of the way there, but we actually need absolute module paths, so the next script will set that up. Add <code>packager/generateModulePaths.js</code> to your project with the following:</p>
|
||||
<pre><code class="hljs"><span class="hljs-comment">// @flow</span>
|
||||
<span class="hljs-comment">/* eslint-disable no-console */</span>
|
||||
<span class="hljs-keyword">const</span> execSync = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).execSync;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
<span class="hljs-keyword">const</span> moduleNames = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./moduleNames'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> pjson = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../package.json'</span>);
|
||||
<span class="hljs-keyword">const</span> localPrefix = <span class="hljs-string">`<span class="hljs-subst">${pjson.name}</span>/`</span>;
|
||||
|
||||
<span class="hljs-keyword">const</span> modulePaths = moduleNames.map(<span class="hljs-function"><span class="hljs-params">moduleName</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (moduleName.startsWith(localPrefix)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./<span class="hljs-subst">${moduleName.substring(localPrefix.length)}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">if</span> (moduleName.endsWith(<span class="hljs-string">'.js'</span>)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./node_modules/<span class="hljs-subst">${moduleName}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">try</span> {
|
||||
<span class="hljs-keyword">const</span> result = execSync(
|
||||
<span class="hljs-string">`grep "@providesModule <span class="hljs-subst">${moduleName}</span>" $(find . -name <span class="hljs-subst">${moduleName}</span>\\\\.js) -l`</span>
|
||||
)
|
||||
.toString()
|
||||
.trim()
|
||||
.split(<span class="hljs-string">'\n'</span>)[<span class="hljs-number">0</span>];
|
||||
<span class="hljs-keyword">if</span> (result != <span class="hljs-literal">null</span>) {
|
||||
<span class="hljs-keyword">return</span> result;
|
||||
}
|
||||
} <span class="hljs-keyword">catch</span> (e) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
}
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
});
|
||||
|
||||
<span class="hljs-keyword">const</span> paths = modulePaths
|
||||
.filter(<span class="hljs-function"><span class="hljs-params">path</span> =></span> path != <span class="hljs-literal">null</span>)
|
||||
.map(<span class="hljs-function"><span class="hljs-params">path</span> =></span> <span class="hljs-string">`'<span class="hljs-subst">${path}</span>'`</span>)
|
||||
.join(<span class="hljs-string">',\n'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> fileData = <span class="hljs-string">`module.exports = [<span class="hljs-subst">${paths}</span>];`</span>;
|
||||
|
||||
fs.writeFile(<span class="hljs-string">'./packager/modulePaths.js'</span>, fileData, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (err) {
|
||||
<span class="hljs-built_in">console</span>.log(err);
|
||||
}
|
||||
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Done'</span>);
|
||||
});
|
||||
</code></pre>
|
||||
<p>You can run via <code>node packager/generateModulePaths.js</code>.</p>
|
||||
<p>This script attempts to map from the module names to module paths. Its not foolproof though, for instance, it ignores platform specific files (*ios.js, and *.android.js). However based on initial testing, it handles 95% of cases. When it runs, after some time it should complete and output a file named <code>packager/modulePaths.js</code>. It should contain paths to module files that are relative to your projects root. You can commit modulePaths.js to your repo so it is transportable.</p>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named <code>packager/modulePaths.js</code>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="updating-the-configjs"></a><a href="#updating-the-configjs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Updating the config.js</h3>
|
||||
<p>Returning to packager/config.js we should update it to use our newly generated modulePaths.js file.</p>
|
||||
<pre><code class="hljs"><span class="hljs-keyword">const</span> modulePaths = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./modulePaths'</span>);
|
||||
<span class="hljs-keyword">const</span> resolve = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).resolve;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
|
||||
<span class="hljs-comment">// Update the following line if the root folder of your app is somewhere else.</span>
|
||||
<span class="hljs-keyword">const</span> ROOT_FOLDER = path.resolve(__dirname, <span class="hljs-string">'..'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> config = {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
<span class="hljs-attr">transformer</span>: {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = config;
|
||||
</code></pre>
|
||||
<p>The preloadedModules entry in the config indicates which modules should be marked as preloaded by the unbundler. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<p>The <code>preloadedModules</code> entry in the config indicates which modules should be marked as preloaded when building a RAM bundle. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="test-and-measure-improvements"></a><a href="#test-and-measure-improvements" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Test and Measure Improvements</h3>
|
||||
<p>You should now be ready to build your app using unbundling and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
<p>You should now be ready to build your app using the RAM format and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/debugging">← Debugging</a><a class="docs-next button" href="/react-native/docs/0.10/gesture-responder-system">Gesture Responder System →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -185,10 +185,10 @@
|
||||
<p><img src="/react-native/docs/assets/SystraceBadCreateUI.png" alt="Creating Views"></p>
|
||||
<p>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.</p>
|
||||
<p>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 an 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.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="unbundling-inline-requires"></a><a href="#unbundling-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Unbundling + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider unbundling and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the unbundle feature of the packager and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="ram-bundles-inline-requires"></a><a href="#ram-bundles-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RAM bundles + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider the Random Access Modules (RAM) bundle format, and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the RAM format and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="loading-javascript"></a><a href="#loading-javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loading JavaScript</h3>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind unbundling is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind RAM bundles is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inline-requires"></a><a href="#inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inline Requires</h3>
|
||||
<p>Inline requires delay the requiring of a module or file until that file is actually needed. A basic example would look like this:</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="veryexpensivejs"></a><a href="#veryexpensivejs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>VeryExpensive.js</h4>
|
||||
@@ -237,48 +237,50 @@ export <span class="hljs-keyword">default</span> <span class="hljs-class"><span
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Even without unbundling inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-unbundling"></a><a href="#enable-unbundling" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable Unbundling</h3>
|
||||
<p>On iOS unbundling will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable unbundling in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/packager/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="unbundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<p>Even without the RAM format, inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-the-ram-format"></a><a href="#enable-the-ram-format" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable the RAM format</h3>
|
||||
<p>On iOS using the RAM format will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable the RAM format in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/scripts/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="ram-bundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>On Android enable unbundling by editing your android/app/build.gradle file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<p>On Android enable the RAM format by editing your <code>android/app/build.gradle</code> file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
]
|
||||
</code></pre>
|
||||
<p>Use the following lines on Android if you want to use a single indexed file:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-unbundle"</span>]
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-ram-bundle"</span>]
|
||||
]
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="configure-preloading-and-inline-requires"></a><a href="#configure-preloading-and-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure Preloading and Inline Requires</h3>
|
||||
<p>Now that we have unbundled our code, there is overhead for calling require. require now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<p>Now that we have a RAM bundle, there is overhead for calling <code>require</code>. <code>require</code> now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-a-packager-config-file"></a><a href="#adding-a-packager-config-file" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding a packager config file</h3>
|
||||
<p>Create a folder in your project called packager, and create a single file named config.js. Add the following:</p>
|
||||
<pre><code class="hljs">const<span class="hljs-built_in"> config </span>= {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
transformer: {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports =<span class="hljs-built_in"> config;
|
||||
</span></code></pre>
|
||||
<p>In Xcode, in the build phase, include <code>export BUNDLE_CONFIG="packager/config.js"</code>.</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_CONFIG</span>=<span class="hljs-string">"packager/config.js"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>Edit your android/app/build.gradle file to include <code>bundleConfig: "packager/config.js",</code>.</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
bundleConfig: <span class="hljs-string">"packager/config.js"</span>
|
||||
]
|
||||
</code></pre>
|
||||
@@ -304,7 +306,7 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
waitingModuleNames.length
|
||||
);
|
||||
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/moduleNames.js</span>
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/modulePaths.js</span>
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`module.exports = <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(loadedModuleNames.sort())}</span>;`</span>);
|
||||
</code></pre>
|
||||
<p>When you run your app, you can look in the console and see how many modules have been loaded, and how many are waiting. You may want to read the moduleNames and see if there are any surprises. Note that inline requires are invoked the first time the imports are referenced. You may need to investigate and refactor to ensure only the modules you want are loaded on startup. Note that you can change the Systrace object on require to help debug problematic requires.</p>
|
||||
@@ -314,84 +316,38 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named packager/moduleNames.js.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="transforming-to-module-paths"></a><a href="#transforming-to-module-paths" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Transforming to Module Paths</h3>
|
||||
<p>The loaded module names get us part of the way there, but we actually need absolute module paths, so the next script will set that up. Add <code>packager/generateModulePaths.js</code> to your project with the following:</p>
|
||||
<pre><code class="hljs"><span class="hljs-comment">// @flow</span>
|
||||
<span class="hljs-comment">/* eslint-disable no-console */</span>
|
||||
<span class="hljs-keyword">const</span> execSync = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).execSync;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
<span class="hljs-keyword">const</span> moduleNames = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./moduleNames'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> pjson = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../package.json'</span>);
|
||||
<span class="hljs-keyword">const</span> localPrefix = <span class="hljs-string">`<span class="hljs-subst">${pjson.name}</span>/`</span>;
|
||||
|
||||
<span class="hljs-keyword">const</span> modulePaths = moduleNames.map(<span class="hljs-function"><span class="hljs-params">moduleName</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (moduleName.startsWith(localPrefix)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./<span class="hljs-subst">${moduleName.substring(localPrefix.length)}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">if</span> (moduleName.endsWith(<span class="hljs-string">'.js'</span>)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./node_modules/<span class="hljs-subst">${moduleName}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">try</span> {
|
||||
<span class="hljs-keyword">const</span> result = execSync(
|
||||
<span class="hljs-string">`grep "@providesModule <span class="hljs-subst">${moduleName}</span>" $(find . -name <span class="hljs-subst">${moduleName}</span>\\\\.js) -l`</span>
|
||||
)
|
||||
.toString()
|
||||
.trim()
|
||||
.split(<span class="hljs-string">'\n'</span>)[<span class="hljs-number">0</span>];
|
||||
<span class="hljs-keyword">if</span> (result != <span class="hljs-literal">null</span>) {
|
||||
<span class="hljs-keyword">return</span> result;
|
||||
}
|
||||
} <span class="hljs-keyword">catch</span> (e) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
}
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
});
|
||||
|
||||
<span class="hljs-keyword">const</span> paths = modulePaths
|
||||
.filter(<span class="hljs-function"><span class="hljs-params">path</span> =></span> path != <span class="hljs-literal">null</span>)
|
||||
.map(<span class="hljs-function"><span class="hljs-params">path</span> =></span> <span class="hljs-string">`'<span class="hljs-subst">${path}</span>'`</span>)
|
||||
.join(<span class="hljs-string">',\n'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> fileData = <span class="hljs-string">`module.exports = [<span class="hljs-subst">${paths}</span>];`</span>;
|
||||
|
||||
fs.writeFile(<span class="hljs-string">'./packager/modulePaths.js'</span>, fileData, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (err) {
|
||||
<span class="hljs-built_in">console</span>.log(err);
|
||||
}
|
||||
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Done'</span>);
|
||||
});
|
||||
</code></pre>
|
||||
<p>You can run via <code>node packager/generateModulePaths.js</code>.</p>
|
||||
<p>This script attempts to map from the module names to module paths. Its not foolproof though, for instance, it ignores platform specific files (*ios.js, and *.android.js). However based on initial testing, it handles 95% of cases. When it runs, after some time it should complete and output a file named <code>packager/modulePaths.js</code>. It should contain paths to module files that are relative to your projects root. You can commit modulePaths.js to your repo so it is transportable.</p>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named <code>packager/modulePaths.js</code>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="updating-the-configjs"></a><a href="#updating-the-configjs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Updating the config.js</h3>
|
||||
<p>Returning to packager/config.js we should update it to use our newly generated modulePaths.js file.</p>
|
||||
<pre><code class="hljs"><span class="hljs-keyword">const</span> modulePaths = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./modulePaths'</span>);
|
||||
<span class="hljs-keyword">const</span> resolve = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).resolve;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
|
||||
<span class="hljs-comment">// Update the following line if the root folder of your app is somewhere else.</span>
|
||||
<span class="hljs-keyword">const</span> ROOT_FOLDER = path.resolve(__dirname, <span class="hljs-string">'..'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> config = {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
<span class="hljs-attr">transformer</span>: {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = config;
|
||||
</code></pre>
|
||||
<p>The preloadedModules entry in the config indicates which modules should be marked as preloaded by the unbundler. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<p>The <code>preloadedModules</code> entry in the config indicates which modules should be marked as preloaded when building a RAM bundle. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="test-and-measure-improvements"></a><a href="#test-and-measure-improvements" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Test and Measure Improvements</h3>
|
||||
<p>You should now be ready to build your app using unbundling and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
<p>You should now be ready to build your app using the RAM format and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/debugging">← Debugging</a><a class="docs-next button" href="/react-native/docs/0.10/gesture-responder-system">Gesture Responder System →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -275,8 +275,12 @@ emulator-<span class="hljs-number">5554</span> offline <span class="hljs-comme
|
||||
<p><img src="/react-native/docs/assets/ConfigureReleaseScheme.png" alt=""></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="3-configure-app-to-use-static-bundle"></a><a href="#3-configure-app-to-use-static-bundle" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>3. Configure app to use static bundle</h3>
|
||||
<p>During the development process, React Native has loaded your JavaScript code dynamically at runtime. For a production build, you want to pre-package the JavaScript bundle and distribute it inside your application. Doing this requires a code change in your code so that it knows to load the static bundle.</p>
|
||||
<p>In <code>AppDelegate.m</code>, change the default <code>jsCodeLocation</code> to point to the static bundle that is built in Release.</p>
|
||||
<pre><code class="hljs css language-objc"> jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<p>In <code>AppDelegate.m</code>, change <code>jsCodeLocation</code> to point to the static bundle if you're not in debug mode.</p>
|
||||
<pre><code class="hljs css language-objc"><span class="hljs-meta">#ifdef DEBUG</span>
|
||||
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:<span class="hljs-string">@"index"</span> fallbackResource:<span class="hljs-literal">nil</span>];
|
||||
<span class="hljs-meta">#else</span>
|
||||
jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<span class="hljs-meta">#endif</span>
|
||||
</code></pre>
|
||||
<p>This will now reference the <code>main.jsbundle</code> resource file that is created during the <code>Bundle React Native code and images</code> Build Phase in Xcode.</p>
|
||||
<blockquote>
|
||||
|
||||
@@ -275,8 +275,12 @@ emulator-<span class="hljs-number">5554</span> offline <span class="hljs-comme
|
||||
<p><img src="/react-native/docs/assets/ConfigureReleaseScheme.png" alt=""></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="3-configure-app-to-use-static-bundle"></a><a href="#3-configure-app-to-use-static-bundle" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>3. Configure app to use static bundle</h3>
|
||||
<p>During the development process, React Native has loaded your JavaScript code dynamically at runtime. For a production build, you want to pre-package the JavaScript bundle and distribute it inside your application. Doing this requires a code change in your code so that it knows to load the static bundle.</p>
|
||||
<p>In <code>AppDelegate.m</code>, change the default <code>jsCodeLocation</code> to point to the static bundle that is built in Release.</p>
|
||||
<pre><code class="hljs css language-objc"> jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<p>In <code>AppDelegate.m</code>, change <code>jsCodeLocation</code> to point to the static bundle if you're not in debug mode.</p>
|
||||
<pre><code class="hljs css language-objc"><span class="hljs-meta">#ifdef DEBUG</span>
|
||||
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:<span class="hljs-string">@"index"</span> fallbackResource:<span class="hljs-literal">nil</span>];
|
||||
<span class="hljs-meta">#else</span>
|
||||
jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<span class="hljs-meta">#endif</span>
|
||||
</code></pre>
|
||||
<p>This will now reference the <code>main.jsbundle</code> resource file that is created during the <code>Bundle React Native code and images</code> Build Phase in Xcode.</p>
|
||||
<blockquote>
|
||||
|
||||
@@ -38,13 +38,22 @@
|
||||
<p>You can generate a private signing key using <code>keytool</code>. On Windows <code>keytool</code> must be run from <code>C:\Program Files\Java\jdkx.x.x_x\bin</code>.</p>
|
||||
<pre><code class="hljs">$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p>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 <code>my-release-key.keystore</code>.</p>
|
||||
<p>This command prompts you for passwords for the keystore and key and for the Distinguished Name fields for your key. It then generates the keystore as a file called <code>my-release-key.keystore</code>.</p>
|
||||
<p>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.</p>
|
||||
<p>On Mac if you not sure where is your jdk bin folder is then perform the following command to find it, <code>$ /usr/libexec/java_home</code> it will output the directroy of jdk which looks like this, <code>/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home</code> then navigate to that directory by the following command, <code>$ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/</code> Now you can perform the keytool command with sudo permission as shown below, <code>$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000</code> <em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<p>On Mac, if you're not sure where your jdk bin folder is, then perform the following command to find it:</p>
|
||||
<pre><code class="hljs">$ /usr/libexec/java_home
|
||||
</code></pre>
|
||||
<p>It will output the directory of the jdk, which will look something like this:</p>
|
||||
<pre><code class="hljs">/Library/Java/JavaVirtualMachines/jdkX.X.X_XXX.jdk/Contents/Home
|
||||
</code></pre>
|
||||
<p>Navigate to that directory by using the command <code>$ cd /your/jdk/path</code> and use the keytool command with sudo permission as shown below.</p>
|
||||
<pre><code class="hljs">$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p><em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="setting-up-gradle-variables"></a><a href="#setting-up-gradle-variables" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Setting up gradle variables</h3>
|
||||
<ol>
|
||||
<li>Place the <code>my-release-key.keystore</code> file under the <code>android/app</code> directory in your project folder.</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code> and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code>, and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
</ol>
|
||||
<pre><code class="hljs"><span class="hljs-attr">MYAPP_RELEASE_STORE_FILE</span>=my-release-key.keystore
|
||||
<span class="hljs-attr">MYAPP_RELEASE_KEY_ALIAS</span>=my-key-alias
|
||||
@@ -58,9 +67,9 @@
|
||||
<blockquote>
|
||||
<p>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.</p>
|
||||
</blockquote>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext, and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-signing-config-to-your-app-s-gradle-config"></a><a href="#adding-signing-config-to-your-app-s-gradle-config" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding signing config to your app's gradle config</h3>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder and add the signing config,</p>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder, and add the signing config,</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
android {
|
||||
...
|
||||
@@ -91,7 +100,7 @@ $ ./gradlew assembleRelease
|
||||
</code></pre>
|
||||
<p>Gradle's <code>assembleRelease</code> 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 <code>android/app/build.gradle</code> to see how you can update it to reflect these changes.</p>
|
||||
<blockquote>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make release build skip bundling JS and assets into the APK.</p>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make the release build skip bundling JS and assets into the APK.</p>
|
||||
</blockquote>
|
||||
<p>The generated APK can be found under <code>android/app/build/outputs/apk/app-release.apk</code>, and is ready to be distributed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="testing-the-release-build-of-your-app"></a><a href="#testing-the-release-build-of-your-app" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Testing the release build of your app</h3>
|
||||
@@ -99,14 +108,17 @@ $ ./gradlew assembleRelease
|
||||
<pre><code class="hljs css language-sh">$ react-native run-android --variant=release
|
||||
</code></pre>
|
||||
<p>Note that <code>--variant=release</code> is only available if you've set up signing as described above.</p>
|
||||
<p>You can kill any running packager instances, all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<p>You can kill any running packager instances, since all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="split-apks-by-abi-to-reduce-file-size"></a><a href="#split-apks-by-abi-to-reduce-file-size" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Split APKs by ABI to reduce file size</h3>
|
||||
<p>By default, the generated APK has the native code for both x86 and ARMv7a CPU architectures. This makes it easier to share APKs that run on almost all Android devices. However, this has the downside that there will be some unused native code on any device, leading to unnecessarily bigger APKs.</p>
|
||||
<p>You can create an APK for each CPU by changing the following line in android/app/build.gradle:</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- ndk {</span>
|
||||
<span class="hljs-deletion">- abiFilters "armeabi-v7a", "x86"</span>
|
||||
<span class="hljs-deletion">- }</span>
|
||||
<span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<span class="hljs-addition">+ def enableSeparateBuildPerCPUArchitecture = true</span>
|
||||
</code></pre>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a> and the users will automatically get the appropriate APK. If you want to upload to other markets such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a>, and the users will automatically get the appropriate APK. If you want to upload to other markets, such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- universalApk false // If true, also generate a universal APK</span>
|
||||
<span class="hljs-addition">+ universalApk true // If true, also generate a universal APK</span>
|
||||
</code></pre>
|
||||
|
||||
@@ -38,13 +38,22 @@
|
||||
<p>You can generate a private signing key using <code>keytool</code>. On Windows <code>keytool</code> must be run from <code>C:\Program Files\Java\jdkx.x.x_x\bin</code>.</p>
|
||||
<pre><code class="hljs">$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p>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 <code>my-release-key.keystore</code>.</p>
|
||||
<p>This command prompts you for passwords for the keystore and key and for the Distinguished Name fields for your key. It then generates the keystore as a file called <code>my-release-key.keystore</code>.</p>
|
||||
<p>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.</p>
|
||||
<p>On Mac if you not sure where is your jdk bin folder is then perform the following command to find it, <code>$ /usr/libexec/java_home</code> it will output the directroy of jdk which looks like this, <code>/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home</code> then navigate to that directory by the following command, <code>$ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/</code> Now you can perform the keytool command with sudo permission as shown below, <code>$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000</code> <em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<p>On Mac, if you're not sure where your jdk bin folder is, then perform the following command to find it:</p>
|
||||
<pre><code class="hljs">$ /usr/libexec/java_home
|
||||
</code></pre>
|
||||
<p>It will output the directory of the jdk, which will look something like this:</p>
|
||||
<pre><code class="hljs">/Library/Java/JavaVirtualMachines/jdkX.X.X_XXX.jdk/Contents/Home
|
||||
</code></pre>
|
||||
<p>Navigate to that directory by using the command <code>$ cd /your/jdk/path</code> and use the keytool command with sudo permission as shown below.</p>
|
||||
<pre><code class="hljs">$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p><em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="setting-up-gradle-variables"></a><a href="#setting-up-gradle-variables" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Setting up gradle variables</h3>
|
||||
<ol>
|
||||
<li>Place the <code>my-release-key.keystore</code> file under the <code>android/app</code> directory in your project folder.</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code> and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code>, and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
</ol>
|
||||
<pre><code class="hljs"><span class="hljs-attr">MYAPP_RELEASE_STORE_FILE</span>=my-release-key.keystore
|
||||
<span class="hljs-attr">MYAPP_RELEASE_KEY_ALIAS</span>=my-key-alias
|
||||
@@ -58,9 +67,9 @@
|
||||
<blockquote>
|
||||
<p>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.</p>
|
||||
</blockquote>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext, and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-signing-config-to-your-app-s-gradle-config"></a><a href="#adding-signing-config-to-your-app-s-gradle-config" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding signing config to your app's gradle config</h3>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder and add the signing config,</p>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder, and add the signing config,</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
android {
|
||||
...
|
||||
@@ -91,7 +100,7 @@ $ ./gradlew assembleRelease
|
||||
</code></pre>
|
||||
<p>Gradle's <code>assembleRelease</code> 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 <code>android/app/build.gradle</code> to see how you can update it to reflect these changes.</p>
|
||||
<blockquote>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make release build skip bundling JS and assets into the APK.</p>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make the release build skip bundling JS and assets into the APK.</p>
|
||||
</blockquote>
|
||||
<p>The generated APK can be found under <code>android/app/build/outputs/apk/app-release.apk</code>, and is ready to be distributed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="testing-the-release-build-of-your-app"></a><a href="#testing-the-release-build-of-your-app" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Testing the release build of your app</h3>
|
||||
@@ -99,14 +108,17 @@ $ ./gradlew assembleRelease
|
||||
<pre><code class="hljs css language-sh">$ react-native run-android --variant=release
|
||||
</code></pre>
|
||||
<p>Note that <code>--variant=release</code> is only available if you've set up signing as described above.</p>
|
||||
<p>You can kill any running packager instances, all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<p>You can kill any running packager instances, since all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="split-apks-by-abi-to-reduce-file-size"></a><a href="#split-apks-by-abi-to-reduce-file-size" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Split APKs by ABI to reduce file size</h3>
|
||||
<p>By default, the generated APK has the native code for both x86 and ARMv7a CPU architectures. This makes it easier to share APKs that run on almost all Android devices. However, this has the downside that there will be some unused native code on any device, leading to unnecessarily bigger APKs.</p>
|
||||
<p>You can create an APK for each CPU by changing the following line in android/app/build.gradle:</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- ndk {</span>
|
||||
<span class="hljs-deletion">- abiFilters "armeabi-v7a", "x86"</span>
|
||||
<span class="hljs-deletion">- }</span>
|
||||
<span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<span class="hljs-addition">+ def enableSeparateBuildPerCPUArchitecture = true</span>
|
||||
</code></pre>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a> and the users will automatically get the appropriate APK. If you want to upload to other markets such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a>, and the users will automatically get the appropriate APK. If you want to upload to other markets, such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- universalApk false // If true, also generate a universal APK</span>
|
||||
<span class="hljs-addition">+ universalApk true // If true, also generate a universal APK</span>
|
||||
</code></pre>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<li><a href="/react-native/docs/0.10/testing#ios">iOS</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#apple-tv">Apple TV</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#end-to-end-tests">End-to-end tests</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#website">Website</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#updating-the-documentation">Updating the Documentation</a></li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="javascript"></a><a href="#javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript</h2>
|
||||
<h3><a class="anchor" aria-hidden="true" id="jest"></a><a href="#jest" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Jest</h3>
|
||||
@@ -64,7 +64,7 @@ $ npm run flow
|
||||
javac <span class="hljs-number">1.8</span><span class="hljs-number">.0</span>_111
|
||||
</code></pre>
|
||||
<p>The version string <code>1.8.x_xxx</code> corresponds to JDK 8.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>. Note that brew may not install the version needed to run the tests. For best results, use the same version as the GitHub builds, which can be found in the <code>.circleci</code> folder in the root of the repo.</p>
|
||||
<p>To run the Android unit tests:</p>
|
||||
<pre><code class="hljs">$ cd react-native
|
||||
$ ./scripts/run-android-local-unit-tests.sh
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<li><a href="/react-native/docs/0.10/testing#ios">iOS</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#apple-tv">Apple TV</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#end-to-end-tests">End-to-end tests</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#website">Website</a></li>
|
||||
<li><a href="/react-native/docs/0.10/testing#updating-the-documentation">Updating the Documentation</a></li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="javascript"></a><a href="#javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript</h2>
|
||||
<h3><a class="anchor" aria-hidden="true" id="jest"></a><a href="#jest" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Jest</h3>
|
||||
@@ -64,7 +64,7 @@ $ npm run flow
|
||||
javac <span class="hljs-number">1.8</span><span class="hljs-number">.0</span>_111
|
||||
</code></pre>
|
||||
<p>The version string <code>1.8.x_xxx</code> corresponds to JDK 8.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>. Note that brew may not install the version needed to run the tests. For best results, use the same version as the GitHub builds, which can be found in the <code>.circleci</code> folder in the root of the repo.</p>
|
||||
<p>To run the Android unit tests:</p>
|
||||
<pre><code class="hljs">$ cd react-native
|
||||
$ ./scripts/run-android-local-unit-tests.sh
|
||||
|
||||
@@ -46,6 +46,46 @@
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="parameters"></a><a href="#parameters" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Parameters</h3>
|
||||
<p>The command name identifies the parameters that a command would expect. When the command parameter is surrounded by greater-than, less-than symbols <code>< ></code>, this indicates that the parameter is expected. When a parameter is surrounded by brackets <code>[ ]</code>, this indicates that the parameter is optional.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="getting-a-list-of-all-cli-commands"></a><a href="#getting-a-list-of-all-cli-commands" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Getting a list of all CLI commands</h3>
|
||||
<p>Running <code>react-native --help</code> from inside a React Native project will list all of your current commands. Here is an example from version <code>0.56</code>:</p>
|
||||
<pre><code class="hljs css language-sh"> Usage: react-native [options] [<span class="hljs-built_in">command</span>]
|
||||
|
||||
Options:
|
||||
|
||||
-V, --version output the version number
|
||||
-h, --<span class="hljs-built_in">help</span> output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
start [options] starts the webserver
|
||||
run-ios [options] builds your app and starts it on iOS simulator
|
||||
run-android [options] builds your app and starts it on a connected Android emulator or device
|
||||
new-library [options] generates a native library bridge
|
||||
bundle [options] builds the javascript bundle <span class="hljs-keyword">for</span> offline use
|
||||
unbundle [options] builds javascript as <span class="hljs-string">"unbundle"</span> <span class="hljs-keyword">for</span> offline use
|
||||
eject [options] Re-create the iOS and Android folders and native code
|
||||
link [options] [packageName] links all native dependencies (updates native build files)
|
||||
unlink [options] <packageName> unlink native dependency
|
||||
install [options] <packageName> install and link native dependencies
|
||||
uninstall [options] <packageName> uninstall and unlink native dependencies
|
||||
upgrade [options] upgrade your app<span class="hljs-string">'s template files to the latest version; run this after updating the react-native version in your package.json and running npm install
|
||||
log-android [options] starts adb logcat
|
||||
log-ios [options] starts iOS device syslog tail
|
||||
dependencies [options] lists dependencies
|
||||
info [options] Get relevant version info about OS, toolchain and libraries
|
||||
</span></code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="cli-configs"></a><a href="#cli-configs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>CLI Configs</h3>
|
||||
<p>When using <code>react-native start</code>, its platform derivatives, and <code>react-native bundle</code> you can use a file to define the CLI options used by React Native by default. If you create a file <code>rn-cli.config.js</code> in the root of your project, it will be evaluated and options for the commands will come from there.</p>
|
||||
<p>You can see the options for the CLI config file inside the <a href="https://github.com/facebook/metro/blob/master/packages/metro/src/Config.js">source code for Metro here</a>, and here is a common <code>rn-cli.config.js</code> used for supporting TypeScript in React Native projects:</p>
|
||||
<pre><code class="hljs css language-js"><span class="hljs-built_in">module</span>.exports = {
|
||||
getTransformModulePath() {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'react-native-typescript-transformer'</span>);
|
||||
},
|
||||
getSourceExts() {
|
||||
<span class="hljs-keyword">return</span> [<span class="hljs-string">'ts'</span>, <span class="hljs-string">'tsx'</span>];
|
||||
},
|
||||
};
|
||||
</code></pre>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/building-from-source">← Building React Native from source</a><a class="docs-next button" href="/react-native/docs/0.10/datepickerios">DatePickerIOS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -46,6 +46,46 @@
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="parameters"></a><a href="#parameters" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Parameters</h3>
|
||||
<p>The command name identifies the parameters that a command would expect. When the command parameter is surrounded by greater-than, less-than symbols <code>< ></code>, this indicates that the parameter is expected. When a parameter is surrounded by brackets <code>[ ]</code>, this indicates that the parameter is optional.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="getting-a-list-of-all-cli-commands"></a><a href="#getting-a-list-of-all-cli-commands" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Getting a list of all CLI commands</h3>
|
||||
<p>Running <code>react-native --help</code> from inside a React Native project will list all of your current commands. Here is an example from version <code>0.56</code>:</p>
|
||||
<pre><code class="hljs css language-sh"> Usage: react-native [options] [<span class="hljs-built_in">command</span>]
|
||||
|
||||
Options:
|
||||
|
||||
-V, --version output the version number
|
||||
-h, --<span class="hljs-built_in">help</span> output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
start [options] starts the webserver
|
||||
run-ios [options] builds your app and starts it on iOS simulator
|
||||
run-android [options] builds your app and starts it on a connected Android emulator or device
|
||||
new-library [options] generates a native library bridge
|
||||
bundle [options] builds the javascript bundle <span class="hljs-keyword">for</span> offline use
|
||||
unbundle [options] builds javascript as <span class="hljs-string">"unbundle"</span> <span class="hljs-keyword">for</span> offline use
|
||||
eject [options] Re-create the iOS and Android folders and native code
|
||||
link [options] [packageName] links all native dependencies (updates native build files)
|
||||
unlink [options] <packageName> unlink native dependency
|
||||
install [options] <packageName> install and link native dependencies
|
||||
uninstall [options] <packageName> uninstall and unlink native dependencies
|
||||
upgrade [options] upgrade your app<span class="hljs-string">'s template files to the latest version; run this after updating the react-native version in your package.json and running npm install
|
||||
log-android [options] starts adb logcat
|
||||
log-ios [options] starts iOS device syslog tail
|
||||
dependencies [options] lists dependencies
|
||||
info [options] Get relevant version info about OS, toolchain and libraries
|
||||
</span></code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="cli-configs"></a><a href="#cli-configs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>CLI Configs</h3>
|
||||
<p>When using <code>react-native start</code>, its platform derivatives, and <code>react-native bundle</code> you can use a file to define the CLI options used by React Native by default. If you create a file <code>rn-cli.config.js</code> in the root of your project, it will be evaluated and options for the commands will come from there.</p>
|
||||
<p>You can see the options for the CLI config file inside the <a href="https://github.com/facebook/metro/blob/master/packages/metro/src/Config.js">source code for Metro here</a>, and here is a common <code>rn-cli.config.js</code> used for supporting TypeScript in React Native projects:</p>
|
||||
<pre><code class="hljs css language-js"><span class="hljs-built_in">module</span>.exports = {
|
||||
getTransformModulePath() {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'react-native-typescript-transformer'</span>);
|
||||
},
|
||||
getSourceExts() {
|
||||
<span class="hljs-keyword">return</span> [<span class="hljs-string">'ts'</span>, <span class="hljs-string">'tsx'</span>];
|
||||
},
|
||||
};
|
||||
</code></pre>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.10/building-from-source">← Building React Native from source</a><a class="docs-next button" href="/react-native/docs/0.10/datepickerios">DatePickerIOS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
<p>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.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitylabel-ios-android"></a><a href="#accessibilitylabel-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityLabel (iOS, Android)</h4>
|
||||
<p>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.</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View:</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel={'Tap me!'}
|
||||
accessibilityLabel="Tap me!"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Press me!</Text>
|
||||
@@ -60,7 +60,55 @@
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>In the above example, the <code>accessibilityLabel</code> on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityhint-ios-android"></a><a href="#accessibilityhint-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityHint (iOS, Android)</h4>
|
||||
<p>An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label.</p>
|
||||
<p>To use, set the <code>accessibilityHint</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel="Go back"
|
||||
accessibilityHint="Navigates to the previous screen"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Back</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>iOS In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for accessibilityHint in the <a href="https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint">iOS Developer Docs</a></p>
|
||||
<p>Android In the above example, Talkback will read the hint after the label. At this time, hints cannot be turned off on Android.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityignoresinvertcolorsios"></a><a href="#accessibilityignoresinvertcolorsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityIgnoresInvertColors(iOS)</h4>
|
||||
<p>Inverting screen colors is an Accessibility feature that makes the iPhone and iPad easier on the eyes for some people with a sensitivity to brightness, easier to distinguish for some people with color blindness, and easier to make out for some people with low vision. However, sometimes you have views such as photos that you don't want to be inverted. In this case, you can set this property to be false so that these specific views won't have their colors inverted.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityrole-ios-android"></a><a href="#accessibilityrole-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityRole (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> Accessibility Role and Accessibility States are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. To use, set the <code>accessibilityRole</code> property to one of the following strings:</p>
|
||||
<ul>
|
||||
<li><strong>none</strong> Used when the element has no role.</li>
|
||||
<li><strong>button</strong> Used when the element should be treated as a button.</li>
|
||||
<li><strong>link</strong> Used when the element should be treated as a link.</li>
|
||||
<li><strong>search</strong> Used when the text field element should also be treated as a search field.</li>
|
||||
<li><strong>image</strong> Used when the element should be treated as an image. Can be combined with button or link, for example.</li>
|
||||
<li><strong>keyboardkey</strong> Used when the element acts as a keyboard key.</li>
|
||||
<li><strong>text</strong> Used when the element should be treated as static text that cannot change.</li>
|
||||
<li><strong>adjustable</strong> Used when an element can be "adjusted" (e.g. a slider).</li>
|
||||
<li><strong>imagebutton</strong> Used when the element should be treated as a button and is also an image.</li>
|
||||
<li><strong>header</strong> Used when an element acts as a header for a content section (e.g. the title of a navigation bar).</li>
|
||||
<li><strong>summary</strong> Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitystate-ios-android"></a><a href="#accessibilitystate-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityState (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityRole</code> and <code>accessibilityStates</code> are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. The state of the element can be set either to <code>selected</code> or <code>disabled</code> or both:</p>
|
||||
<ul>
|
||||
<li><strong>selected</strong> Used when the element is in a selected state. For example, a button is selected.</li>
|
||||
<li><strong>disabled</strong> Used when the element is disabled and cannot be interacted with.</li>
|
||||
</ul>
|
||||
<p>To use, set the <code>accessibilityState</code> to an array containing either <code>selected</code>, <code>disabled</code>, or both.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitytraits-ios"></a><a href="#accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityTraits (iOS)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> <code>accessibilityTraits</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>accessibilityTraits</code>.</p>
|
||||
<p>To use, set the <code>accessibilityTraits</code> property to one of (or an array of) accessibility trait strings:</p>
|
||||
<ul>
|
||||
@@ -93,6 +141,9 @@
|
||||
<h4><a class="anchor" aria-hidden="true" id="onmagictap-ios"></a><a href="#onmagictap-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>onMagicTap (iOS)</h4>
|
||||
<p>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 <code>onMagicTap</code> function, the system will traverse up the view hierarchy until it finds a view that does.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitycomponenttype-android"></a><a href="#accessibilitycomponenttype-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityComponentType (Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityComponentType</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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. We support 'none', ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’.</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableWithoutFeedback accessibilityComponentType=”button”
|
||||
onPress={this._onPress}>
|
||||
@@ -155,7 +206,7 @@ _onPress: <span class="hljs-function"><span class="hljs-keyword">function</span>
|
||||
}
|
||||
|
||||
<CustomRadioButton
|
||||
accessibleComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
accessibilityComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
onPress={<span class="hljs-keyword">this</span>._onPress}/>
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
<p>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.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitylabel-ios-android"></a><a href="#accessibilitylabel-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityLabel (iOS, Android)</h4>
|
||||
<p>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.</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View:</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel={'Tap me!'}
|
||||
accessibilityLabel="Tap me!"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Press me!</Text>
|
||||
@@ -60,7 +60,55 @@
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>In the above example, the <code>accessibilityLabel</code> on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityhint-ios-android"></a><a href="#accessibilityhint-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityHint (iOS, Android)</h4>
|
||||
<p>An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label.</p>
|
||||
<p>To use, set the <code>accessibilityHint</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel="Go back"
|
||||
accessibilityHint="Navigates to the previous screen"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Back</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>iOS In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for accessibilityHint in the <a href="https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint">iOS Developer Docs</a></p>
|
||||
<p>Android In the above example, Talkback will read the hint after the label. At this time, hints cannot be turned off on Android.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityignoresinvertcolorsios"></a><a href="#accessibilityignoresinvertcolorsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityIgnoresInvertColors(iOS)</h4>
|
||||
<p>Inverting screen colors is an Accessibility feature that makes the iPhone and iPad easier on the eyes for some people with a sensitivity to brightness, easier to distinguish for some people with color blindness, and easier to make out for some people with low vision. However, sometimes you have views such as photos that you don't want to be inverted. In this case, you can set this property to be false so that these specific views won't have their colors inverted.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityrole-ios-android"></a><a href="#accessibilityrole-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityRole (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> Accessibility Role and Accessibility States are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. To use, set the <code>accessibilityRole</code> property to one of the following strings:</p>
|
||||
<ul>
|
||||
<li><strong>none</strong> Used when the element has no role.</li>
|
||||
<li><strong>button</strong> Used when the element should be treated as a button.</li>
|
||||
<li><strong>link</strong> Used when the element should be treated as a link.</li>
|
||||
<li><strong>search</strong> Used when the text field element should also be treated as a search field.</li>
|
||||
<li><strong>image</strong> Used when the element should be treated as an image. Can be combined with button or link, for example.</li>
|
||||
<li><strong>keyboardkey</strong> Used when the element acts as a keyboard key.</li>
|
||||
<li><strong>text</strong> Used when the element should be treated as static text that cannot change.</li>
|
||||
<li><strong>adjustable</strong> Used when an element can be "adjusted" (e.g. a slider).</li>
|
||||
<li><strong>imagebutton</strong> Used when the element should be treated as a button and is also an image.</li>
|
||||
<li><strong>header</strong> Used when an element acts as a header for a content section (e.g. the title of a navigation bar).</li>
|
||||
<li><strong>summary</strong> Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitystate-ios-android"></a><a href="#accessibilitystate-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityState (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityRole</code> and <code>accessibilityStates</code> are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. The state of the element can be set either to <code>selected</code> or <code>disabled</code> or both:</p>
|
||||
<ul>
|
||||
<li><strong>selected</strong> Used when the element is in a selected state. For example, a button is selected.</li>
|
||||
<li><strong>disabled</strong> Used when the element is disabled and cannot be interacted with.</li>
|
||||
</ul>
|
||||
<p>To use, set the <code>accessibilityState</code> to an array containing either <code>selected</code>, <code>disabled</code>, or both.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitytraits-ios"></a><a href="#accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityTraits (iOS)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> <code>accessibilityTraits</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>accessibilityTraits</code>.</p>
|
||||
<p>To use, set the <code>accessibilityTraits</code> property to one of (or an array of) accessibility trait strings:</p>
|
||||
<ul>
|
||||
@@ -93,6 +141,9 @@
|
||||
<h4><a class="anchor" aria-hidden="true" id="onmagictap-ios"></a><a href="#onmagictap-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>onMagicTap (iOS)</h4>
|
||||
<p>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 <code>onMagicTap</code> function, the system will traverse up the view hierarchy until it finds a view that does.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitycomponenttype-android"></a><a href="#accessibilitycomponenttype-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityComponentType (Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityComponentType</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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. We support 'none', ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’.</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableWithoutFeedback accessibilityComponentType=”button”
|
||||
onPress={this._onPress}>
|
||||
@@ -155,7 +206,7 @@ _onPress: <span class="hljs-function"><span class="hljs-keyword">function</span>
|
||||
}
|
||||
|
||||
<CustomRadioButton
|
||||
accessibleComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
accessibilityComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
onPress={<span class="hljs-keyword">this</span>._onPress}/>
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For Apple TV · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.11"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For Apple TV · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For TV Devices · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.11"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For TV Devices · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
@@ -33,7 +33,7 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For Apple TV</h1></header><article><div><span><style>
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For TV Devices</h1></header><article><div><span><style>
|
||||
.toggler li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -151,20 +151,20 @@
|
||||
<ul>
|
||||
<li><p><em>General support for tvOS</em>: 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.</p></li>
|
||||
<li><p><em>Common codebase</em>: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.</p></li>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
@@ -222,7 +222,7 @@
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, make a long press on the play/pause button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
<ul>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For Apple TV · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.11"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For Apple TV · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For TV Devices · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.11"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For TV Devices · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
@@ -33,7 +33,7 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For Apple TV</h1></header><article><div><span><style>
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For TV Devices</h1></header><article><div><span><style>
|
||||
.toggler li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -151,20 +151,20 @@
|
||||
<ul>
|
||||
<li><p><em>General support for tvOS</em>: 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.</p></li>
|
||||
<li><p><em>Common codebase</em>: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.</p></li>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
@@ -222,7 +222,7 @@
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, make a long press on the play/pause button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
<ul>
|
||||
|
||||
@@ -63,10 +63,10 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
</code></pre>
|
||||
<h4><a class="anchor" aria-hidden="true" id="download-links-for-android-ndk"></a><a href="#download-links-for-android-ndk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download links for Android NDK</h4>
|
||||
<ol>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip</a></li>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip</a></li>
|
||||
</ol>
|
||||
<p>You can find further instructions on the <a href="https://developer.android.com/ndk/index.html">official page</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="building-the-source"></a><a href="#building-the-source" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Building the source</h3>
|
||||
@@ -79,7 +79,7 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
<p>Add <code>gradle-download-task</code> as dependency in <code>android/build.gradle</code>:</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
<span class="hljs-keyword">dependencies</span> {
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:1.3.1'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:2.3.3'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'de.undercouch:gradle-download-task:3.1.2'</span>
|
||||
|
||||
<span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Do not place your application dependencies here; they belong</span>
|
||||
|
||||
@@ -63,10 +63,10 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
</code></pre>
|
||||
<h4><a class="anchor" aria-hidden="true" id="download-links-for-android-ndk"></a><a href="#download-links-for-android-ndk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download links for Android NDK</h4>
|
||||
<ol>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip</a></li>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip</a></li>
|
||||
</ol>
|
||||
<p>You can find further instructions on the <a href="https://developer.android.com/ndk/index.html">official page</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="building-the-source"></a><a href="#building-the-source" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Building the source</h3>
|
||||
@@ -79,7 +79,7 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
<p>Add <code>gradle-download-task</code> as dependency in <code>android/build.gradle</code>:</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
<span class="hljs-keyword">dependencies</span> {
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:1.3.1'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:2.3.3'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'de.undercouch:gradle-download-task:3.1.2'</span>
|
||||
|
||||
<span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Do not place your application dependencies here; they belong</span>
|
||||
|
||||
@@ -94,11 +94,11 @@ YellowBox.ignoreWarnings([<span class="hljs-string">'Warning: ...'</span>]);
|
||||
<p>Note: if you prefer to avoid global installations, you can add <code>react-devtools</code> as a project dependency. Add the <code>react-devtools</code> package to your project using <code>npm install --save-dev react-devtools</code>, then add <code>"react-devtools": "react-devtools"</code> to the <code>scripts</code> section in your <code>package.json</code>, and then run <code>npm run react-devtools</code> from your project folder to open the DevTools.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" aria-hidden="true" id="integration-with-react-native-inspector"></a><a href="#integration-with-react-native-inspector" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Integration with React Native Inspector</h3>
|
||||
<p>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:</p>
|
||||
<p>Open the in-app developer menu and choose "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:</p>
|
||||
<p><img src="/react-native/docs/assets/Inspector.gif" alt="React Native Inspector"></p>
|
||||
<p>However, when <code>react-devtools</code> 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:</p>
|
||||
<p><img src="/react-native/docs/assets/ReactDevToolsInspector.gif" alt="React DevTools Inspector Integration"></p>
|
||||
<p>You can choose "Hide Inspector" in the same menu to exit this mode.</p>
|
||||
<p>You can choose "Toggle Inspector" in the same menu to exit this mode.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inspecting-component-instances"></a><a href="#inspecting-component-instances" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inspecting Component Instances</h3>
|
||||
<p>When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.</p>
|
||||
<p>First, follow the instructions for debugging in Chrome to open the Chrome console.</p>
|
||||
|
||||
@@ -94,11 +94,11 @@ YellowBox.ignoreWarnings([<span class="hljs-string">'Warning: ...'</span>]);
|
||||
<p>Note: if you prefer to avoid global installations, you can add <code>react-devtools</code> as a project dependency. Add the <code>react-devtools</code> package to your project using <code>npm install --save-dev react-devtools</code>, then add <code>"react-devtools": "react-devtools"</code> to the <code>scripts</code> section in your <code>package.json</code>, and then run <code>npm run react-devtools</code> from your project folder to open the DevTools.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" aria-hidden="true" id="integration-with-react-native-inspector"></a><a href="#integration-with-react-native-inspector" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Integration with React Native Inspector</h3>
|
||||
<p>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:</p>
|
||||
<p>Open the in-app developer menu and choose "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:</p>
|
||||
<p><img src="/react-native/docs/assets/Inspector.gif" alt="React Native Inspector"></p>
|
||||
<p>However, when <code>react-devtools</code> 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:</p>
|
||||
<p><img src="/react-native/docs/assets/ReactDevToolsInspector.gif" alt="React DevTools Inspector Integration"></p>
|
||||
<p>You can choose "Hide Inspector" in the same menu to exit this mode.</p>
|
||||
<p>You can choose "Toggle Inspector" in the same menu to exit this mode.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inspecting-component-instances"></a><a href="#inspecting-component-instances" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inspecting Component Instances</h3>
|
||||
<p>When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.</p>
|
||||
<p>First, follow the instructions for debugging in Chrome to open the Chrome console.</p>
|
||||
|
||||
@@ -72,7 +72,7 @@ render() {
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js">NativeMethodsMixin.js</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react-native/blob/master/Libraries/Renderer/oss/ReactNativeRenderer-prod.js">NativeMethodsMixin</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="composite-components-and-setnativeprops"></a><a href="#composite-components-and-setnativeprops" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Composite components and setNativeProps</h2>
|
||||
<p>Composite components are not backed by a native view, so you cannot call <code>setNativeProps</code> on them. Consider this example:</p>
|
||||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||||
|
||||
@@ -72,7 +72,7 @@ render() {
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js">NativeMethodsMixin.js</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react-native/blob/master/Libraries/Renderer/oss/ReactNativeRenderer-prod.js">NativeMethodsMixin</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="composite-components-and-setnativeprops"></a><a href="#composite-components-and-setnativeprops" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Composite components and setNativeProps</h2>
|
||||
<p>Composite components are not backed by a native view, so you cannot call <code>setNativeProps</code> on them. Consider this example:</p>
|
||||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<p>A useful tool to visualize cubic bezier curves can be found at <a href="http://cubic-bezier.com/">http://cubic-bezier.com/</a></p>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="in"></a><a href="#in" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>in()</code></h3>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span>(easing)
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span> easing;
|
||||
</code></pre>
|
||||
<p>Runs an easing function forwards.</p>
|
||||
<hr>
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
<p>A useful tool to visualize cubic bezier curves can be found at <a href="http://cubic-bezier.com/">http://cubic-bezier.com/</a></p>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="in"></a><a href="#in" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>in()</code></h3>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span>(easing)
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span> easing;
|
||||
</code></pre>
|
||||
<p>Runs an easing function forwards.</p>
|
||||
<hr>
|
||||
|
||||
@@ -105,11 +105,11 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
<span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
|
||||
<span class="hljs-attr">flexDirection</span>: <span class="hljs-string">'column'</span>,
|
||||
<span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'stretch'</span>,
|
||||
}}>
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
|
||||
<View style={{height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{height: 100, backgroundColor: 'steelblue'}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'stretch'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%20100%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
|
||||
<h4><a class="anchor" aria-hidden="true" id="going-deeper"></a><a href="#going-deeper" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Going Deeper</h4>
|
||||
<p>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 <a href="/react-native/docs/0.11/layout-props">here</a>.</p>
|
||||
|
||||
@@ -105,11 +105,11 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
<span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
|
||||
<span class="hljs-attr">flexDirection</span>: <span class="hljs-string">'column'</span>,
|
||||
<span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'stretch'</span>,
|
||||
}}>
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
|
||||
<View style={{height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{height: 100, backgroundColor: 'steelblue'}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'stretch'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%20100%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
|
||||
<h4><a class="anchor" aria-hidden="true" id="going-deeper"></a><a href="#going-deeper" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Going Deeper</h4>
|
||||
<p>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 <a href="/react-native/docs/0.11/layout-props">here</a>.</p>
|
||||
|
||||
@@ -260,7 +260,7 @@ npm start
|
||||
</blockquote>
|
||||
<p>Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="2-install-the-android-sdk"></a><a href="#2-install-the-android-sdk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Install the Android SDK</h4>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 6.0 (Marshmallow)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 8.0 (Oreo)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png" alt="Android Studio Welcome"></p>
|
||||
@@ -270,11 +270,9 @@ npm start
|
||||
<blockquote>
|
||||
<p>The SDK Manager can also be found within the Android Studio "Preferences" dialog, under <strong>Appearance & Behavior</strong> → <strong>System Settings</strong> → <strong>Android SDK</strong>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>Android 6.0 (Marshmallow)</code> entry, then make sure the following items are all checked:</p>
|
||||
<p>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 <code>Android 8.0 (Oreo)</code> entry, then make sure the following items are all checked:</p>
|
||||
<ul>
|
||||
<li><code>Google APIs</code></li>
|
||||
<li><code>Android SDK Platform 23</code></li>
|
||||
<li><code>Intel x86 Atom_64 System Image</code></li>
|
||||
<li><code>Android SDK Platform 26</code></li>
|
||||
<li><code>Google APIs Intel x86 Atom_64 System Image</code></li>
|
||||
</ul>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -282,11 +280,11 @@ npm start
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerWindows.png" alt="Android SDK Manager"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>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 <code>23.0.1</code> is selected.</p>
|
||||
<p>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 <code>26.0.3</code> is selected.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>Finally, click "Apply" to download and install the Android SDK and related build tools.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -303,12 +301,14 @@ npm start
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native linux android" /></p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">ANDROID_HOME</span>=<span class="hljs-variable">$HOME</span>/Android/Sdk
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native mac linux android" /></p>
|
||||
<blockquote>
|
||||
@@ -351,7 +351,7 @@ npm start
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-physical-device"></a><a href="#using-a-physical-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a physical device</h3>
|
||||
<p>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 <a href="/react-native/docs/0.11/running-on-device">here</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-virtual-device"></a><a href="#using-a-virtual-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a virtual device</h3>
|
||||
<p>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:</p>
|
||||
<p>If you use Android Studio to open <code>./AwesomeProject/android</code>, 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:</p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioAVD.png" alt="Android Studio AVD Manager"></p>
|
||||
<p>If you have just installed Android Studio, you will likely need to <a href="https://developer.android.com/studio/run/managing-avds.html">create a new AVD</a>. Select "Create Virtual Device...", then pick any Phone from the list and click "Next".</p>
|
||||
<p><block class="native windows android" /></p>
|
||||
@@ -359,7 +359,7 @@ npm start
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedCreateAVDMacOS.png" alt="Android Studio AVD Manager"></p>
|
||||
<p><block class="native mac windows linux android" /></p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Marshmallow</strong> API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.</p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Oreo</strong> API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.</p>
|
||||
<p><block class="native linux android" /></p>
|
||||
<blockquote>
|
||||
<p>We recommend configuring <a href="https://developer.android.com/studio/run/emulator-acceleration.html#vm-linux">VM acceleration</a> on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.</p>
|
||||
|
||||
@@ -260,7 +260,7 @@ npm start
|
||||
</blockquote>
|
||||
<p>Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="2-install-the-android-sdk"></a><a href="#2-install-the-android-sdk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Install the Android SDK</h4>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 6.0 (Marshmallow)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 8.0 (Oreo)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png" alt="Android Studio Welcome"></p>
|
||||
@@ -270,11 +270,9 @@ npm start
|
||||
<blockquote>
|
||||
<p>The SDK Manager can also be found within the Android Studio "Preferences" dialog, under <strong>Appearance & Behavior</strong> → <strong>System Settings</strong> → <strong>Android SDK</strong>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>Android 6.0 (Marshmallow)</code> entry, then make sure the following items are all checked:</p>
|
||||
<p>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 <code>Android 8.0 (Oreo)</code> entry, then make sure the following items are all checked:</p>
|
||||
<ul>
|
||||
<li><code>Google APIs</code></li>
|
||||
<li><code>Android SDK Platform 23</code></li>
|
||||
<li><code>Intel x86 Atom_64 System Image</code></li>
|
||||
<li><code>Android SDK Platform 26</code></li>
|
||||
<li><code>Google APIs Intel x86 Atom_64 System Image</code></li>
|
||||
</ul>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -282,11 +280,11 @@ npm start
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerWindows.png" alt="Android SDK Manager"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>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 <code>23.0.1</code> is selected.</p>
|
||||
<p>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 <code>26.0.3</code> is selected.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>Finally, click "Apply" to download and install the Android SDK and related build tools.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -303,12 +301,14 @@ npm start
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native linux android" /></p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">ANDROID_HOME</span>=<span class="hljs-variable">$HOME</span>/Android/Sdk
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native mac linux android" /></p>
|
||||
<blockquote>
|
||||
@@ -351,7 +351,7 @@ npm start
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-physical-device"></a><a href="#using-a-physical-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a physical device</h3>
|
||||
<p>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 <a href="/react-native/docs/0.11/running-on-device">here</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-virtual-device"></a><a href="#using-a-virtual-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a virtual device</h3>
|
||||
<p>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:</p>
|
||||
<p>If you use Android Studio to open <code>./AwesomeProject/android</code>, 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:</p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioAVD.png" alt="Android Studio AVD Manager"></p>
|
||||
<p>If you have just installed Android Studio, you will likely need to <a href="https://developer.android.com/studio/run/managing-avds.html">create a new AVD</a>. Select "Create Virtual Device...", then pick any Phone from the list and click "Next".</p>
|
||||
<p><block class="native windows android" /></p>
|
||||
@@ -359,7 +359,7 @@ npm start
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedCreateAVDMacOS.png" alt="Android Studio AVD Manager"></p>
|
||||
<p><block class="native mac windows linux android" /></p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Marshmallow</strong> API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.</p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Oreo</strong> API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.</p>
|
||||
<p><block class="native linux android" /></p>
|
||||
<blockquote>
|
||||
<p>We recommend configuring <a href="https://developer.android.com/studio/run/emulator-acceleration.html#vm-linux">VM acceleration</a> on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.</p>
|
||||
|
||||
@@ -99,14 +99,14 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Button Basics"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
@@ -194,14 +194,14 @@ AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
<span class="hljs-attr">padding</span>: <span class="hljs-number">20</span>,
|
||||
<span class="hljs-attr">color</span>: <span class="hljs-string">'white'</span>
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
<span class="hljs-comment">// skip this line if using Create React Native App</span>
|
||||
AppRegistry.registerComponent(<span class="hljs-string">'AwesomeProject'</span>, () => Touchables);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Touchables"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-platform="android"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
@@ -99,14 +99,14 @@ const styles = StyleSheet.create({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Button Basics"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Button%2C%20StyleSheet%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20ButtonBasics%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.buttonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Press%20Me%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.alternativeLayoutButtonContainer%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22This%20looks%20great!%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3CButton%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22OK!%22%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3D%22%23841584%22%0A%20%20%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20flex%3A%201%2C%0A%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%7D%2C%0A%20%20buttonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%0A%20%20%7D%2C%0A%20%20alternativeLayoutButtonContainer%3A%20%7B%0A%20%20%20%20margin%3A%2020%2C%0A%20%20%20%20flexDirection%3A%20'row'%2C%0A%20%20%20%20justifyContent%3A%20'space-between'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20ButtonBasics)%3B%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
@@ -194,14 +194,14 @@ AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
|
||||
<span class="hljs-attr">padding</span>: <span class="hljs-number">20</span>,
|
||||
<span class="hljs-attr">color</span>: <span class="hljs-string">'white'</span>
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
<span class="hljs-comment">// skip this line if using Create React Native App</span>
|
||||
AppRegistry.registerComponent(<span class="hljs-string">'AwesomeProject'</span>, () => Touchables);
|
||||
</code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Touchables"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-code="import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20Alert%2C%20AppRegistry%2C%20Platform%2C%20StyleSheet%2C%20Text%2C%20TouchableHighlight%2C%20TouchableOpacity%2C%20TouchableNativeFeedback%2C%20TouchableWithoutFeedback%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20Touchables%20extends%20Component%20%7B%0A%20%20_onPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20tapped%20the%20button!')%0A%20%20%7D%0A%0A%20%20_onLongPressButton()%20%7B%0A%20%20%20%20Alert.alert('You%20long-pressed%20the%20button!')%0A%20%20%7D%0A%0A%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableHighlight%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%20%20%3CTouchableOpacity%20onPress%3D%7Bthis._onPressButton%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableOpacity%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableOpacity%3E%0A%20%20%20%20%20%20%20%20%3CTouchableNativeFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3D%7BPlatform.OS%20%3D%3D%3D%20'android'%20%3F%20TouchableNativeFeedback.SelectableBackground()%20%3A%20''%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableNativeFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableNativeFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableWithoutFeedback%0A%20%20%20%20%20%20%20%20%20%20%20%20onPress%3D%7Bthis._onPressButton%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchableWithoutFeedback%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableWithoutFeedback%3E%0A%20%20%20%20%20%20%20%20%3CTouchableHighlight%20onPress%3D%7Bthis._onPressButton%7D%20onLongPress%3D%7Bthis._onLongPressButton%7D%20underlayColor%3D%22white%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.button%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.buttonText%7D%3ETouchable%20with%20Long%20Press%3C%2FText%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20%20%20%3C%2FTouchableHighlight%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20paddingTop%3A%2060%2C%0A%20%20%20%20alignItems%3A%20'center'%0A%20%20%7D%2C%0A%20%20button%3A%20%7B%0A%20%20%20%20marginBottom%3A%2030%2C%0A%20%20%20%20width%3A%20260%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%232196F3'%0A%20%20%7D%2C%0A%20%20buttonText%3A%20%7B%0A%20%20%20%20padding%3A%2020%2C%0A%20%20%20%20color%3A%20'white'%0A%20%20%7D%0A%7D)%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20Touchables)%3B%0A"
|
||||
data-snack-platform="android"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<span class="hljs-comment">// do stuff</span>
|
||||
};
|
||||
</code></pre>
|
||||
<p>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).</p>
|
||||
<p>You can do anything in your task such as network requests, timers and so on, as long as it doesn't touch UI. 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).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="the-java-api"></a><a href="#the-java-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>The Java API</h2>
|
||||
<p>Yes, this does still require some native code, but it's pretty thin. You need to extend <code>HeadlessJsTaskService</code> and override <code>getTaskConfig</code>, e.g.:</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyTaskService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HeadlessJsTaskService</span> </span>{
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<span class="hljs-comment">// do stuff</span>
|
||||
};
|
||||
</code></pre>
|
||||
<p>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).</p>
|
||||
<p>You can do anything in your task such as network requests, timers and so on, as long as it doesn't touch UI. 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).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="the-java-api"></a><a href="#the-java-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>The Java API</h2>
|
||||
<p>Yes, this does still require some native code, but it's pretty thin. You need to extend <code>HeadlessJsTaskService</code> and override <code>getTaskConfig</code>, e.g.:</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyTaskService</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">HeadlessJsTaskService</span> </span>{
|
||||
|
||||
@@ -121,7 +121,7 @@ var icon = this.props.active
|
||||
style={{
|
||||
<span class="hljs-attr">width</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">height</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">resizeMode</span>: Image.resizeMode.contain,
|
||||
<span class="hljs-attr">resizeMode</span>: <span class="hljs-string">'contain'</span>,
|
||||
}}
|
||||
source={{
|
||||
<span class="hljs-attr">uri</span>:
|
||||
|
||||
@@ -121,7 +121,7 @@ var icon = this.props.active
|
||||
style={{
|
||||
<span class="hljs-attr">width</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">height</span>: <span class="hljs-number">51</span>,
|
||||
<span class="hljs-attr">resizeMode</span>: Image.resizeMode.contain,
|
||||
<span class="hljs-attr">resizeMode</span>: <span class="hljs-string">'contain'</span>,
|
||||
}}
|
||||
source={{
|
||||
<span class="hljs-attr">uri</span>:
|
||||
|
||||
@@ -46,20 +46,15 @@
|
||||
<li>Fellow developers write and publish React Native modules to npm and open source them on GitHub.</li>
|
||||
<li>Making modules helps grow the React Native ecosystem and community. We recommend writing modules for your use cases and sharing them on npm.</li>
|
||||
<li>Read the guides on Native Modules (<a href="/react-native/docs/0.11/native-modules-ios">iOS</a>, <a href="/react-native/docs/0.11/native-modules-android">Android</a>) and Native UI Components (<a href="/react-native/docs/0.11/native-components-ios">iOS</a>, <a href="/react-native/docs/0.11/native-components-android">Android</a>) if you are interested in extending native functionality.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a>.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a> or <a href="https://native.directory/">Native Directory</a> to find what the community has been creating.</li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="development-tools"></a><a href="#development-tools" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Development Tools</h2>
|
||||
<p><a href="https://nuclide.io/">Nuclide</a> 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. <a href="https://code.visualstudio.com/">VS Code</a> is another IDE that is popular with JavaScript developers.</p>
|
||||
<p><a href="https://github.com/infinitered/ignite">Ignite</a> 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.</p>
|
||||
<p><a href="https://microsoft.github.io/code-push/">CodePush</a> 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.</p>
|
||||
<p><a href="https://appcenter.ms/">App Center</a> 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 App Center a try.</p>
|
||||
<p><a href="https://docs.expo.io">Expo</a> 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.</p>
|
||||
<p><a href="https://yogalayout.com/">Yoga</a> is a stand-alone layout engine that extends beyond React Native and allows product engineers to build layouts quickly for multiple platforms with a highly optimized open source layout engine designed with speed, size, and ease of use in mind.</p>
|
||||
<p>The <a href="/react-native/docs/0.11/debugging#react-developer-tools">React Developer Tools</a> are great for debugging React and React Native apps.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="where-react-native-people-hang-out"></a><a href="#where-react-native-people-hang-out" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Where React Native People Hang Out</h2>
|
||||
<p>The <a href="https://discuss.reactjs.org/">forum at discuss.reactjs.org</a> is a great place for discussion about best practices and application architecture as well as the future of React Native.</p>
|
||||
<p><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux</a> 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.</p>
|
||||
<p>The <a href="https://twitter.com/reactjs">React Twitter account</a> covers both React and React Native. Follow the React Native <a href="https://twitter.com/reactnative">Twitter account</a> and <a href="/react-native/blog/">blog</a> to find out what's happening in the world of React Native.</p>
|
||||
<p>There are a lot of <a href="http://www.meetup.com/topics/react-native/">React Native Meetups</a> that happen around the world. Often there is React Native content in React meetups as well.</p>
|
||||
<p>Sometimes we have React conferences. We posted the <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS3fZ46IGFirdqKTIxlws7e0">videos from React.js Conf 2017</a>, <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY">React.js Conf 2016</a>, and <a href="https://www.youtube.com/watch?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr&v=KVZ-P-ZI6W4">React.js Conf 2015</a>. We'll probably have more conferences in the future, too. Stay tuned. You can also find a list of dedicated React Native conferences <a href="http://www.awesome-react-native.com/#conferences">here</a>.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/network">← Networking</a><a class="docs-next button" href="/react-native/docs/0.11/components-and-apis">Components and APIs →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -46,20 +46,15 @@
|
||||
<li>Fellow developers write and publish React Native modules to npm and open source them on GitHub.</li>
|
||||
<li>Making modules helps grow the React Native ecosystem and community. We recommend writing modules for your use cases and sharing them on npm.</li>
|
||||
<li>Read the guides on Native Modules (<a href="/react-native/docs/0.11/native-modules-ios">iOS</a>, <a href="/react-native/docs/0.11/native-modules-android">Android</a>) and Native UI Components (<a href="/react-native/docs/0.11/native-components-ios">iOS</a>, <a href="/react-native/docs/0.11/native-components-android">Android</a>) if you are interested in extending native functionality.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a>.</li>
|
||||
<li>Looking for a pre-built component? Check <a href="https://js.coach/react-native">JS.coach</a> or <a href="https://native.directory/">Native Directory</a> to find what the community has been creating.</li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="development-tools"></a><a href="#development-tools" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Development Tools</h2>
|
||||
<p><a href="https://nuclide.io/">Nuclide</a> 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. <a href="https://code.visualstudio.com/">VS Code</a> is another IDE that is popular with JavaScript developers.</p>
|
||||
<p><a href="https://github.com/infinitered/ignite">Ignite</a> 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.</p>
|
||||
<p><a href="https://microsoft.github.io/code-push/">CodePush</a> 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.</p>
|
||||
<p><a href="https://appcenter.ms/">App Center</a> 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 App Center a try.</p>
|
||||
<p><a href="https://docs.expo.io">Expo</a> 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.</p>
|
||||
<p><a href="https://yogalayout.com/">Yoga</a> is a stand-alone layout engine that extends beyond React Native and allows product engineers to build layouts quickly for multiple platforms with a highly optimized open source layout engine designed with speed, size, and ease of use in mind.</p>
|
||||
<p>The <a href="/react-native/docs/0.11/debugging#react-developer-tools">React Developer Tools</a> are great for debugging React and React Native apps.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="where-react-native-people-hang-out"></a><a href="#where-react-native-people-hang-out" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Where React Native People Hang Out</h2>
|
||||
<p>The <a href="https://discuss.reactjs.org/">forum at discuss.reactjs.org</a> is a great place for discussion about best practices and application architecture as well as the future of React Native.</p>
|
||||
<p><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux</a> 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.</p>
|
||||
<p>The <a href="https://twitter.com/reactjs">React Twitter account</a> covers both React and React Native. Follow the React Native <a href="https://twitter.com/reactnative">Twitter account</a> and <a href="/react-native/blog/">blog</a> to find out what's happening in the world of React Native.</p>
|
||||
<p>There are a lot of <a href="http://www.meetup.com/topics/react-native/">React Native Meetups</a> that happen around the world. Often there is React Native content in React meetups as well.</p>
|
||||
<p>Sometimes we have React conferences. We posted the <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS3fZ46IGFirdqKTIxlws7e0">videos from React.js Conf 2017</a>, <a href="https://www.youtube.com/playlist?list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY">React.js Conf 2016</a>, and <a href="https://www.youtube.com/watch?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr&v=KVZ-P-ZI6W4">React.js Conf 2015</a>. We'll probably have more conferences in the future, too. Stay tuned. You can also find a list of dedicated React Native conferences <a href="http://www.awesome-react-native.com/#conferences">here</a>.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/network">← Networking</a><a class="docs-next button" href="/react-native/docs/0.11/components-and-apis">Components and APIs →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -99,25 +99,21 @@
|
||||
}
|
||||
</code></pre>
|
||||
<h2><a class="anchor" aria-hidden="true" id="5-implement-the-javascript-module"></a><a href="#5-implement-the-javascript-module" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>5. Implement the JavaScript module</h2>
|
||||
<p>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 <code>propTypes</code>.</p>
|
||||
<p>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. It is recommended for you to document the component interface in this module (e.g. using Flow, TypeScript, or plain old comments).</p>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-comment">// ImageView.js</span>
|
||||
|
||||
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">'prop-types'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent, ViewPropTypes} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
|
||||
<span class="hljs-keyword">var</span> iface = {
|
||||
<span class="hljs-attr">name</span>: <span class="hljs-string">'ImageView'</span>,
|
||||
<span class="hljs-attr">propTypes</span>: {
|
||||
<span class="hljs-attr">src</span>: PropTypes.string,
|
||||
<span class="hljs-attr">borderRadius</span>: PropTypes.number,
|
||||
<span class="hljs-attr">resizeMode</span>: PropTypes.oneOf([<span class="hljs-string">'cover'</span>, <span class="hljs-string">'contain'</span>, <span class="hljs-string">'stretch'</span>]),
|
||||
...ViewPropTypes, <span class="hljs-comment">// include the default view properties</span>
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>, iface);
|
||||
<span class="hljs-comment">/**
|
||||
* Composes `View`.
|
||||
*
|
||||
* - src: string
|
||||
* - borderRadius: number
|
||||
* - resizeMode: 'cover' | 'contain' | 'stretch'
|
||||
*/</span>
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>);
|
||||
</code></pre>
|
||||
<p><code>requireNativeComponent</code> 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 <code>name</code> for use in debug messages and must declare the <code>propTypes</code> reflected by the Native View. The <code>propTypes</code> 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 <code>iface</code> to <code>requireNativeComponent</code>. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<p>The <code>requireNativeComponent</code> function takes the name of the native view. Note that if your component needs to do anything more sophisticated (e.g. custom event handling), you should wrap the native component in another React component. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<h1><a class="anchor" aria-hidden="true" id="events"></a><a href="#events" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Events</h1>
|
||||
<p>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 <code>getId()</code> method.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyCustomView</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">View</span> </span>{
|
||||
@@ -173,11 +169,8 @@ MyCustomView.propTypes = {
|
||||
...
|
||||
};
|
||||
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`, MyCustomView, {
|
||||
nativeOnly: {onChange: true}
|
||||
});
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`);
|
||||
</span></code></pre>
|
||||
<p>Note the use of <code>nativeOnly</code> 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, <code>Switch</code> has a custom <code>onChange</code> handler for the raw native event, and exposes an <code>onValueChange</code> handler property that is invoked with just the boolean value rather than the raw event (similar to <code>onChangeMessage</code> 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 <code>propTypes</code>, but if you don't you'll get an error. The solution is simply to call them out via the <code>nativeOnly</code> option.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/native-modules-android">← Native Modules</a><a class="docs-next button" href="/react-native/docs/0.11/headless-js-android">Headless JS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -99,25 +99,21 @@
|
||||
}
|
||||
</code></pre>
|
||||
<h2><a class="anchor" aria-hidden="true" id="5-implement-the-javascript-module"></a><a href="#5-implement-the-javascript-module" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>5. Implement the JavaScript module</h2>
|
||||
<p>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 <code>propTypes</code>.</p>
|
||||
<p>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. It is recommended for you to document the component interface in this module (e.g. using Flow, TypeScript, or plain old comments).</p>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-comment">// ImageView.js</span>
|
||||
|
||||
<span class="hljs-keyword">import</span> PropTypes <span class="hljs-keyword">from</span> <span class="hljs-string">'prop-types'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent, ViewPropTypes} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
<span class="hljs-keyword">import</span> {requireNativeComponent} <span class="hljs-keyword">from</span> <span class="hljs-string">'react-native'</span>;
|
||||
|
||||
<span class="hljs-keyword">var</span> iface = {
|
||||
<span class="hljs-attr">name</span>: <span class="hljs-string">'ImageView'</span>,
|
||||
<span class="hljs-attr">propTypes</span>: {
|
||||
<span class="hljs-attr">src</span>: PropTypes.string,
|
||||
<span class="hljs-attr">borderRadius</span>: PropTypes.number,
|
||||
<span class="hljs-attr">resizeMode</span>: PropTypes.oneOf([<span class="hljs-string">'cover'</span>, <span class="hljs-string">'contain'</span>, <span class="hljs-string">'stretch'</span>]),
|
||||
...ViewPropTypes, <span class="hljs-comment">// include the default view properties</span>
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>, iface);
|
||||
<span class="hljs-comment">/**
|
||||
* Composes `View`.
|
||||
*
|
||||
* - src: string
|
||||
* - borderRadius: number
|
||||
* - resizeMode: 'cover' | 'contain' | 'stretch'
|
||||
*/</span>
|
||||
<span class="hljs-built_in">module</span>.exports = requireNativeComponent(<span class="hljs-string">'RCTImageView'</span>);
|
||||
</code></pre>
|
||||
<p><code>requireNativeComponent</code> 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 <code>name</code> for use in debug messages and must declare the <code>propTypes</code> reflected by the Native View. The <code>propTypes</code> 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 <code>iface</code> to <code>requireNativeComponent</code>. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<p>The <code>requireNativeComponent</code> function takes the name of the native view. Note that if your component needs to do anything more sophisticated (e.g. custom event handling), you should wrap the native component in another React component. This is illustrated in the <code>MyCustomView</code> example below.</p>
|
||||
<h1><a class="anchor" aria-hidden="true" id="events"></a><a href="#events" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Events</h1>
|
||||
<p>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 <code>getId()</code> method.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyCustomView</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">View</span> </span>{
|
||||
@@ -173,11 +169,8 @@ MyCustomView.propTypes = {
|
||||
...
|
||||
};
|
||||
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`, MyCustomView, {
|
||||
nativeOnly: {onChange: true}
|
||||
});
|
||||
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`);
|
||||
</span></code></pre>
|
||||
<p>Note the use of <code>nativeOnly</code> 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, <code>Switch</code> has a custom <code>onChange</code> handler for the raw native event, and exposes an <code>onValueChange</code> handler property that is invoked with just the boolean value rather than the raw event (similar to <code>onChangeMessage</code> 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 <code>propTypes</code>, but if you don't you'll get an error. The solution is simply to call them out via the <code>nativeOnly</code> option.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/native-modules-android">← Native Modules</a><a class="docs-next button" href="/react-native/docs/0.11/headless-js-android">Headless JS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -137,7 +137,13 @@ R<span class="hljs-function"><span class="hljs-title">eadableArray</span> -><
|
||||
}
|
||||
</code></pre>
|
||||
<p>The package needs to be provided in the <code>getPackages</code> method of the <code>MainApplication.java</code> file. This file exists under the android folder in your react-native application directory. The path to this file is: <code>android/app/src/main/java/com/your-app-name/MainApplication.java</code>.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<pre><code class="hljs css language-java"><span class="hljs-comment">// MainApplication.java</span>
|
||||
|
||||
...
|
||||
<span class="hljs-keyword">import</span> com.your-app-name.CustomToastPackage; <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
...
|
||||
|
||||
<span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<span class="hljs-keyword">return</span> Arrays.<ReactPackage>asList(
|
||||
<span class="hljs-keyword">new</span> MainReactPackage(),
|
||||
<span class="hljs-keyword">new</span> CustomToastPackage()); <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
|
||||
@@ -137,7 +137,13 @@ R<span class="hljs-function"><span class="hljs-title">eadableArray</span> -><
|
||||
}
|
||||
</code></pre>
|
||||
<p>The package needs to be provided in the <code>getPackages</code> method of the <code>MainApplication.java</code> file. This file exists under the android folder in your react-native application directory. The path to this file is: <code>android/app/src/main/java/com/your-app-name/MainApplication.java</code>.</p>
|
||||
<pre><code class="hljs css language-java"><span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<pre><code class="hljs css language-java"><span class="hljs-comment">// MainApplication.java</span>
|
||||
|
||||
...
|
||||
<span class="hljs-keyword">import</span> com.your-app-name.CustomToastPackage; <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
...
|
||||
|
||||
<span class="hljs-function"><span class="hljs-keyword">protected</span> List<ReactPackage> <span class="hljs-title">getPackages</span><span class="hljs-params">()</span> </span>{
|
||||
<span class="hljs-keyword">return</span> Arrays.<ReactPackage>asList(
|
||||
<span class="hljs-keyword">new</span> MainReactPackage(),
|
||||
<span class="hljs-keyword">new</span> CustomToastPackage()); <span class="hljs-comment">// <-- Add this line with your package name.</span>
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/navigation.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Navigating Between Screens</h1></header><article><div><span><p>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.</p>
|
||||
<p>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 <a href="/react-native/docs/0.11/navigation#react-navigation">React Navigation</a>. 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 <a href="https://reactnavigation.org/docs/redux-integration.html">redux</a>.</p>
|
||||
<p>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 <a href="/react-native/docs/0.11/navigation#react-navigation">React Navigation</a>. 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.</p>
|
||||
<p>If you're only targeting iOS, you may want to also check out <a href="/react-native/docs/0.11/navigation#navigatorios">NavigatorIOS</a> as a way of providing a native look and feel with minimal configuration, as it provides a wrapper around the native <code>UINavigationController</code> class. This component will not work on Android, however.</p>
|
||||
<p>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: <a href="http://airbnb.io/native-navigation/">native-navigation</a>, <a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<p>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 library provides native navigation on both platforms:<a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="react-navigation"></a><a href="#react-navigation" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>React Navigation</h2>
|
||||
<p>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.</p>
|
||||
<p>The first step is to install in your project:</p>
|
||||
@@ -72,7 +72,7 @@ export <span class="hljs-keyword">default</span> App;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>React Navigation routers make it easy to override navigation logic. Because routers can be nested inside each other, developers can override navigation logic for one area of the app without making widespread changes.</p>
|
||||
<p>The views in React Navigation use native components and the <a href="/react-native/docs/0.11/animated"><code>Animated</code></a> library to deliver 60fps animations that are run on the native thread. Plus, the animations and gestures can be easily customized.</p>
|
||||
<p>For a complete intro to React Navigation, follow the <a href="https://reactnavigation.org/docs/getting-started.html">React Navigation Getting Started Guide</a>, or browse other docs such as the <a href="https://expo.io/@react-navigation/NavigationPlayground">Intro to Navigators</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="navigatorios"></a><a href="#navigatorios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>NavigatorIOS</h2>
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/navigation.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Navigating Between Screens</h1></header><article><div><span><p>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.</p>
|
||||
<p>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 <a href="/react-native/docs/0.11/navigation#react-navigation">React Navigation</a>. 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 <a href="https://reactnavigation.org/docs/redux-integration.html">redux</a>.</p>
|
||||
<p>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 <a href="/react-native/docs/0.11/navigation#react-navigation">React Navigation</a>. 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.</p>
|
||||
<p>If you're only targeting iOS, you may want to also check out <a href="/react-native/docs/0.11/navigation#navigatorios">NavigatorIOS</a> as a way of providing a native look and feel with minimal configuration, as it provides a wrapper around the native <code>UINavigationController</code> class. This component will not work on Android, however.</p>
|
||||
<p>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: <a href="http://airbnb.io/native-navigation/">native-navigation</a>, <a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<p>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 library provides native navigation on both platforms:<a href="https://github.com/wix/react-native-navigation">react-native-navigation</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="react-navigation"></a><a href="#react-navigation" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>React Navigation</h2>
|
||||
<p>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.</p>
|
||||
<p>The first step is to install in your project:</p>
|
||||
@@ -72,7 +72,7 @@ export <span class="hljs-keyword">default</span> App;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>React Navigation routers make it easy to override navigation logic. Because routers can be nested inside each other, developers can override navigation logic for one area of the app without making widespread changes.</p>
|
||||
<p>The views in React Navigation use native components and the <a href="/react-native/docs/0.11/animated"><code>Animated</code></a> library to deliver 60fps animations that are run on the native thread. Plus, the animations and gestures can be easily customized.</p>
|
||||
<p>For a complete intro to React Navigation, follow the <a href="https://reactnavigation.org/docs/getting-started.html">React Navigation Getting Started Guide</a>, or browse other docs such as the <a href="https://expo.io/@react-navigation/NavigationPlayground">Intro to Navigators</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="navigatorios"></a><a href="#navigatorios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>NavigatorIOS</h2>
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<span class="hljs-tag"><<span class="hljs-name">FlatList</span>
|
||||
<span class="hljs-attr">data</span>=<span class="hljs-string">{this.state.dataSource}</span>
|
||||
<span class="hljs-attr">renderItem</span>=<span class="hljs-string">{({item})</span> =></span> <span class="hljs-tag"><<span class="hljs-name">Text</span>></span>{item.title}, {item.releaseYear}<span class="hljs-tag"></<span class="hljs-name">Text</span>></span>}
|
||||
keyExtractor={(item, index) => index}
|
||||
keyExtractor={({id}, index) => id}
|
||||
/>
|
||||
<span class="hljs-tag"></<span class="hljs-name">View</span>></span>
|
||||
);
|
||||
@@ -136,7 +136,7 @@
|
||||
</span></code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Fetch Example"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(item%2C%20index)%20%3D%3E%20index%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(%7Bid%7D%2C%20index)%20%3D%3E%20id%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
<span class="hljs-tag"><<span class="hljs-name">FlatList</span>
|
||||
<span class="hljs-attr">data</span>=<span class="hljs-string">{this.state.dataSource}</span>
|
||||
<span class="hljs-attr">renderItem</span>=<span class="hljs-string">{({item})</span> =></span> <span class="hljs-tag"><<span class="hljs-name">Text</span>></span>{item.title}, {item.releaseYear}<span class="hljs-tag"></<span class="hljs-name">Text</span>></span>}
|
||||
keyExtractor={(item, index) => index}
|
||||
keyExtractor={({id}, index) => id}
|
||||
/>
|
||||
<span class="hljs-tag"></<span class="hljs-name">View</span>></span>
|
||||
);
|
||||
@@ -136,7 +136,7 @@
|
||||
</span></code></pre></div><div class="desktop-friendly-snack" style="margin-top: 15px; margin-bottom: 15px"><div
|
||||
data-snack-name="Fetch Example"
|
||||
data-snack-description="Example usage"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(item%2C%20index)%20%3D%3E%20index%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-code="import%20React%20from%20'react'%3B%0Aimport%20%7B%20FlatList%2C%20ActivityIndicator%2C%20Text%2C%20View%20%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20FetchExample%20extends%20React.Component%20%7B%0A%0A%20%20constructor(props)%7B%0A%20%20%20%20super(props)%3B%0A%20%20%20%20this.state%20%3D%7B%20isLoading%3A%20true%7D%0A%20%20%7D%0A%0A%20%20componentDidMount()%7B%0A%20%20%20%20return%20fetch('https%3A%2F%2Ffacebook.github.io%2Freact-native%2Fmovies.json')%0A%20%20%20%20%20%20.then((response)%20%3D%3E%20response.json())%0A%20%20%20%20%20%20.then((responseJson)%20%3D%3E%20%7B%0A%0A%20%20%20%20%20%20%20%20this.setState(%7B%0A%20%20%20%20%20%20%20%20%20%20isLoading%3A%20false%2C%0A%20%20%20%20%20%20%20%20%20%20dataSource%3A%20responseJson.movies%2C%0A%20%20%20%20%20%20%20%20%7D%2C%20function()%7B%0A%0A%20%20%20%20%20%20%20%20%7D)%3B%0A%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20.catch((error)%20%3D%3E%7B%0A%20%20%20%20%20%20%20%20console.error(error)%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%0A%0A%20%20render()%7B%0A%0A%20%20%20%20if(this.state.isLoading)%7B%0A%20%20%20%20%20%20return(%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20padding%3A%2020%7D%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%3CActivityIndicator%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20%20%20)%0A%20%20%20%20%7D%0A%0A%20%20%20%20return(%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7Bflex%3A%201%2C%20paddingTop%3A20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CFlatList%0A%20%20%20%20%20%20%20%20%20%20data%3D%7Bthis.state.dataSource%7D%0A%20%20%20%20%20%20%20%20%20%20renderItem%3D%7B(%7Bitem%7D)%20%3D%3E%20%3CText%3E%7Bitem.title%7D%2C%20%7Bitem.releaseYear%7D%3C%2FText%3E%7D%0A%20%20%20%20%20%20%20%20%20%20keyExtractor%3D%7B(%7Bid%7D%2C%20index)%20%3D%3E%20id%7D%0A%20%20%20%20%20%20%20%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A"
|
||||
data-snack-platform="ios"
|
||||
data-snack-preview="true"
|
||||
data-snack-sdk-version="26.0.0"
|
||||
|
||||
+43
-87
@@ -185,10 +185,10 @@
|
||||
<p><img src="/react-native/docs/assets/SystraceBadCreateUI.png" alt="Creating Views"></p>
|
||||
<p>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.</p>
|
||||
<p>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 an 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.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="unbundling-inline-requires"></a><a href="#unbundling-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Unbundling + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider unbundling and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the unbundle feature of the packager and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="ram-bundles-inline-requires"></a><a href="#ram-bundles-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RAM bundles + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider the Random Access Modules (RAM) bundle format, and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the RAM format and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="loading-javascript"></a><a href="#loading-javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loading JavaScript</h3>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind unbundling is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind RAM bundles is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inline-requires"></a><a href="#inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inline Requires</h3>
|
||||
<p>Inline requires delay the requiring of a module or file until that file is actually needed. A basic example would look like this:</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="veryexpensivejs"></a><a href="#veryexpensivejs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>VeryExpensive.js</h4>
|
||||
@@ -237,48 +237,50 @@ export <span class="hljs-keyword">default</span> <span class="hljs-class"><span
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Even without unbundling inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-unbundling"></a><a href="#enable-unbundling" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable Unbundling</h3>
|
||||
<p>On iOS unbundling will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable unbundling in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/packager/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="unbundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<p>Even without the RAM format, inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-the-ram-format"></a><a href="#enable-the-ram-format" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable the RAM format</h3>
|
||||
<p>On iOS using the RAM format will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable the RAM format in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/scripts/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="ram-bundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>On Android enable unbundling by editing your android/app/build.gradle file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<p>On Android enable the RAM format by editing your <code>android/app/build.gradle</code> file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
]
|
||||
</code></pre>
|
||||
<p>Use the following lines on Android if you want to use a single indexed file:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-unbundle"</span>]
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-ram-bundle"</span>]
|
||||
]
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="configure-preloading-and-inline-requires"></a><a href="#configure-preloading-and-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure Preloading and Inline Requires</h3>
|
||||
<p>Now that we have unbundled our code, there is overhead for calling require. require now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<p>Now that we have a RAM bundle, there is overhead for calling <code>require</code>. <code>require</code> now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-a-packager-config-file"></a><a href="#adding-a-packager-config-file" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding a packager config file</h3>
|
||||
<p>Create a folder in your project called packager, and create a single file named config.js. Add the following:</p>
|
||||
<pre><code class="hljs">const<span class="hljs-built_in"> config </span>= {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
transformer: {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports =<span class="hljs-built_in"> config;
|
||||
</span></code></pre>
|
||||
<p>In Xcode, in the build phase, include <code>export BUNDLE_CONFIG="packager/config.js"</code>.</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_CONFIG</span>=<span class="hljs-string">"packager/config.js"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>Edit your android/app/build.gradle file to include <code>bundleConfig: "packager/config.js",</code>.</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
bundleConfig: <span class="hljs-string">"packager/config.js"</span>
|
||||
]
|
||||
</code></pre>
|
||||
@@ -304,7 +306,7 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
waitingModuleNames.length
|
||||
);
|
||||
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/moduleNames.js</span>
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/modulePaths.js</span>
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`module.exports = <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(loadedModuleNames.sort())}</span>;`</span>);
|
||||
</code></pre>
|
||||
<p>When you run your app, you can look in the console and see how many modules have been loaded, and how many are waiting. You may want to read the moduleNames and see if there are any surprises. Note that inline requires are invoked the first time the imports are referenced. You may need to investigate and refactor to ensure only the modules you want are loaded on startup. Note that you can change the Systrace object on require to help debug problematic requires.</p>
|
||||
@@ -314,84 +316,38 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named packager/moduleNames.js.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="transforming-to-module-paths"></a><a href="#transforming-to-module-paths" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Transforming to Module Paths</h3>
|
||||
<p>The loaded module names get us part of the way there, but we actually need absolute module paths, so the next script will set that up. Add <code>packager/generateModulePaths.js</code> to your project with the following:</p>
|
||||
<pre><code class="hljs"><span class="hljs-comment">// @flow</span>
|
||||
<span class="hljs-comment">/* eslint-disable no-console */</span>
|
||||
<span class="hljs-keyword">const</span> execSync = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).execSync;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
<span class="hljs-keyword">const</span> moduleNames = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./moduleNames'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> pjson = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../package.json'</span>);
|
||||
<span class="hljs-keyword">const</span> localPrefix = <span class="hljs-string">`<span class="hljs-subst">${pjson.name}</span>/`</span>;
|
||||
|
||||
<span class="hljs-keyword">const</span> modulePaths = moduleNames.map(<span class="hljs-function"><span class="hljs-params">moduleName</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (moduleName.startsWith(localPrefix)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./<span class="hljs-subst">${moduleName.substring(localPrefix.length)}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">if</span> (moduleName.endsWith(<span class="hljs-string">'.js'</span>)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./node_modules/<span class="hljs-subst">${moduleName}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">try</span> {
|
||||
<span class="hljs-keyword">const</span> result = execSync(
|
||||
<span class="hljs-string">`grep "@providesModule <span class="hljs-subst">${moduleName}</span>" $(find . -name <span class="hljs-subst">${moduleName}</span>\\\\.js) -l`</span>
|
||||
)
|
||||
.toString()
|
||||
.trim()
|
||||
.split(<span class="hljs-string">'\n'</span>)[<span class="hljs-number">0</span>];
|
||||
<span class="hljs-keyword">if</span> (result != <span class="hljs-literal">null</span>) {
|
||||
<span class="hljs-keyword">return</span> result;
|
||||
}
|
||||
} <span class="hljs-keyword">catch</span> (e) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
}
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
});
|
||||
|
||||
<span class="hljs-keyword">const</span> paths = modulePaths
|
||||
.filter(<span class="hljs-function"><span class="hljs-params">path</span> =></span> path != <span class="hljs-literal">null</span>)
|
||||
.map(<span class="hljs-function"><span class="hljs-params">path</span> =></span> <span class="hljs-string">`'<span class="hljs-subst">${path}</span>'`</span>)
|
||||
.join(<span class="hljs-string">',\n'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> fileData = <span class="hljs-string">`module.exports = [<span class="hljs-subst">${paths}</span>];`</span>;
|
||||
|
||||
fs.writeFile(<span class="hljs-string">'./packager/modulePaths.js'</span>, fileData, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (err) {
|
||||
<span class="hljs-built_in">console</span>.log(err);
|
||||
}
|
||||
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Done'</span>);
|
||||
});
|
||||
</code></pre>
|
||||
<p>You can run via <code>node packager/generateModulePaths.js</code>.</p>
|
||||
<p>This script attempts to map from the module names to module paths. Its not foolproof though, for instance, it ignores platform specific files (*ios.js, and *.android.js). However based on initial testing, it handles 95% of cases. When it runs, after some time it should complete and output a file named <code>packager/modulePaths.js</code>. It should contain paths to module files that are relative to your projects root. You can commit modulePaths.js to your repo so it is transportable.</p>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named <code>packager/modulePaths.js</code>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="updating-the-configjs"></a><a href="#updating-the-configjs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Updating the config.js</h3>
|
||||
<p>Returning to packager/config.js we should update it to use our newly generated modulePaths.js file.</p>
|
||||
<pre><code class="hljs"><span class="hljs-keyword">const</span> modulePaths = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./modulePaths'</span>);
|
||||
<span class="hljs-keyword">const</span> resolve = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).resolve;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
|
||||
<span class="hljs-comment">// Update the following line if the root folder of your app is somewhere else.</span>
|
||||
<span class="hljs-keyword">const</span> ROOT_FOLDER = path.resolve(__dirname, <span class="hljs-string">'..'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> config = {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
<span class="hljs-attr">transformer</span>: {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = config;
|
||||
</code></pre>
|
||||
<p>The preloadedModules entry in the config indicates which modules should be marked as preloaded by the unbundler. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<p>The <code>preloadedModules</code> entry in the config indicates which modules should be marked as preloaded when building a RAM bundle. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="test-and-measure-improvements"></a><a href="#test-and-measure-improvements" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Test and Measure Improvements</h3>
|
||||
<p>You should now be ready to build your app using unbundling and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
<p>You should now be ready to build your app using the RAM format and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/debugging">← Debugging</a><a class="docs-next button" href="/react-native/docs/0.11/gesture-responder-system">Gesture Responder System →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -185,10 +185,10 @@
|
||||
<p><img src="/react-native/docs/assets/SystraceBadCreateUI.png" alt="Creating Views"></p>
|
||||
<p>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.</p>
|
||||
<p>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 an 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.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="unbundling-inline-requires"></a><a href="#unbundling-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Unbundling + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider unbundling and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the unbundle feature of the packager and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="ram-bundles-inline-requires"></a><a href="#ram-bundles-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>RAM bundles + inline requires</h2>
|
||||
<p>If you have a large app you may want to consider the Random Access Modules (RAM) bundle format, and using inline requires. This is useful for apps that have a large number of screens which may not ever be opened during a typical usage of the app. Generally it is useful to apps that have large amounts of code that are not needed for a while after startup. For instance the app includes complicated profile screens or lesser used features, but most sessions only involve visiting the main screen of the app for updates. We can optimize the loading of the bundle by using the RAM format and requiring those features and screens inline (when they are actually used).</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="loading-javascript"></a><a href="#loading-javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Loading JavaScript</h3>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind unbundling is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<p>Before react-native can execute JS code, that code must be loaded into memory and parsed. With a standard bundle if you load a 50mb bundle, all 50mb must be loaded and parsed before any of it can be executed. The optimization behind RAM bundles is that you can load only the portion of the 50mb that you actually need at startup, and progressively load more of the bundle as those sections are needed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inline-requires"></a><a href="#inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inline Requires</h3>
|
||||
<p>Inline requires delay the requiring of a module or file until that file is actually needed. A basic example would look like this:</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="veryexpensivejs"></a><a href="#veryexpensivejs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>VeryExpensive.js</h4>
|
||||
@@ -237,48 +237,50 @@ export <span class="hljs-keyword">default</span> <span class="hljs-class"><span
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Even without unbundling inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-unbundling"></a><a href="#enable-unbundling" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable Unbundling</h3>
|
||||
<p>On iOS unbundling will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable unbundling in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/packager/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="unbundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<p>Even without the RAM format, inline requires can lead to startup time improvements, because the code within VeryExpensive.js will only execute once it is required for the first time.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="enable-the-ram-format"></a><a href="#enable-the-ram-format" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Enable the RAM format</h3>
|
||||
<p>On iOS using the RAM format will create a single indexed file that react native will load one module at a time. On Android, by default it will create a set of files for each module. You can force Android to create a single file, like iOS, but using multiple files can be more performant and requires less memory.</p>
|
||||
<p>Enable the RAM format in Xcode by editing the build phase "Bundle React Native code and images". Before <code>../node_modules/react-native/scripts/react-native-xcode.sh</code> add <code>export BUNDLE_COMMAND="ram-bundle"</code>:</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>On Android enable unbundling by editing your android/app/build.gradle file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<p>On Android enable the RAM format by editing your <code>android/app/build.gradle</code> file. Before the line <code>apply from: "../../node_modules/react-native/react.gradle"</code> add or amend the <code>project.ext.react</code> block:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
]
|
||||
</code></pre>
|
||||
<p>Use the following lines on Android if you want to use a single indexed file:</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-unbundle"</span>]
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
extraPackagerArgs: [<span class="hljs-string">"--indexed-ram-bundle"</span>]
|
||||
]
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="configure-preloading-and-inline-requires"></a><a href="#configure-preloading-and-inline-requires" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Configure Preloading and Inline Requires</h3>
|
||||
<p>Now that we have unbundled our code, there is overhead for calling require. require now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<p>Now that we have a RAM bundle, there is overhead for calling <code>require</code>. <code>require</code> now needs to send a message over the bridge when it encounters a module it has not loaded yet. This will impact startup the most, because that is where the largest number of require calls are likely to take place while the app loads the initial module. Luckily we can configure a portion of the modules to be preloaded. In order to do this, you will need to implement some form of inline require.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-a-packager-config-file"></a><a href="#adding-a-packager-config-file" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding a packager config file</h3>
|
||||
<p>Create a folder in your project called packager, and create a single file named config.js. Add the following:</p>
|
||||
<pre><code class="hljs">const<span class="hljs-built_in"> config </span>= {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
transformer: {
|
||||
getTransformOptions: () => {
|
||||
return {
|
||||
transform: { inlineRequires: <span class="hljs-literal">true</span> },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports =<span class="hljs-built_in"> config;
|
||||
</span></code></pre>
|
||||
<p>In Xcode, in the build phase, include <code>export BUNDLE_CONFIG="packager/config.js"</code>.</p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"unbundle"</span>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_COMMAND</span>=<span class="hljs-string">"ram-bundle"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">BUNDLE_CONFIG</span>=<span class="hljs-string">"packager/config.js"</span>
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">NODE_BINARY</span>=node
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/packager/react-native-xcode.sh
|
||||
<span class="hljs-built_in">..</span>/node_modules/react-native/scripts/react-native-xcode.sh
|
||||
</code></pre>
|
||||
<p>Edit your android/app/build.gradle file to include <code>bundleConfig: "packager/config.js",</code>.</p>
|
||||
<pre><code class="hljs">project<span class="hljs-selector-class">.ext</span><span class="hljs-selector-class">.react</span> = [
|
||||
bundleCommand: <span class="hljs-string">"unbundle"</span>,
|
||||
bundleCommand: <span class="hljs-string">"ram-bundle"</span>,
|
||||
bundleConfig: <span class="hljs-string">"packager/config.js"</span>
|
||||
]
|
||||
</code></pre>
|
||||
@@ -304,7 +306,7 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
waitingModuleNames.length
|
||||
);
|
||||
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/moduleNames.js</span>
|
||||
<span class="hljs-comment">// grab this text blob, and put it in a file named packager/modulePaths.js</span>
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`module.exports = <span class="hljs-subst">${<span class="hljs-built_in">JSON</span>.stringify(loadedModuleNames.sort())}</span>;`</span>);
|
||||
</code></pre>
|
||||
<p>When you run your app, you can look in the console and see how many modules have been loaded, and how many are waiting. You may want to read the moduleNames and see if there are any surprises. Note that inline requires are invoked the first time the imports are referenced. You may need to investigate and refactor to ensure only the modules you want are loaded on startup. Note that you can change the Systrace object on require to help debug problematic requires.</p>
|
||||
@@ -314,84 +316,38 @@ module.exports =<span class="hljs-built_in"> config;
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named packager/moduleNames.js.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="transforming-to-module-paths"></a><a href="#transforming-to-module-paths" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Transforming to Module Paths</h3>
|
||||
<p>The loaded module names get us part of the way there, but we actually need absolute module paths, so the next script will set that up. Add <code>packager/generateModulePaths.js</code> to your project with the following:</p>
|
||||
<pre><code class="hljs"><span class="hljs-comment">// @flow</span>
|
||||
<span class="hljs-comment">/* eslint-disable no-console */</span>
|
||||
<span class="hljs-keyword">const</span> execSync = <span class="hljs-built_in">require</span>(<span class="hljs-string">'child_process'</span>).execSync;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
<span class="hljs-keyword">const</span> moduleNames = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./moduleNames'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> pjson = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../package.json'</span>);
|
||||
<span class="hljs-keyword">const</span> localPrefix = <span class="hljs-string">`<span class="hljs-subst">${pjson.name}</span>/`</span>;
|
||||
|
||||
<span class="hljs-keyword">const</span> modulePaths = moduleNames.map(<span class="hljs-function"><span class="hljs-params">moduleName</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (moduleName.startsWith(localPrefix)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./<span class="hljs-subst">${moduleName.substring(localPrefix.length)}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">if</span> (moduleName.endsWith(<span class="hljs-string">'.js'</span>)) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-string">`./node_modules/<span class="hljs-subst">${moduleName}</span>`</span>;
|
||||
}
|
||||
<span class="hljs-keyword">try</span> {
|
||||
<span class="hljs-keyword">const</span> result = execSync(
|
||||
<span class="hljs-string">`grep "@providesModule <span class="hljs-subst">${moduleName}</span>" $(find . -name <span class="hljs-subst">${moduleName}</span>\\\\.js) -l`</span>
|
||||
)
|
||||
.toString()
|
||||
.trim()
|
||||
.split(<span class="hljs-string">'\n'</span>)[<span class="hljs-number">0</span>];
|
||||
<span class="hljs-keyword">if</span> (result != <span class="hljs-literal">null</span>) {
|
||||
<span class="hljs-keyword">return</span> result;
|
||||
}
|
||||
} <span class="hljs-keyword">catch</span> (e) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
}
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||||
});
|
||||
|
||||
<span class="hljs-keyword">const</span> paths = modulePaths
|
||||
.filter(<span class="hljs-function"><span class="hljs-params">path</span> =></span> path != <span class="hljs-literal">null</span>)
|
||||
.map(<span class="hljs-function"><span class="hljs-params">path</span> =></span> <span class="hljs-string">`'<span class="hljs-subst">${path}</span>'`</span>)
|
||||
.join(<span class="hljs-string">',\n'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> fileData = <span class="hljs-string">`module.exports = [<span class="hljs-subst">${paths}</span>];`</span>;
|
||||
|
||||
fs.writeFile(<span class="hljs-string">'./packager/modulePaths.js'</span>, fileData, <span class="hljs-function"><span class="hljs-params">err</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (err) {
|
||||
<span class="hljs-built_in">console</span>.log(err);
|
||||
}
|
||||
|
||||
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Done'</span>);
|
||||
});
|
||||
</code></pre>
|
||||
<p>You can run via <code>node packager/generateModulePaths.js</code>.</p>
|
||||
<p>This script attempts to map from the module names to module paths. Its not foolproof though, for instance, it ignores platform specific files (*ios.js, and *.android.js). However based on initial testing, it handles 95% of cases. When it runs, after some time it should complete and output a file named <code>packager/modulePaths.js</code>. It should contain paths to module files that are relative to your projects root. You can commit modulePaths.js to your repo so it is transportable.</p>
|
||||
<p>Every app is different, but it may make sense to only load the modules you need for the very first screen. When you are satisified, put the output of the loadedModuleNames into a file named <code>packager/modulePaths.js</code>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="updating-the-configjs"></a><a href="#updating-the-configjs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Updating the config.js</h3>
|
||||
<p>Returning to packager/config.js we should update it to use our newly generated modulePaths.js file.</p>
|
||||
<pre><code class="hljs"><span class="hljs-keyword">const</span> modulePaths = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./modulePaths'</span>);
|
||||
<span class="hljs-keyword">const</span> resolve = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>).resolve;
|
||||
<span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
|
||||
|
||||
<span class="hljs-comment">// Update the following line if the root folder of your app is somewhere else.</span>
|
||||
<span class="hljs-keyword">const</span> ROOT_FOLDER = path.resolve(__dirname, <span class="hljs-string">'..'</span>);
|
||||
|
||||
<span class="hljs-keyword">const</span> config = {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
<span class="hljs-attr">transformer</span>: {
|
||||
<span class="hljs-attr">getTransformOptions</span>: <span class="hljs-function"><span class="hljs-params">()</span> =></span> {
|
||||
<span class="hljs-keyword">const</span> moduleMap = {};
|
||||
modulePaths.forEach(<span class="hljs-function"><span class="hljs-params">path</span> =></span> {
|
||||
<span class="hljs-keyword">if</span> (fs.existsSync(path)) {
|
||||
moduleMap[resolve(path)] = <span class="hljs-literal">true</span>;
|
||||
}
|
||||
});
|
||||
<span class="hljs-keyword">return</span> {
|
||||
<span class="hljs-attr">preloadedModules</span>: moduleMap,
|
||||
<span class="hljs-attr">transform</span>: { <span class="hljs-attr">inlineRequires</span>: { <span class="hljs-attr">blacklist</span>: moduleMap } },
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
<span class="hljs-built_in">module</span>.exports = config;
|
||||
</code></pre>
|
||||
<p>The preloadedModules entry in the config indicates which modules should be marked as preloaded by the unbundler. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<p>The <code>preloadedModules</code> entry in the config indicates which modules should be marked as preloaded when building a RAM bundle. When the bundle is loaded, those modules are immediately loaded, before any requires have even executed. The blacklist entry indicates that those modules should not be required inline. Because they are preloaded, there is no performance benefit from using an inline require. In fact the javascript spends extra time resolving the inline require every time the imports are referenced.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="test-and-measure-improvements"></a><a href="#test-and-measure-improvements" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Test and Measure Improvements</h3>
|
||||
<p>You should now be ready to build your app using unbundling and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
<p>You should now be ready to build your app using the RAM format and inline requires. Make sure you measure the before and after startup times.</p>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/debugging">← Debugging</a><a class="docs-next button" href="/react-native/docs/0.11/gesture-responder-system">Gesture Responder System →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -275,8 +275,12 @@ emulator-<span class="hljs-number">5554</span> offline <span class="hljs-comme
|
||||
<p><img src="/react-native/docs/assets/ConfigureReleaseScheme.png" alt=""></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="3-configure-app-to-use-static-bundle"></a><a href="#3-configure-app-to-use-static-bundle" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>3. Configure app to use static bundle</h3>
|
||||
<p>During the development process, React Native has loaded your JavaScript code dynamically at runtime. For a production build, you want to pre-package the JavaScript bundle and distribute it inside your application. Doing this requires a code change in your code so that it knows to load the static bundle.</p>
|
||||
<p>In <code>AppDelegate.m</code>, change the default <code>jsCodeLocation</code> to point to the static bundle that is built in Release.</p>
|
||||
<pre><code class="hljs css language-objc"> jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<p>In <code>AppDelegate.m</code>, change <code>jsCodeLocation</code> to point to the static bundle if you're not in debug mode.</p>
|
||||
<pre><code class="hljs css language-objc"><span class="hljs-meta">#ifdef DEBUG</span>
|
||||
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:<span class="hljs-string">@"index"</span> fallbackResource:<span class="hljs-literal">nil</span>];
|
||||
<span class="hljs-meta">#else</span>
|
||||
jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<span class="hljs-meta">#endif</span>
|
||||
</code></pre>
|
||||
<p>This will now reference the <code>main.jsbundle</code> resource file that is created during the <code>Bundle React Native code and images</code> Build Phase in Xcode.</p>
|
||||
<blockquote>
|
||||
|
||||
@@ -275,8 +275,12 @@ emulator-<span class="hljs-number">5554</span> offline <span class="hljs-comme
|
||||
<p><img src="/react-native/docs/assets/ConfigureReleaseScheme.png" alt=""></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="3-configure-app-to-use-static-bundle"></a><a href="#3-configure-app-to-use-static-bundle" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>3. Configure app to use static bundle</h3>
|
||||
<p>During the development process, React Native has loaded your JavaScript code dynamically at runtime. For a production build, you want to pre-package the JavaScript bundle and distribute it inside your application. Doing this requires a code change in your code so that it knows to load the static bundle.</p>
|
||||
<p>In <code>AppDelegate.m</code>, change the default <code>jsCodeLocation</code> to point to the static bundle that is built in Release.</p>
|
||||
<pre><code class="hljs css language-objc"> jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<p>In <code>AppDelegate.m</code>, change <code>jsCodeLocation</code> to point to the static bundle if you're not in debug mode.</p>
|
||||
<pre><code class="hljs css language-objc"><span class="hljs-meta">#ifdef DEBUG</span>
|
||||
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:<span class="hljs-string">@"index"</span> fallbackResource:<span class="hljs-literal">nil</span>];
|
||||
<span class="hljs-meta">#else</span>
|
||||
jsCodeLocation = [[<span class="hljs-built_in">NSBundle</span> mainBundle] URLForResource:<span class="hljs-string">@"main"</span> withExtension:<span class="hljs-string">@"jsbundle"</span>];
|
||||
<span class="hljs-meta">#endif</span>
|
||||
</code></pre>
|
||||
<p>This will now reference the <code>main.jsbundle</code> resource file that is created during the <code>Bundle React Native code and images</code> Build Phase in Xcode.</p>
|
||||
<blockquote>
|
||||
|
||||
@@ -38,13 +38,22 @@
|
||||
<p>You can generate a private signing key using <code>keytool</code>. On Windows <code>keytool</code> must be run from <code>C:\Program Files\Java\jdkx.x.x_x\bin</code>.</p>
|
||||
<pre><code class="hljs">$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p>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 <code>my-release-key.keystore</code>.</p>
|
||||
<p>This command prompts you for passwords for the keystore and key and for the Distinguished Name fields for your key. It then generates the keystore as a file called <code>my-release-key.keystore</code>.</p>
|
||||
<p>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.</p>
|
||||
<p>On Mac if you not sure where is your jdk bin folder is then perform the following command to find it, <code>$ /usr/libexec/java_home</code> it will output the directroy of jdk which looks like this, <code>/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home</code> then navigate to that directory by the following command, <code>$ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/</code> Now you can perform the keytool command with sudo permission as shown below, <code>$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000</code> <em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<p>On Mac, if you're not sure where your jdk bin folder is, then perform the following command to find it:</p>
|
||||
<pre><code class="hljs">$ /usr/libexec/java_home
|
||||
</code></pre>
|
||||
<p>It will output the directory of the jdk, which will look something like this:</p>
|
||||
<pre><code class="hljs">/Library/Java/JavaVirtualMachines/jdkX.X.X_XXX.jdk/Contents/Home
|
||||
</code></pre>
|
||||
<p>Navigate to that directory by using the command <code>$ cd /your/jdk/path</code> and use the keytool command with sudo permission as shown below.</p>
|
||||
<pre><code class="hljs">$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p><em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="setting-up-gradle-variables"></a><a href="#setting-up-gradle-variables" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Setting up gradle variables</h3>
|
||||
<ol>
|
||||
<li>Place the <code>my-release-key.keystore</code> file under the <code>android/app</code> directory in your project folder.</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code> and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code>, and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
</ol>
|
||||
<pre><code class="hljs"><span class="hljs-attr">MYAPP_RELEASE_STORE_FILE</span>=my-release-key.keystore
|
||||
<span class="hljs-attr">MYAPP_RELEASE_KEY_ALIAS</span>=my-key-alias
|
||||
@@ -58,9 +67,9 @@
|
||||
<blockquote>
|
||||
<p>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.</p>
|
||||
</blockquote>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext, and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-signing-config-to-your-app-s-gradle-config"></a><a href="#adding-signing-config-to-your-app-s-gradle-config" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding signing config to your app's gradle config</h3>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder and add the signing config,</p>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder, and add the signing config,</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
android {
|
||||
...
|
||||
@@ -91,7 +100,7 @@ $ ./gradlew assembleRelease
|
||||
</code></pre>
|
||||
<p>Gradle's <code>assembleRelease</code> 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 <code>android/app/build.gradle</code> to see how you can update it to reflect these changes.</p>
|
||||
<blockquote>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make release build skip bundling JS and assets into the APK.</p>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make the release build skip bundling JS and assets into the APK.</p>
|
||||
</blockquote>
|
||||
<p>The generated APK can be found under <code>android/app/build/outputs/apk/app-release.apk</code>, and is ready to be distributed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="testing-the-release-build-of-your-app"></a><a href="#testing-the-release-build-of-your-app" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Testing the release build of your app</h3>
|
||||
@@ -99,14 +108,17 @@ $ ./gradlew assembleRelease
|
||||
<pre><code class="hljs css language-sh">$ react-native run-android --variant=release
|
||||
</code></pre>
|
||||
<p>Note that <code>--variant=release</code> is only available if you've set up signing as described above.</p>
|
||||
<p>You can kill any running packager instances, all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<p>You can kill any running packager instances, since all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="split-apks-by-abi-to-reduce-file-size"></a><a href="#split-apks-by-abi-to-reduce-file-size" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Split APKs by ABI to reduce file size</h3>
|
||||
<p>By default, the generated APK has the native code for both x86 and ARMv7a CPU architectures. This makes it easier to share APKs that run on almost all Android devices. However, this has the downside that there will be some unused native code on any device, leading to unnecessarily bigger APKs.</p>
|
||||
<p>You can create an APK for each CPU by changing the following line in android/app/build.gradle:</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- ndk {</span>
|
||||
<span class="hljs-deletion">- abiFilters "armeabi-v7a", "x86"</span>
|
||||
<span class="hljs-deletion">- }</span>
|
||||
<span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<span class="hljs-addition">+ def enableSeparateBuildPerCPUArchitecture = true</span>
|
||||
</code></pre>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a> and the users will automatically get the appropriate APK. If you want to upload to other markets such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a>, and the users will automatically get the appropriate APK. If you want to upload to other markets, such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- universalApk false // If true, also generate a universal APK</span>
|
||||
<span class="hljs-addition">+ universalApk true // If true, also generate a universal APK</span>
|
||||
</code></pre>
|
||||
|
||||
@@ -38,13 +38,22 @@
|
||||
<p>You can generate a private signing key using <code>keytool</code>. On Windows <code>keytool</code> must be run from <code>C:\Program Files\Java\jdkx.x.x_x\bin</code>.</p>
|
||||
<pre><code class="hljs">$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p>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 <code>my-release-key.keystore</code>.</p>
|
||||
<p>This command prompts you for passwords for the keystore and key and for the Distinguished Name fields for your key. It then generates the keystore as a file called <code>my-release-key.keystore</code>.</p>
|
||||
<p>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.</p>
|
||||
<p>On Mac if you not sure where is your jdk bin folder is then perform the following command to find it, <code>$ /usr/libexec/java_home</code> it will output the directroy of jdk which looks like this, <code>/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home</code> then navigate to that directory by the following command, <code>$ cd /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/</code> Now you can perform the keytool command with sudo permission as shown below, <code>$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000</code> <em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<p>On Mac, if you're not sure where your jdk bin folder is, then perform the following command to find it:</p>
|
||||
<pre><code class="hljs">$ /usr/libexec/java_home
|
||||
</code></pre>
|
||||
<p>It will output the directory of the jdk, which will look something like this:</p>
|
||||
<pre><code class="hljs">/Library/Java/JavaVirtualMachines/jdkX.X.X_XXX.jdk/Contents/Home
|
||||
</code></pre>
|
||||
<p>Navigate to that directory by using the command <code>$ cd /your/jdk/path</code> and use the keytool command with sudo permission as shown below.</p>
|
||||
<pre><code class="hljs">$ sudo keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
|
||||
</code></pre>
|
||||
<p><em>Note: Remember to keep your keystore file private and never commit it to version control.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="setting-up-gradle-variables"></a><a href="#setting-up-gradle-variables" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Setting up gradle variables</h3>
|
||||
<ol>
|
||||
<li>Place the <code>my-release-key.keystore</code> file under the <code>android/app</code> directory in your project folder.</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code> and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
<li>Edit the file <code>~/.gradle/gradle.properties</code> or <code>android/gradle.properties</code>, and add the following (replace <code>*****</code> with the correct keystore password, alias and key password),</li>
|
||||
</ol>
|
||||
<pre><code class="hljs"><span class="hljs-attr">MYAPP_RELEASE_STORE_FILE</span>=my-release-key.keystore
|
||||
<span class="hljs-attr">MYAPP_RELEASE_KEY_ALIAS</span>=my-key-alias
|
||||
@@ -58,9 +67,9 @@
|
||||
<blockquote>
|
||||
<p>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.</p>
|
||||
</blockquote>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<p><em>Note about security: If you are not keen on storing your passwords in plaintext, and you are running OSX, you can also <a href="https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/">store your credentials in the Keychain Access app</a>. Then you can skip the two last rows in <code>~/.gradle/gradle.properties</code>.</em></p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="adding-signing-config-to-your-app-s-gradle-config"></a><a href="#adding-signing-config-to-your-app-s-gradle-config" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Adding signing config to your app's gradle config</h3>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder and add the signing config,</p>
|
||||
<p>Edit the file <code>android/app/build.gradle</code> in your project folder, and add the signing config,</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
android {
|
||||
...
|
||||
@@ -91,7 +100,7 @@ $ ./gradlew assembleRelease
|
||||
</code></pre>
|
||||
<p>Gradle's <code>assembleRelease</code> 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 <code>android/app/build.gradle</code> to see how you can update it to reflect these changes.</p>
|
||||
<blockquote>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make release build skip bundling JS and assets into the APK.</p>
|
||||
<p>Note: Make sure gradle.properties does not include <em>org.gradle.configureondemand=true</em> as that will make the release build skip bundling JS and assets into the APK.</p>
|
||||
</blockquote>
|
||||
<p>The generated APK can be found under <code>android/app/build/outputs/apk/app-release.apk</code>, and is ready to be distributed.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="testing-the-release-build-of-your-app"></a><a href="#testing-the-release-build-of-your-app" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Testing the release build of your app</h3>
|
||||
@@ -99,14 +108,17 @@ $ ./gradlew assembleRelease
|
||||
<pre><code class="hljs css language-sh">$ react-native run-android --variant=release
|
||||
</code></pre>
|
||||
<p>Note that <code>--variant=release</code> is only available if you've set up signing as described above.</p>
|
||||
<p>You can kill any running packager instances, all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<p>You can kill any running packager instances, since all your framework and JavaScript code is bundled in the APK's assets.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="split-apks-by-abi-to-reduce-file-size"></a><a href="#split-apks-by-abi-to-reduce-file-size" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Split APKs by ABI to reduce file size</h3>
|
||||
<p>By default, the generated APK has the native code for both x86 and ARMv7a CPU architectures. This makes it easier to share APKs that run on almost all Android devices. However, this has the downside that there will be some unused native code on any device, leading to unnecessarily bigger APKs.</p>
|
||||
<p>You can create an APK for each CPU by changing the following line in android/app/build.gradle:</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- ndk {</span>
|
||||
<span class="hljs-deletion">- abiFilters "armeabi-v7a", "x86"</span>
|
||||
<span class="hljs-deletion">- }</span>
|
||||
<span class="hljs-deletion">- def enableSeparateBuildPerCPUArchitecture = false</span>
|
||||
<span class="hljs-addition">+ def enableSeparateBuildPerCPUArchitecture = true</span>
|
||||
</code></pre>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a> and the users will automatically get the appropriate APK. If you want to upload to other markets such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<p>Upload both these files to markets which support device targetting, such as <a href="https://developer.android.com/google/play/publishing/multiple-apks.html">Google Play</a> and <a href="https://developer.amazon.com/docs/app-submission/getting-started-with-device-targeting.html">Amazon AppStore</a>, and the users will automatically get the appropriate APK. If you want to upload to other markets, such as <a href="https://www.apkfiles.com/">APKFiles</a>, which do not support multiple APKs for a single app, change the following line as well to create the default universal APK with binaries for both CPUs.</p>
|
||||
<pre><code class="hljs css language-diff"><span class="hljs-deletion">- universalApk false // If true, also generate a universal APK</span>
|
||||
<span class="hljs-addition">+ universalApk true // If true, also generate a universal APK</span>
|
||||
</code></pre>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<li><a href="/react-native/docs/0.11/testing#ios">iOS</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#apple-tv">Apple TV</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#end-to-end-tests">End-to-end tests</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#website">Website</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#updating-the-documentation">Updating the Documentation</a></li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="javascript"></a><a href="#javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript</h2>
|
||||
<h3><a class="anchor" aria-hidden="true" id="jest"></a><a href="#jest" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Jest</h3>
|
||||
@@ -64,7 +64,7 @@ $ npm run flow
|
||||
javac <span class="hljs-number">1.8</span><span class="hljs-number">.0</span>_111
|
||||
</code></pre>
|
||||
<p>The version string <code>1.8.x_xxx</code> corresponds to JDK 8.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>. Note that brew may not install the version needed to run the tests. For best results, use the same version as the GitHub builds, which can be found in the <code>.circleci</code> folder in the root of the repo.</p>
|
||||
<p>To run the Android unit tests:</p>
|
||||
<pre><code class="hljs">$ cd react-native
|
||||
$ ./scripts/run-android-local-unit-tests.sh
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<li><a href="/react-native/docs/0.11/testing#ios">iOS</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#apple-tv">Apple TV</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#end-to-end-tests">End-to-end tests</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#website">Website</a></li>
|
||||
<li><a href="/react-native/docs/0.11/testing#updating-the-documentation">Updating the Documentation</a></li>
|
||||
</ul>
|
||||
<h2><a class="anchor" aria-hidden="true" id="javascript"></a><a href="#javascript" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>JavaScript</h2>
|
||||
<h3><a class="anchor" aria-hidden="true" id="jest"></a><a href="#jest" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Jest</h3>
|
||||
@@ -64,7 +64,7 @@ $ npm run flow
|
||||
javac <span class="hljs-number">1.8</span><span class="hljs-number">.0</span>_111
|
||||
</code></pre>
|
||||
<p>The version string <code>1.8.x_xxx</code> corresponds to JDK 8.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>.</p>
|
||||
<p>You also need to install the <a href="https://buckbuild.com/setup/install.html">Buck build tool</a>. Note that brew may not install the version needed to run the tests. For best results, use the same version as the GitHub builds, which can be found in the <code>.circleci</code> folder in the root of the repo.</p>
|
||||
<p>To run the Android unit tests:</p>
|
||||
<pre><code class="hljs">$ cd react-native
|
||||
$ ./scripts/run-android-local-unit-tests.sh
|
||||
|
||||
@@ -46,6 +46,46 @@
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="parameters"></a><a href="#parameters" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Parameters</h3>
|
||||
<p>The command name identifies the parameters that a command would expect. When the command parameter is surrounded by greater-than, less-than symbols <code>< ></code>, this indicates that the parameter is expected. When a parameter is surrounded by brackets <code>[ ]</code>, this indicates that the parameter is optional.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="getting-a-list-of-all-cli-commands"></a><a href="#getting-a-list-of-all-cli-commands" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Getting a list of all CLI commands</h3>
|
||||
<p>Running <code>react-native --help</code> from inside a React Native project will list all of your current commands. Here is an example from version <code>0.56</code>:</p>
|
||||
<pre><code class="hljs css language-sh"> Usage: react-native [options] [<span class="hljs-built_in">command</span>]
|
||||
|
||||
Options:
|
||||
|
||||
-V, --version output the version number
|
||||
-h, --<span class="hljs-built_in">help</span> output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
start [options] starts the webserver
|
||||
run-ios [options] builds your app and starts it on iOS simulator
|
||||
run-android [options] builds your app and starts it on a connected Android emulator or device
|
||||
new-library [options] generates a native library bridge
|
||||
bundle [options] builds the javascript bundle <span class="hljs-keyword">for</span> offline use
|
||||
unbundle [options] builds javascript as <span class="hljs-string">"unbundle"</span> <span class="hljs-keyword">for</span> offline use
|
||||
eject [options] Re-create the iOS and Android folders and native code
|
||||
link [options] [packageName] links all native dependencies (updates native build files)
|
||||
unlink [options] <packageName> unlink native dependency
|
||||
install [options] <packageName> install and link native dependencies
|
||||
uninstall [options] <packageName> uninstall and unlink native dependencies
|
||||
upgrade [options] upgrade your app<span class="hljs-string">'s template files to the latest version; run this after updating the react-native version in your package.json and running npm install
|
||||
log-android [options] starts adb logcat
|
||||
log-ios [options] starts iOS device syslog tail
|
||||
dependencies [options] lists dependencies
|
||||
info [options] Get relevant version info about OS, toolchain and libraries
|
||||
</span></code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="cli-configs"></a><a href="#cli-configs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>CLI Configs</h3>
|
||||
<p>When using <code>react-native start</code>, its platform derivatives, and <code>react-native bundle</code> you can use a file to define the CLI options used by React Native by default. If you create a file <code>rn-cli.config.js</code> in the root of your project, it will be evaluated and options for the commands will come from there.</p>
|
||||
<p>You can see the options for the CLI config file inside the <a href="https://github.com/facebook/metro/blob/master/packages/metro/src/Config.js">source code for Metro here</a>, and here is a common <code>rn-cli.config.js</code> used for supporting TypeScript in React Native projects:</p>
|
||||
<pre><code class="hljs css language-js"><span class="hljs-built_in">module</span>.exports = {
|
||||
getTransformModulePath() {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'react-native-typescript-transformer'</span>);
|
||||
},
|
||||
getSourceExts() {
|
||||
<span class="hljs-keyword">return</span> [<span class="hljs-string">'ts'</span>, <span class="hljs-string">'tsx'</span>];
|
||||
},
|
||||
};
|
||||
</code></pre>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/testing">← Testing your Changes</a><a class="docs-next button" href="/react-native/docs/0.11/datepickerios">DatePickerIOS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -46,6 +46,46 @@
|
||||
</code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="parameters"></a><a href="#parameters" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Parameters</h3>
|
||||
<p>The command name identifies the parameters that a command would expect. When the command parameter is surrounded by greater-than, less-than symbols <code>< ></code>, this indicates that the parameter is expected. When a parameter is surrounded by brackets <code>[ ]</code>, this indicates that the parameter is optional.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="getting-a-list-of-all-cli-commands"></a><a href="#getting-a-list-of-all-cli-commands" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Getting a list of all CLI commands</h3>
|
||||
<p>Running <code>react-native --help</code> from inside a React Native project will list all of your current commands. Here is an example from version <code>0.56</code>:</p>
|
||||
<pre><code class="hljs css language-sh"> Usage: react-native [options] [<span class="hljs-built_in">command</span>]
|
||||
|
||||
Options:
|
||||
|
||||
-V, --version output the version number
|
||||
-h, --<span class="hljs-built_in">help</span> output usage information
|
||||
|
||||
Commands:
|
||||
|
||||
start [options] starts the webserver
|
||||
run-ios [options] builds your app and starts it on iOS simulator
|
||||
run-android [options] builds your app and starts it on a connected Android emulator or device
|
||||
new-library [options] generates a native library bridge
|
||||
bundle [options] builds the javascript bundle <span class="hljs-keyword">for</span> offline use
|
||||
unbundle [options] builds javascript as <span class="hljs-string">"unbundle"</span> <span class="hljs-keyword">for</span> offline use
|
||||
eject [options] Re-create the iOS and Android folders and native code
|
||||
link [options] [packageName] links all native dependencies (updates native build files)
|
||||
unlink [options] <packageName> unlink native dependency
|
||||
install [options] <packageName> install and link native dependencies
|
||||
uninstall [options] <packageName> uninstall and unlink native dependencies
|
||||
upgrade [options] upgrade your app<span class="hljs-string">'s template files to the latest version; run this after updating the react-native version in your package.json and running npm install
|
||||
log-android [options] starts adb logcat
|
||||
log-ios [options] starts iOS device syslog tail
|
||||
dependencies [options] lists dependencies
|
||||
info [options] Get relevant version info about OS, toolchain and libraries
|
||||
</span></code></pre>
|
||||
<h3><a class="anchor" aria-hidden="true" id="cli-configs"></a><a href="#cli-configs" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>CLI Configs</h3>
|
||||
<p>When using <code>react-native start</code>, its platform derivatives, and <code>react-native bundle</code> you can use a file to define the CLI options used by React Native by default. If you create a file <code>rn-cli.config.js</code> in the root of your project, it will be evaluated and options for the commands will come from there.</p>
|
||||
<p>You can see the options for the CLI config file inside the <a href="https://github.com/facebook/metro/blob/master/packages/metro/src/Config.js">source code for Metro here</a>, and here is a common <code>rn-cli.config.js</code> used for supporting TypeScript in React Native projects:</p>
|
||||
<pre><code class="hljs css language-js"><span class="hljs-built_in">module</span>.exports = {
|
||||
getTransformModulePath() {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">require</span>.resolve(<span class="hljs-string">'react-native-typescript-transformer'</span>);
|
||||
},
|
||||
getSourceExts() {
|
||||
<span class="hljs-keyword">return</span> [<span class="hljs-string">'ts'</span>, <span class="hljs-string">'tsx'</span>];
|
||||
},
|
||||
};
|
||||
</code></pre>
|
||||
</span></div></article></div><div class="docs-prevnext"><a class="docs-prev button" href="/react-native/docs/0.11/testing">← Testing your Changes</a><a class="docs-next button" href="/react-native/docs/0.11/datepickerios">DatePickerIOS →</a></div></div></div></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/react-native/" class="nav-home"><img src="/react-native/img/header_logo.png" alt="React Native" width="66" height="58"/></a><div><h5><a href="/react-native/docs/getting-started.html">Docs</a></h5><a href="/react-native/docs/getting-started.html">Getting Started</a><a href="/react-native/docs/tutorial.html">Tutorial</a><a href="/react-native/docs/components-and-apis.html">Components and APIs</a><a href="/react-native/docs/more-resources.html">More Resources</a></div><div><h5><a href="/react-native/help.html">Community</a></h5><a href="/react-native/showcase.html">Who's using React Native?</a><a href="http://stackoverflow.com/questions/tagged/react-native" target="_blank">Stack Overflow</a><a href="https://discuss.reactjs.org" target="_blank">Discussion Forum</a><a href="https://discord.gg/0ZcbPKXt5bZjGY5n">Reactiflux Chat</a></div><div><h5>More</h5><a href="/react-native/blog">Blog</a><a href="https://twitter.com/reactnative" target="_blank">Twitter</a><a href="https://github.com/facebook/react-native" target="_blank">GitHub</a><a href="http://reactjs.org" target="_blank">React</a></div></section><a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource"><img src="/react-native/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/></a><section class="copyright">Copyright © 2018 Facebook Inc.</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>window.fbAsyncInit = function() {FB.init({appId:'1677033832619985',xfbml:true,version:'v2.7'});};(function(d, s, id){var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = '//connect.facebook.net/en_US/sdk.js';fjs.parentNode.insertBefore(js, fjs);}(document, 'script','facebook-jssdk'));
|
||||
</script><script>window.twttr=(function(d,s, id){var js,fjs=d.getElementsByTagName(s)[0],t=window.twttr||{};if(d.getElementById(id))return t;js=d.createElement(s);js.id=id;js.src='https://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js, fjs);t._e = [];t.ready = function(f) {t._e.push(f);};return t;}(document, 'script', 'twitter-wjs'));</script><script>
|
||||
var search = docsearch({
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
<p>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.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitylabel-ios-android"></a><a href="#accessibilitylabel-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityLabel (iOS, Android)</h4>
|
||||
<p>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.</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View:</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel={'Tap me!'}
|
||||
accessibilityLabel="Tap me!"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Press me!</Text>
|
||||
@@ -60,7 +60,55 @@
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>In the above example, the <code>accessibilityLabel</code> on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityhint-ios-android"></a><a href="#accessibilityhint-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityHint (iOS, Android)</h4>
|
||||
<p>An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label.</p>
|
||||
<p>To use, set the <code>accessibilityHint</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel="Go back"
|
||||
accessibilityHint="Navigates to the previous screen"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Back</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>iOS In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for accessibilityHint in the <a href="https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint">iOS Developer Docs</a></p>
|
||||
<p>Android In the above example, Talkback will read the hint after the label. At this time, hints cannot be turned off on Android.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityignoresinvertcolorsios"></a><a href="#accessibilityignoresinvertcolorsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityIgnoresInvertColors(iOS)</h4>
|
||||
<p>Inverting screen colors is an Accessibility feature that makes the iPhone and iPad easier on the eyes for some people with a sensitivity to brightness, easier to distinguish for some people with color blindness, and easier to make out for some people with low vision. However, sometimes you have views such as photos that you don't want to be inverted. In this case, you can set this property to be false so that these specific views won't have their colors inverted.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityrole-ios-android"></a><a href="#accessibilityrole-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityRole (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> Accessibility Role and Accessibility States are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. To use, set the <code>accessibilityRole</code> property to one of the following strings:</p>
|
||||
<ul>
|
||||
<li><strong>none</strong> Used when the element has no role.</li>
|
||||
<li><strong>button</strong> Used when the element should be treated as a button.</li>
|
||||
<li><strong>link</strong> Used when the element should be treated as a link.</li>
|
||||
<li><strong>search</strong> Used when the text field element should also be treated as a search field.</li>
|
||||
<li><strong>image</strong> Used when the element should be treated as an image. Can be combined with button or link, for example.</li>
|
||||
<li><strong>keyboardkey</strong> Used when the element acts as a keyboard key.</li>
|
||||
<li><strong>text</strong> Used when the element should be treated as static text that cannot change.</li>
|
||||
<li><strong>adjustable</strong> Used when an element can be "adjusted" (e.g. a slider).</li>
|
||||
<li><strong>imagebutton</strong> Used when the element should be treated as a button and is also an image.</li>
|
||||
<li><strong>header</strong> Used when an element acts as a header for a content section (e.g. the title of a navigation bar).</li>
|
||||
<li><strong>summary</strong> Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitystate-ios-android"></a><a href="#accessibilitystate-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityState (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityRole</code> and <code>accessibilityStates</code> are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. The state of the element can be set either to <code>selected</code> or <code>disabled</code> or both:</p>
|
||||
<ul>
|
||||
<li><strong>selected</strong> Used when the element is in a selected state. For example, a button is selected.</li>
|
||||
<li><strong>disabled</strong> Used when the element is disabled and cannot be interacted with.</li>
|
||||
</ul>
|
||||
<p>To use, set the <code>accessibilityState</code> to an array containing either <code>selected</code>, <code>disabled</code>, or both.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitytraits-ios"></a><a href="#accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityTraits (iOS)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> <code>accessibilityTraits</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>accessibilityTraits</code>.</p>
|
||||
<p>To use, set the <code>accessibilityTraits</code> property to one of (or an array of) accessibility trait strings:</p>
|
||||
<ul>
|
||||
@@ -93,6 +141,9 @@
|
||||
<h4><a class="anchor" aria-hidden="true" id="onmagictap-ios"></a><a href="#onmagictap-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>onMagicTap (iOS)</h4>
|
||||
<p>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 <code>onMagicTap</code> function, the system will traverse up the view hierarchy until it finds a view that does.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitycomponenttype-android"></a><a href="#accessibilitycomponenttype-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityComponentType (Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityComponentType</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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. We support 'none', ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’.</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableWithoutFeedback accessibilityComponentType=”button”
|
||||
onPress={this._onPress}>
|
||||
@@ -155,7 +206,7 @@ _onPress: <span class="hljs-function"><span class="hljs-keyword">function</span>
|
||||
}
|
||||
|
||||
<CustomRadioButton
|
||||
accessibleComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
accessibilityComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
onPress={<span class="hljs-keyword">this</span>._onPress}/>
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
|
||||
@@ -49,10 +49,10 @@
|
||||
<p>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.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitylabel-ios-android"></a><a href="#accessibilitylabel-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityLabel (iOS, Android)</h4>
|
||||
<p>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.</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View:</p>
|
||||
<p>To use, set the <code>accessibilityLabel</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel={'Tap me!'}
|
||||
accessibilityLabel="Tap me!"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Press me!</Text>
|
||||
@@ -60,7 +60,55 @@
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>In the above example, the <code>accessibilityLabel</code> on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityhint-ios-android"></a><a href="#accessibilityhint-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityHint (iOS, Android)</h4>
|
||||
<p>An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not obvious from the accessibility label.</p>
|
||||
<p>To use, set the <code>accessibilityHint</code> property to a custom string on your View, Text or Touchable:</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableOpacity
|
||||
accessible={true}
|
||||
accessibilityLabel="Go back"
|
||||
accessibilityHint="Navigates to the previous screen"
|
||||
onPress={this._onPress}>
|
||||
<View style={styles.button}>
|
||||
<Text style={styles.buttonText}>Back</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</code></pre>
|
||||
<p>iOS In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for accessibilityHint in the <a href="https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint">iOS Developer Docs</a></p>
|
||||
<p>Android In the above example, Talkback will read the hint after the label. At this time, hints cannot be turned off on Android.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityignoresinvertcolorsios"></a><a href="#accessibilityignoresinvertcolorsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityIgnoresInvertColors(iOS)</h4>
|
||||
<p>Inverting screen colors is an Accessibility feature that makes the iPhone and iPad easier on the eyes for some people with a sensitivity to brightness, easier to distinguish for some people with color blindness, and easier to make out for some people with low vision. However, sometimes you have views such as photos that you don't want to be inverted. In this case, you can set this property to be false so that these specific views won't have their colors inverted.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilityrole-ios-android"></a><a href="#accessibilityrole-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityRole (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> Accessibility Role and Accessibility States are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. To use, set the <code>accessibilityRole</code> property to one of the following strings:</p>
|
||||
<ul>
|
||||
<li><strong>none</strong> Used when the element has no role.</li>
|
||||
<li><strong>button</strong> Used when the element should be treated as a button.</li>
|
||||
<li><strong>link</strong> Used when the element should be treated as a link.</li>
|
||||
<li><strong>search</strong> Used when the text field element should also be treated as a search field.</li>
|
||||
<li><strong>image</strong> Used when the element should be treated as an image. Can be combined with button or link, for example.</li>
|
||||
<li><strong>keyboardkey</strong> Used when the element acts as a keyboard key.</li>
|
||||
<li><strong>text</strong> Used when the element should be treated as static text that cannot change.</li>
|
||||
<li><strong>adjustable</strong> Used when an element can be "adjusted" (e.g. a slider).</li>
|
||||
<li><strong>imagebutton</strong> Used when the element should be treated as a button and is also an image.</li>
|
||||
<li><strong>header</strong> Used when an element acts as a header for a content section (e.g. the title of a navigation bar).</li>
|
||||
<li><strong>summary</strong> Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitystate-ios-android"></a><a href="#accessibilitystate-ios-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityState (iOS, Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityRole</code> and <code>accessibilityStates</code> are meant to be a cross-platform solution to replace <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>, which will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. The state of the element can be set either to <code>selected</code> or <code>disabled</code> or both:</p>
|
||||
<ul>
|
||||
<li><strong>selected</strong> Used when the element is in a selected state. For example, a button is selected.</li>
|
||||
<li><strong>disabled</strong> Used when the element is disabled and cannot be interacted with.</li>
|
||||
</ul>
|
||||
<p>To use, set the <code>accessibilityState</code> to an array containing either <code>selected</code>, <code>disabled</code>, or both.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitytraits-ios"></a><a href="#accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityTraits (iOS)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> <code>accessibilityTraits</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>accessibilityTraits</code>.</p>
|
||||
<p>To use, set the <code>accessibilityTraits</code> property to one of (or an array of) accessibility trait strings:</p>
|
||||
<ul>
|
||||
@@ -93,6 +141,9 @@
|
||||
<h4><a class="anchor" aria-hidden="true" id="onmagictap-ios"></a><a href="#onmagictap-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>onMagicTap (iOS)</h4>
|
||||
<p>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 <code>onMagicTap</code> function, the system will traverse up the view hierarchy until it finds a view that does.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="accessibilitycomponenttype-android"></a><a href="#accessibilitycomponenttype-android" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>accessibilityComponentType (Android)</h4>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> > <code>accessibilityComponentType</code> will soon be deprecated. When possible, use <code>accessibilityRole</code> and <code>accessibilityStates</code> instead of <code>accessibilityTraits</code> and <code>accessibilityComponentType</code>.</p>
|
||||
</blockquote>
|
||||
<p>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. We support 'none', ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’.</p>
|
||||
<pre><code class="hljs css language-javascript"><TouchableWithoutFeedback accessibilityComponentType=”button”
|
||||
onPress={this._onPress}>
|
||||
@@ -155,7 +206,7 @@ _onPress: <span class="hljs-function"><span class="hljs-keyword">function</span>
|
||||
}
|
||||
|
||||
<CustomRadioButton
|
||||
accessibleComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
accessibilityComponentType={<span class="hljs-keyword">this</span>.state.radioButton}
|
||||
onPress={<span class="hljs-keyword">this</span>._onPress}/>
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For Apple TV · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.12"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For Apple TV · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For TV Devices · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.12"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For TV Devices · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
@@ -33,7 +33,7 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For Apple TV</h1></header><article><div><span><style>
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For TV Devices</h1></header><article><div><span><style>
|
||||
.toggler li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -151,20 +151,20 @@
|
||||
<ul>
|
||||
<li><p><em>General support for tvOS</em>: 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.</p></li>
|
||||
<li><p><em>Common codebase</em>: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.</p></li>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
@@ -222,7 +222,7 @@
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, make a long press on the play/pause button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
<ul>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For Apple TV · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.12"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For Apple TV · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Building For TV Devices · React Native</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="<style>"/><meta name="docsearch:version" content="0.12"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Building For TV Devices · React Native"/><meta property="og:type" content="website"/><meta property="og:url" content="https://facebook.github.io/react-native/index.html"/><meta property="og:description" content="<style>"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/react-native/img/favicon.png"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/solarized-dark.min.css"/><link rel="alternate" type="application/atom+xml" href="https://facebook.github.io/react-native/blog/atom.xml" title="React Native Blog ATOM Feed"/><link rel="alternate" type="application/rss+xml" href="https://facebook.github.io/react-native/blog/feed.xml" title="React Native Blog RSS Feed"/><script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
@@ -33,7 +33,7 @@
|
||||
};
|
||||
}
|
||||
});
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For Apple TV</h1></header><article><div><span><style>
|
||||
</script></nav></div><div class="container mainContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/facebook/react-native-website/blob/master/docs/building-for-apple-tv.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 class="postHeaderTitle">Building For TV Devices</h1></header><article><div><span><style>
|
||||
.toggler li {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -151,20 +151,20 @@
|
||||
<ul>
|
||||
<li><p><em>General support for tvOS</em>: 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.</p></li>
|
||||
<li><p><em>Common codebase</em>: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.</p></li>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Apple TV, the native view class is <code>RCTTVView</code>, which has additional methods to make use of the tvOS focus engine. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code> and <code>TouchableOpacity</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<li><p><em>Access to touchable controls</em>: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The <code>Touchable</code> 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 <code>TouchableWithoutFeedback</code>, <code>TouchableHighlight</code>, <code>TouchableOpacity</code> and <code>TouchableNativeFeedback</code> will "just work". In particular:</p>
|
||||
<ul>
|
||||
<li><code>touchableHandleActivePressIn</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>touchableHandleActivePressOut</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>touchableHandlePress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
<li><code>onFocus</code> will be executed when the touchable view goes into focus</li>
|
||||
<li><code>onBlur</code> will be executed when the touchable view goes out of focus</li>
|
||||
<li><code>onPress</code> will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
@@ -222,7 +222,7 @@
|
||||
</ul>
|
||||
<p><block class="android" /></p>
|
||||
<ul>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, make a long press on the play/pause button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
<li><em>Dev Menu support</em>: On the simulator, cmd-M will bring up the developer menu, just like on Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) )</li>
|
||||
</ul>
|
||||
<p><block class="ios" /></p>
|
||||
<ul>
|
||||
|
||||
@@ -63,10 +63,10 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
</code></pre>
|
||||
<h4><a class="anchor" aria-hidden="true" id="download-links-for-android-ndk"></a><a href="#download-links-for-android-ndk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download links for Android NDK</h4>
|
||||
<ol>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip</a></li>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip</a></li>
|
||||
</ol>
|
||||
<p>You can find further instructions on the <a href="https://developer.android.com/ndk/index.html">official page</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="building-the-source"></a><a href="#building-the-source" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Building the source</h3>
|
||||
@@ -79,7 +79,7 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
<p>Add <code>gradle-download-task</code> as dependency in <code>android/build.gradle</code>:</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
<span class="hljs-keyword">dependencies</span> {
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:1.3.1'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:2.3.3'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'de.undercouch:gradle-download-task:3.1.2'</span>
|
||||
|
||||
<span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Do not place your application dependencies here; they belong</span>
|
||||
|
||||
@@ -63,10 +63,10 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
</code></pre>
|
||||
<h4><a class="anchor" aria-hidden="true" id="download-links-for-android-ndk"></a><a href="#download-links-for-android-ndk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Download links for Android NDK</h4>
|
||||
<ol>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip</a></li>
|
||||
<li>Mac OS (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-darwin-x86_64.zip</a></li>
|
||||
<li>Linux (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip</a></li>
|
||||
<li>Windows (64-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86_64.zip</a></li>
|
||||
<li>Windows (32-bit) - <a href="http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip">http://dl.google.com/android/repository/android-ndk-r17b-windows-x86.zip</a></li>
|
||||
</ol>
|
||||
<p>You can find further instructions on the <a href="https://developer.android.com/ndk/index.html">official page</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="building-the-source"></a><a href="#building-the-source" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Building the source</h3>
|
||||
@@ -79,7 +79,7 @@ ndk.<span class="hljs-attribute">dir</span>=/Users/your_unix_name/android-ndk/an
|
||||
<p>Add <code>gradle-download-task</code> as dependency in <code>android/build.gradle</code>:</p>
|
||||
<pre><code class="hljs css language-gradle">...
|
||||
<span class="hljs-keyword">dependencies</span> {
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:1.3.1'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'com.android.tools.build:gradle:2.3.3'</span>
|
||||
<span class="hljs-keyword">classpath</span> <span class="hljs-string">'de.undercouch:gradle-download-task:3.1.2'</span>
|
||||
|
||||
<span class="hljs-comment">// <span class="hljs-doctag">NOTE:</span> Do not place your application dependencies here; they belong</span>
|
||||
|
||||
@@ -94,11 +94,11 @@ YellowBox.ignoreWarnings([<span class="hljs-string">'Warning: ...'</span>]);
|
||||
<p>Note: if you prefer to avoid global installations, you can add <code>react-devtools</code> as a project dependency. Add the <code>react-devtools</code> package to your project using <code>npm install --save-dev react-devtools</code>, then add <code>"react-devtools": "react-devtools"</code> to the <code>scripts</code> section in your <code>package.json</code>, and then run <code>npm run react-devtools</code> from your project folder to open the DevTools.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" aria-hidden="true" id="integration-with-react-native-inspector"></a><a href="#integration-with-react-native-inspector" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Integration with React Native Inspector</h3>
|
||||
<p>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:</p>
|
||||
<p>Open the in-app developer menu and choose "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:</p>
|
||||
<p><img src="/react-native/docs/assets/Inspector.gif" alt="React Native Inspector"></p>
|
||||
<p>However, when <code>react-devtools</code> 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:</p>
|
||||
<p><img src="/react-native/docs/assets/ReactDevToolsInspector.gif" alt="React DevTools Inspector Integration"></p>
|
||||
<p>You can choose "Hide Inspector" in the same menu to exit this mode.</p>
|
||||
<p>You can choose "Toggle Inspector" in the same menu to exit this mode.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inspecting-component-instances"></a><a href="#inspecting-component-instances" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inspecting Component Instances</h3>
|
||||
<p>When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.</p>
|
||||
<p>First, follow the instructions for debugging in Chrome to open the Chrome console.</p>
|
||||
|
||||
@@ -94,11 +94,11 @@ YellowBox.ignoreWarnings([<span class="hljs-string">'Warning: ...'</span>]);
|
||||
<p>Note: if you prefer to avoid global installations, you can add <code>react-devtools</code> as a project dependency. Add the <code>react-devtools</code> package to your project using <code>npm install --save-dev react-devtools</code>, then add <code>"react-devtools": "react-devtools"</code> to the <code>scripts</code> section in your <code>package.json</code>, and then run <code>npm run react-devtools</code> from your project folder to open the DevTools.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" aria-hidden="true" id="integration-with-react-native-inspector"></a><a href="#integration-with-react-native-inspector" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Integration with React Native Inspector</h3>
|
||||
<p>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:</p>
|
||||
<p>Open the in-app developer menu and choose "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:</p>
|
||||
<p><img src="/react-native/docs/assets/Inspector.gif" alt="React Native Inspector"></p>
|
||||
<p>However, when <code>react-devtools</code> 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:</p>
|
||||
<p><img src="/react-native/docs/assets/ReactDevToolsInspector.gif" alt="React DevTools Inspector Integration"></p>
|
||||
<p>You can choose "Hide Inspector" in the same menu to exit this mode.</p>
|
||||
<p>You can choose "Toggle Inspector" in the same menu to exit this mode.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="inspecting-component-instances"></a><a href="#inspecting-component-instances" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Inspecting Component Instances</h3>
|
||||
<p>When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.</p>
|
||||
<p>First, follow the instructions for debugging in Chrome to open the Chrome console.</p>
|
||||
|
||||
@@ -72,7 +72,7 @@ render() {
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js">NativeMethodsMixin.js</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react-native/blob/master/Libraries/Renderer/oss/ReactNativeRenderer-prod.js">NativeMethodsMixin</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="composite-components-and-setnativeprops"></a><a href="#composite-components-and-setnativeprops" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Composite components and setNativeProps</h2>
|
||||
<p>Composite components are not backed by a native view, so you cannot call <code>setNativeProps</code> on them. Consider this example:</p>
|
||||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||||
|
||||
@@ -72,7 +72,7 @@ render() {
|
||||
}
|
||||
</code></pre>
|
||||
<p>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.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js">NativeMethodsMixin.js</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<p>If you look at the implementation of <code>setNativeProps</code> in <a href="https://github.com/facebook/react-native/blob/master/Libraries/Renderer/oss/ReactNativeRenderer-prod.js">NativeMethodsMixin</a> you will notice that it is a wrapper around <code>RCTUIManager.updateView</code> - this is the exact same function call that results from re-rendering - see <a href="https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js">receiveComponent in ReactNativeBaseComponent.js</a>.</p>
|
||||
<h2><a class="anchor" aria-hidden="true" id="composite-components-and-setnativeprops"></a><a href="#composite-components-and-setnativeprops" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Composite components and setNativeProps</h2>
|
||||
<p>Composite components are not backed by a native view, so you cannot call <code>setNativeProps</code> on them. Consider this example:</p>
|
||||
<div class="snack-player"><div class="mobile-friendly-snack" style="display: none"><pre><code class="hljs css javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="in"></a><a href="#in" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>in()</code></h3>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span>(easing)
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span> easing;
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="out"></a><a href="#out" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>out()</code></h3>
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="in"></a><a href="#in" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>in()</code></h3>
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span>(easing)
|
||||
<pre><code class="hljs css language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">in</span> easing;
|
||||
</code></pre>
|
||||
<hr>
|
||||
<h3><a class="anchor" aria-hidden="true" id="out"></a><a href="#out" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a><code>out()</code></h3>
|
||||
|
||||
@@ -105,11 +105,11 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
<span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
|
||||
<span class="hljs-attr">flexDirection</span>: <span class="hljs-string">'column'</span>,
|
||||
<span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'stretch'</span>,
|
||||
}}>
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
|
||||
<View style={{height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{height: 100, backgroundColor: 'steelblue'}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'stretch'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%20100%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
|
||||
<h4><a class="anchor" aria-hidden="true" id="going-deeper"></a><a href="#going-deeper" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Going Deeper</h4>
|
||||
<p>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 <a href="/react-native/docs/0.12/layout-props">here</a>.</p>
|
||||
|
||||
@@ -105,11 +105,11 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
<span class="hljs-attr">flex</span>: <span class="hljs-number">1</span>,
|
||||
<span class="hljs-attr">flexDirection</span>: <span class="hljs-string">'column'</span>,
|
||||
<span class="hljs-attr">justifyContent</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'center'</span>,
|
||||
<span class="hljs-attr">alignItems</span>: <span class="hljs-string">'stretch'</span>,
|
||||
}}>
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
|
||||
<View style={{height: 50, backgroundColor: 'skyblue'}} />
|
||||
<View style={{height: 100, backgroundColor: 'steelblue'}} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -117,7 +117,7 @@ AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
|
||||
|
||||
// skip this line if using Create React Native App
|
||||
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
</code></pre><iframe style="margin-top: 4" width="100%" height="420" data-src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v1.10.0/index.html#code=import%20React%2C%20%7B%20Component%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20View%20%7D%20from%20'react-native'%3B%0A%0Aexport%20default%20class%20AlignItemsBasics%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60alignItems%60%20to%20'flex-start'%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60justifyContent%60%20to%20%60flex-end%60.%0A%20%20%20%20%20%20%2F%2F%20Try%20setting%20%60flexDirection%60%20to%20%60row%60.%0A%20%20%20%20%20%20%3CView%20style%3D%7B%7B%0A%20%20%20%20%20%20%20%20flex%3A%201%2C%0A%20%20%20%20%20%20%20%20flexDirection%3A%20'column'%2C%0A%20%20%20%20%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20%20%20%20%20alignItems%3A%20'stretch'%2C%0A%20%20%20%20%20%20%7D%7D%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bwidth%3A%2050%2C%20height%3A%2050%2C%20backgroundColor%3A%20'powderblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%2050%2C%20backgroundColor%3A%20'skyblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CView%20style%3D%7B%7Bheight%3A%20100%2C%20backgroundColor%3A%20'steelblue'%7D%7D%20%2F%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%20skip%20this%20line%20if%20using%20Create%20React%20Native%20App%0AAppRegistry.registerComponent('AwesomeProject'%2C%20()%20%3D%3E%20AlignItemsBasics)%3B%0A" frame-border="0"></iframe></div>
|
||||
|
||||
<h4><a class="anchor" aria-hidden="true" id="going-deeper"></a><a href="#going-deeper" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Going Deeper</h4>
|
||||
<p>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 <a href="/react-native/docs/0.12/layout-props">here</a>.</p>
|
||||
|
||||
@@ -260,7 +260,7 @@ npm start
|
||||
</blockquote>
|
||||
<p>Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="2-install-the-android-sdk"></a><a href="#2-install-the-android-sdk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Install the Android SDK</h4>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 6.0 (Marshmallow)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 8.0 (Oreo)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png" alt="Android Studio Welcome"></p>
|
||||
@@ -270,11 +270,9 @@ npm start
|
||||
<blockquote>
|
||||
<p>The SDK Manager can also be found within the Android Studio "Preferences" dialog, under <strong>Appearance & Behavior</strong> → <strong>System Settings</strong> → <strong>Android SDK</strong>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>Android 6.0 (Marshmallow)</code> entry, then make sure the following items are all checked:</p>
|
||||
<p>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 <code>Android 8.0 (Oreo)</code> entry, then make sure the following items are all checked:</p>
|
||||
<ul>
|
||||
<li><code>Google APIs</code></li>
|
||||
<li><code>Android SDK Platform 23</code></li>
|
||||
<li><code>Intel x86 Atom_64 System Image</code></li>
|
||||
<li><code>Android SDK Platform 26</code></li>
|
||||
<li><code>Google APIs Intel x86 Atom_64 System Image</code></li>
|
||||
</ul>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -282,11 +280,11 @@ npm start
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerWindows.png" alt="Android SDK Manager"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>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 <code>23.0.1</code> is selected.</p>
|
||||
<p>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 <code>26.0.3</code> is selected.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>Finally, click "Apply" to download and install the Android SDK and related build tools.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -303,12 +301,14 @@ npm start
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native linux android" /></p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">ANDROID_HOME</span>=<span class="hljs-variable">$HOME</span>/Android/Sdk
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native mac linux android" /></p>
|
||||
<blockquote>
|
||||
@@ -351,7 +351,7 @@ npm start
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-physical-device"></a><a href="#using-a-physical-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a physical device</h3>
|
||||
<p>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 <a href="/react-native/docs/0.12/running-on-device">here</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-virtual-device"></a><a href="#using-a-virtual-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a virtual device</h3>
|
||||
<p>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:</p>
|
||||
<p>If you use Android Studio to open <code>./AwesomeProject/android</code>, 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:</p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioAVD.png" alt="Android Studio AVD Manager"></p>
|
||||
<p>If you have just installed Android Studio, you will likely need to <a href="https://developer.android.com/studio/run/managing-avds.html">create a new AVD</a>. Select "Create Virtual Device...", then pick any Phone from the list and click "Next".</p>
|
||||
<p><block class="native windows android" /></p>
|
||||
@@ -359,7 +359,7 @@ npm start
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedCreateAVDMacOS.png" alt="Android Studio AVD Manager"></p>
|
||||
<p><block class="native mac windows linux android" /></p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Marshmallow</strong> API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.</p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Oreo</strong> API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.</p>
|
||||
<p><block class="native linux android" /></p>
|
||||
<blockquote>
|
||||
<p>We recommend configuring <a href="https://developer.android.com/studio/run/emulator-acceleration.html#vm-linux">VM acceleration</a> on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.</p>
|
||||
|
||||
@@ -260,7 +260,7 @@ npm start
|
||||
</blockquote>
|
||||
<p>Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.</p>
|
||||
<h4><a class="anchor" aria-hidden="true" id="2-install-the-android-sdk"></a><a href="#2-install-the-android-sdk" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Install the Android SDK</h4>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 6.0 (Marshmallow)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the <code>Android 8.0 (Oreo)</code> SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.</p>
|
||||
<p>The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png" alt="Android Studio Welcome"></p>
|
||||
@@ -270,11 +270,9 @@ npm start
|
||||
<blockquote>
|
||||
<p>The SDK Manager can also be found within the Android Studio "Preferences" dialog, under <strong>Appearance & Behavior</strong> → <strong>System Settings</strong> → <strong>Android SDK</strong>.</p>
|
||||
</blockquote>
|
||||
<p>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 <code>Android 6.0 (Marshmallow)</code> entry, then make sure the following items are all checked:</p>
|
||||
<p>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 <code>Android 8.0 (Oreo)</code> entry, then make sure the following items are all checked:</p>
|
||||
<ul>
|
||||
<li><code>Google APIs</code></li>
|
||||
<li><code>Android SDK Platform 23</code></li>
|
||||
<li><code>Intel x86 Atom_64 System Image</code></li>
|
||||
<li><code>Android SDK Platform 26</code></li>
|
||||
<li><code>Google APIs Intel x86 Atom_64 System Image</code></li>
|
||||
</ul>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -282,11 +280,11 @@ npm start
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerWindows.png" alt="Android SDK Manager"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>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 <code>23.0.1</code> is selected.</p>
|
||||
<p>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 <code>26.0.3</code> is selected.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsMacOS.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 23.0.1 Build Tools"></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidSDKManagerSDKToolsWindows.png" alt="Android SDK Manager - 26.0.3 Build Tools"></p>
|
||||
<p><block class="native windows mac linux android" /></p>
|
||||
<p>Finally, click "Apply" to download and install the Android SDK and related build tools.</p>
|
||||
<p><block class="native mac android" /></p>
|
||||
@@ -303,12 +301,14 @@ npm start
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native linux android" /></p>
|
||||
<pre><code class="hljs"><span class="hljs-builtin-name">export</span> <span class="hljs-attribute">ANDROID_HOME</span>=<span class="hljs-variable">$HOME</span>/Android/Sdk
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/tools/bin
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/platform-tools
|
||||
<span class="hljs-builtin-name">export</span> <span class="hljs-attribute">PATH</span>=<span class="hljs-variable">$PATH</span>:$ANDROID_HOME/emulator
|
||||
</code></pre>
|
||||
<p><block class="native mac linux android" /></p>
|
||||
<blockquote>
|
||||
@@ -351,7 +351,7 @@ npm start
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-physical-device"></a><a href="#using-a-physical-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a physical device</h3>
|
||||
<p>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 <a href="/react-native/docs/0.12/running-on-device">here</a>.</p>
|
||||
<h3><a class="anchor" aria-hidden="true" id="using-a-virtual-device"></a><a href="#using-a-virtual-device" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Using a virtual device</h3>
|
||||
<p>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:</p>
|
||||
<p>If you use Android Studio to open <code>./AwesomeProject/android</code>, 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:</p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedAndroidStudioAVD.png" alt="Android Studio AVD Manager"></p>
|
||||
<p>If you have just installed Android Studio, you will likely need to <a href="https://developer.android.com/studio/run/managing-avds.html">create a new AVD</a>. Select "Create Virtual Device...", then pick any Phone from the list and click "Next".</p>
|
||||
<p><block class="native windows android" /></p>
|
||||
@@ -359,7 +359,7 @@ npm start
|
||||
<p><block class="native mac android" /></p>
|
||||
<p><img src="/react-native/docs/assets/GettingStartedCreateAVDMacOS.png" alt="Android Studio AVD Manager"></p>
|
||||
<p><block class="native mac windows linux android" /></p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Marshmallow</strong> API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.</p>
|
||||
<p>Select the "x86 Images" tab, then look for the <strong>Oreo</strong> API Level 26, x86_64 ABI image with a Android 8.0 (Google APIs) target.</p>
|
||||
<p><block class="native linux android" /></p>
|
||||
<blockquote>
|
||||
<p>We recommend configuring <a href="https://developer.android.com/studio/run/emulator-acceleration.html#vm-linux">VM acceleration</a> on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.</p>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user