Split out docs to their own repo

Reviewed By: yungsters

Differential Revision: D6462045

fbshipit-source-id: c4fe1e3bd2ccf4dbd344587456f027d6404ccbe7
This commit is contained in:
Héctor Ramos 2017-12-05 12:58:50 -08:00 committed by Facebook Github Bot
parent a99f0d6100
commit 2d86618e7e
333 changed files with 2 additions and 42552 deletions

View File

@ -4,12 +4,7 @@
**/main.js
Libraries/vendor/**/*
Libraries/Renderer/*
website/node_modules
pr-inactivity-bookmarklet.js
question-bookmarklet.js
flow/
website/core/metadata.js
website/core/metadata-blog.js
website/src/react-native/docs/
website/src/react-native/blog/
danger/

View File

@ -5,9 +5,6 @@
; Ignore templates for 'react-native init'
.*/local-cli/templates/.*
; Ignore the website subdir
<PROJECT_ROOT>/website/.*
; Ignore the Dangerfile
<PROJECT_ROOT>/danger/dangerfile.js

3
.github/CODEOWNERS vendored
View File

@ -9,10 +9,7 @@ React/Views/* @shergin
React/Modules/* @shergin
React/CxxBridge/* @mhorowitz
ReactAndroid/src/main/java/com/facebook/react/animated/* @janicduplessis
website/* @hramos
website/showcase.json @hramos
package.json @hramos
website/package.json @hramos
local-cli/core/* @grabbou @kureev
local-cli/link/* @grabbou @kureev
local-cli/unlink/* @grabbou @kureev

View File

@ -106,11 +106,10 @@ All pull requests should be opened against the `master` branch. After opening yo
#### Test plan
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website.
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI.
* If you've added code that should be tested, add tests!
* If you've changed APIs, update the documentation.
* If you've updated the docs, verify the website locally and submit screenshots if applicable (see [website/README.md](https://github.com/facebook/react-native/blob/master/website/README.md))
See [What is a Test Plan?](https://medium.com/@martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9) to learn more.

View File

@ -1,180 +0,0 @@
---
id: accessibility
title: Accessibility
layout: docs
category: Guides
permalink: docs/accessibility.html
next: improvingux
previous: animations
---
## Native App Accessibility (iOS and Android)
Both iOS and Android provide APIs for making apps accessible to people with disabilities. In addition, both platforms provide bundled assistive technologies, like the screen readers VoiceOver (iOS) and TalkBack (Android) for the visually impaired. Similarly, in React Native we have included APIs designed to provide developers with support for making apps more accessible. Take note, iOS and Android differ slightly in their approaches, and thus the React Native implementations may vary by platform.
In addition to this documentation, you might find [this blog post](https://code.facebook.com/posts/435862739941212/making-react-native-apps-accessible/) about React Native accessibility to be useful.
## Making Apps Accessible
### Accessibility properties
#### accessible (iOS, Android)
When `true`, indicates that the view is an accessibility element. When a view is an accessibility element, it groups its children into a single selectable component. By default, all touchable elements are accessible.
On Android, accessible={true} property for a react-native View will be translated into native focusable={true}.
```javascript
<View accessible={true}>
<Text>text one</Text>
<Text>text two</Text>
</View>
```
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.
#### accessibilityLabel (iOS, Android)
When a view is marked as accessible, it is a good practice to set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected. VoiceOver will read this string when a user selects the associated element.
To use, set the `accessibilityLabel` property to a custom string on your View:
```javascript
<TouchableOpacity accessible={true} accessibilityLabel={'Tap me!'} onPress={this._onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableOpacity>
```
In the above example, the `accessibilityLabel` on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.
#### accessibilityTraits (iOS)
Accessibility traits tell a person using VoiceOver what kind of element they have selected. Is this element a label? A button? A header? These questions are answered by `accessibilityTraits`.
To use, set the `accessibilityTraits` property to one of (or an array of) accessibility trait strings:
* **none** Used when the element has no traits.
* **button** Used when the element should be treated as a button.
* **link** Used when the element should be treated as a link.
* **header** Used when an element acts as a header for a content section (e.g. the title of a navigation bar).
* **search** Used when the text field element should also be treated as a search field.
* **image** Used when the element should be treated as an image. Can be combined with button or link, for example.
* **selected** Used when the element is selected. For example, a selected row in a table or a selected button within a segmented control.
* **plays** Used when the element plays its own sound when activated.
* **key** Used when the element acts as a keyboard key.
* **text** Used when the element should be treated as static text that cannot change.
* **summary** Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches. For example, when Weather first launches, the element with today's weather conditions is marked with this trait.
* **disabled** Used when the control is not enabled and does not respond to user input.
* **frequentUpdates** Used when the element frequently updates its label or value, but too often to send notifications. Allows an accessibility client to poll for changes. A stopwatch would be an example.
* **startsMedia** Used when activating an element starts a media session (e.g. playing a movie, recording audio) that should not be interrupted by output from an assistive technology, like VoiceOver.
* **adjustable** Used when an element can be "adjusted" (e.g. a slider).
* **allowsDirectInteraction** Used when an element allows direct touch interaction for VoiceOver users (for example, a view representing a piano keyboard).
* **pageTurn** Informs VoiceOver that it should scroll to the next page when it finishes reading the contents of the element.
#### accessibilityViewIsModal (iOS)
A Boolean value indicating whether VoiceOver should ignore the elements within views that are siblings of the receiver.
For example, in a window that contains sibling views `A` and `B`, setting `accessibilityViewIsModal` to `true` on view `B` causes VoiceOver to ignore the elements in the view `A`.
On the other hand, if view `B` contains a child view `C` and you set `accessibilityViewIsModal` to `true` on view `C`, VoiceOver does not ignore the elements in view `A`.
#### onAccessibilityTap (iOS)
Use this property to assign a custom function to be called when someone activates an accessible element by double tapping on it while it's selected.
#### onMagicTap (iOS)
Assign this property to a custom function which will be called when someone performs the "magic tap" gesture, which is a double-tap with two fingers. A magic tap function should perform the most relevant action a user could take on a component. In the Phone app on iPhone, a magic tap answers a phone call, or ends the current one. If the selected element does not have an `onMagicTap` function, the system will traverse up the view hierarchy until it finds a view that does.
#### accessibilityComponentType (Android)
In some cases, we also want to alert the end user of the type of selected component (i.e., that it is a “button”). If we were using native buttons, this would work automatically. Since we are using javascript, we need to provide a bit more context for TalkBack. To do so, you must specify the accessibilityComponentType property for any UI component. For instances, we support button, radiobutton_checked and radiobutton_unchecked and so on.
```javascript
<TouchableWithoutFeedback accessibilityComponentType=”button”
onPress={this._onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableWithoutFeedback>
```
In the above example, the TouchableWithoutFeedback is being announced by TalkBack as a native Button.
#### accessibilityLiveRegion (Android)
When components dynamically change, we want TalkBack to alert the end user. This is made possible by the accessibilityLiveRegion property. It can be set to none, polite and assertive:
* **none** Accessibility services should not announce changes to this view.
* **polite** Accessibility services should announce changes to this view.
* **assertive** Accessibility services should interrupt ongoing speech to immediately announce changes to this view.
```javascript
<TouchableWithoutFeedback onPress={this._addOne}>
<View style={styles.embedded}>
<Text>Click me</Text>
</View>
</TouchableWithoutFeedback>
<Text accessibilityLiveRegion="polite">
Clicked {this.state.count} times
</Text>
```
In the above example method _addOne changes the state.count variable. As soon as an end user clicks the TouchableWithoutFeedback, TalkBack reads text in the Text view because of its 'accessibilityLiveRegion=”polite”' property.
#### importantForAccessibility (Android)
In the case of two overlapping UI components with the same parent, default accessibility focus can have unpredictable behavior. The importantForAccessibility property will resolve this by controlling if a view fires accessibility events and if it is reported to accessibility services. It can be set to auto, yes, no and no-hide-descendants (the last value will force accessibility services to ignore the component and all of its children).
```javascript
<View style={styles.container}>
<View style={{position: 'absolute', left: 10, top: 10, right: 10, height: 100,
backgroundColor: 'green'}} importantForAccessibility=”yes”>
<Text> First layout </Text>
</View>
<View style={{position: 'absolute', left: 10, top: 10, right: 10, height: 100,
backgroundColor: 'yellow'}} importantForAccessibility=”no-hide-descendants”>
<Text> Second layout </Text>
</View>
</View>
```
In the above example, the yellow layout and its descendants are completely invisible to TalkBack and all other accessibility services. So we can easily use overlapping views with the same parent without confusing TalkBack.
### Checking if a Screen Reader is Enabled
The `AccessibilityInfo` API allows you to determine whether or not a screen reader is currently active. See the [AccessibilityInfo documentation](docs/accessibilityinfo.html) for details.
### Sending Accessibility Events (Android)
Sometimes it is useful to trigger an accessibility event on a UI component (i.e. when a custom view appears on a screen or a custom radio button has been selected). Native UIManager module exposes a method sendAccessibilityEvent for this purpose. It takes two arguments: view tag and a type of an event.
```javascript
_onPress: function() {
this.state.radioButton = this.state.radioButton === “radiobutton_checked” ?
“radiobutton_unchecked” : “radiobutton_checked”;
if (this.state.radioButton === “radiobutton_checked”) {
RCTUIManager.sendAccessibilityEvent(
ReactNative.findNodeHandle(this),
RCTUIManager.AccessibilityEventTypes.typeViewClicked);
}
}
<CustomRadioButton
accessibleComponentType={this.state.radioButton}
onPress={this._onPress}/>
```
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.
## Testing VoiceOver Support (iOS)
To enable VoiceOver, go to the Settings app on your iOS device. Tap General, then Accessibility. There you will find many tools that people use to make their devices more usable, such as bolder text, increased contrast, and VoiceOver.
To enable VoiceOver, tap on VoiceOver under "Vision" and toggle the switch that appears at the top.
At the very bottom of the Accessibility settings, there is an "Accessibility Shortcut". You can use this to toggle VoiceOver by triple clicking the Home button.

View File

@ -1,512 +0,0 @@
---
id: animations
title: Animations
layout: docs
category: Guides
permalink: docs/animations.html
next: accessibility
previous: images
---
Animations are very important to create a great user experience.
Stationary objects must overcome inertia as they start moving.
Objects in motion have momentum and rarely come to a stop immediately.
Animations allow you to convey physically believable motion in your interface.
React Native provides two complementary animation systems:
[`Animated`](docs/animations.html#animated-api) for granular and interactive control of specific values, and
[`LayoutAnimation`](docs/animations.html#layoutanimation) for animated global layout transactions.
## `Animated` API
The [`Animated`](docs/animated.html) API is designed to make it very easy to concisely express a wide variety of interesting animation and interaction patterns in a very performant way.
`Animated` focuses on declarative relationships between inputs and outputs, with configurable transforms in between, and simple `start`/`stop` methods to control time-based animation execution.
`Animated` exports four animatable component types: `View`, `Text`, `Image`, and `ScrollView`, but you can also create your own using `Animated.createAnimatedComponent()`.
For example, a container view that fades in when it is mounted may look like this:
```SnackPlayer
import React from 'react';
import { Animated, Text, View } from 'react-native';
class FadeInView extends React.Component {
state = {
fadeAnim: new Animated.Value(0), // Initial value for opacity: 0
}
componentDidMount() {
Animated.timing( // Animate over time
this.state.fadeAnim, // The animated value to drive
{
toValue: 1, // Animate to opacity: 1 (opaque)
duration: 10000, // Make it take a while
}
).start(); // Starts the animation
}
render() {
let { fadeAnim } = this.state;
return (
<Animated.View // Special animatable View
style={{
...this.props.style,
opacity: fadeAnim, // Bind opacity to animated value
}}
>
{this.props.children}
</Animated.View>
);
}
}
// You can then use your `FadeInView` in place of a `View` in your components:
export default class App extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
<Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
</FadeInView>
</View>
)
}
}
```
Let's break down what's happening here.
In the `FadeInView` constructor, a new `Animated.Value` called `fadeAnim` is initialized as part of `state`.
The opacity property on the `View` is mapped to this animated value.
Behind the scenes, the numeric value is extracted and used to set opacity.
When the component mounts, the opacity is set to 0.
Then, an easing animation is started on the `fadeAnim` animated value,
which will update all of its dependent mappings (in this case, just the opacity) on each frame as the value animates to the final value of 1.
This is done in an optimized way that is faster than calling `setState` and re-rendering.
Because the entire configuration is declarative, we will be able to implement further optimizations that serialize the configuration and runs the animation on a high-priority thread.
### Configuring animations
Animations are heavily configurable. Custom and predefined easing functions, delays, durations, decay factors, spring constants, and more can all be tweaked depending on the type of animation.
`Animated` provides several animation types, the most commonly used one being [`Animated.timing()`](docs/animated.html#timing).
It supports animating a value over time using one of various predefined easing functions, or you can use your own.
Easing functions are typically used in animation to convey gradual acceleration and deceleration of objects.
By default, `timing` will use a easeInOut curve that conveys gradual acceleration to full speed and concludes by gradually decelerating to a stop.
You can specify a different easing function by passing a `easing` parameter.
Custom `duration` or even a `delay` before the animation starts is also supported.
For example, if we want to create a 2-second long animation of an object that slightly backs up before moving to its final position:
```javascript
Animated.timing(
this.state.xPosition,
{
toValue: 100,
easing: Easing.back(),
duration: 2000,
}
).start();
```
Take a look at the [Configuring animations](docs/animated.html#configuring-animations) section of the `Animated` API reference to learn more about all the config parameters supported by the built-in animations.
### Composing animations
Animations can be combined and played in sequence or in parallel.
Sequential animations can play immediately after the previous animation has finished,
or they can start after a specified delay.
The `Animated` API provides several methods, such as `sequence()` and `delay()`,
each of which simply take an array of animations to execute and automatically calls `start()`/`stop()` as needed.
For example, the following animation coasts to a stop, then it springs back while twirling in parallel:
```javascript
Animated.sequence([ // decay, then spring to start and twirl
Animated.decay(position, { // coast to a stop
velocity: {x: gestureState.vx, y: gestureState.vy}, // velocity from gesture release
deceleration: 0.997,
}),
Animated.parallel([ // after decay, in parallel:
Animated.spring(position, {
toValue: {x: 0, y: 0} // return to start
}),
Animated.timing(twirl, { // and twirl
toValue: 360,
}),
]),
]).start(); // start the sequence group
```
If one animation is stopped or interrupted, then all other animations in the group are also stopped.
`Animated.parallel` has a `stopTogether` option that can be set to `false` to disable this.
You can find a full list of composition methods in the [Composing animations](docs/animated.html#composing-animations) section of the `Animated` API reference.
### Combining animated values
You can [combine two animated values](docs/animated.html#combining-animated-values) via addition, multiplication, division, or modulo to make a new animated value.
There are some cases where an animated value needs to invert another animated value for calculation.
An example is inverting a scale (2x --> 0.5x):
```javascript
const a = new Animated.Value(1);
const b = Animated.divide(1, a);
Animated.spring(a, {
toValue: 2,
}).start();
```
### Interpolation
Each property can be run through an interpolation first.
An interpolation maps input ranges to output ranges,
typically using a linear interpolation but also supports easing functions.
By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value.
A simple mapping to convert a 0-1 range to a 0-100 range would be:
```javascript
value.interpolate({
inputRange: [0, 1],
outputRange: [0, 100],
});
```
For example, you may want to think about your `Animated.Value` as going from 0 to 1,
but animate the position from 150px to 0px and the opacity from 0 to 1.
This can easily be done by modifying `style` from the example above like so:
```javascript
style={{
opacity: this.state.fadeAnim, // Binds directly
transform: [{
translateY: this.state.fadeAnim.interpolate({
inputRange: [0, 1],
outputRange: [150, 0] // 0 : 150, 0.5 : 75, 1 : 0
}),
}],
}}
```
[`interpolate()`](docs/animated.html#interpolate) supports multiple range segments as well, which is handy for defining dead zones and other handy tricks.
For example, to get an negation relationship at -300 that goes to 0 at -100, then back up to 1 at 0, and then back down to zero at 100 followed by a dead-zone that remains at 0 for everything beyond that, you could do:
```javascript
value.interpolate({
inputRange: [-300, -100, 0, 100, 101],
outputRange: [300, 0, 1, 0, 0],
});
```
Which would map like so:
```
Input | Output
------|-------
-400| 450
-300| 300
-200| 150
-100| 0
-50| 0.5
0| 1
50| 0.5
100| 0
101| 0
200| 0
```
`interpolate()` also supports mapping to strings, allowing you to animate colors as well as values with units. For example, if you wanted to animate a rotation you could do:
```javascript
value.interpolate({
inputRange: [0, 360],
outputRange: ['0deg', '360deg']
})
```
`interpolate()` also supports arbitrary easing functions, many of which are already implemented in the
[`Easing`](docs/easing.html) module.
`interpolate()` also has configurable behavior for extrapolating the `outputRange`.
You can set the extrapolation by setting the `extrapolate`, `extrapolateLeft`, or `extrapolateRight` options.
The default value is `extend` but you can use `clamp` to prevent the output value from exceeding `outputRange`.
### Tracking dynamic values
Animated values can also track other values.
Just set the `toValue` of an animation to another animated value instead of a plain number.
For example, a "Chat Heads" animation like the one used by Messenger on Android could be implemented with a `spring()` pinned on another animated value, or with `timing()` and a `duration` of 0 for rigid tracking.
They can also be composed with interpolations:
```javascript
Animated.spring(follower, {toValue: leader}).start();
Animated.timing(opacity, {
toValue: pan.x.interpolate({
inputRange: [0, 300],
outputRange: [1, 0],
}),
}).start();
```
The `leader` and `follower` animated values would be implemented using `Animated.ValueXY()`.
`ValueXY` is a handy way to deal with 2D interactions, such as panning or dragging.
It is a simple wrapper that basically contains two `Animated.Value` instances and some helper functions that call through to them,
making `ValueXY` a drop-in replacement for `Value` in many cases.
It allows us to track both x and y values in the example above.
### Tracking gestures
Gestures, like panning or scrolling, and other events can map directly to animated values using [`Animated.event`](docs/animated.html#event).
This is done with a structured map syntax so that values can be extracted from complex event objects.
The first level is an array to allow mapping across multiple args, and that array contains nested objects.
For example, when working with horizontal scrolling gestures,
you would do the following in order to map `event.nativeEvent.contentOffset.x` to `scrollX` (an `Animated.Value`):
```javascript
onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{ nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}
```
When using `PanResponder`, you could use the following code to extract the x and y positions from `gestureState.dx` and `gestureState.dy`.
We use a `null` in the first position of the array, as we are only interested in the second argument passed to the `PanResponder` handler,
which is the `gestureState`.
```javascript
onPanResponderMove={Animated.event(
[null, // ignore the native event
// extract dx and dy from gestureState
// like 'pan.x = gestureState.dx, pan.y = gestureState.dy'
{dx: pan.x, dy: pan.y}
])}
```
### Responding to the current animation value
You may notice that there is no obvious way to read the current value while animating.
This is because the value may only be known in the native runtime due to optimizations.
If you need to run JavaScript in response to the current value, there are two approaches:
- `spring.stopAnimation(callback)` will stop the animation and invoke `callback` with the final value. This is useful when making gesture transitions.
- `spring.addListener(callback)` will invoke `callback` asynchronously while the animation is running, providing a recent value.
This is useful for triggering state changes,
for example snapping a bobble to a new option as the user drags it closer,
because these larger state changes are less sensitive to a few frames of lag compared to continuous gestures like panning which need to run at 60 fps.
`Animated` is designed to be fully serializable so that animations can be run in a high performance way, independent of the normal JavaScript event loop.
This does influence the API, so keep that in mind when it seems a little trickier to do something compared to a fully synchronous system.
Check out `Animated.Value.addListener` as a way to work around some of these limitations,
but use it sparingly since it might have performance implications in the future.
### Using the native driver
The `Animated` API is designed to be serializable.
By using the [native driver](http://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html),
we send everything about the animation to native before starting the animation,
allowing native code to perform the animation on the UI thread without having to go through the bridge on every frame.
Once the animation has started, the JS thread can be blocked without affecting the animation.
Using the native driver for normal animations is quite simple.
Just add `useNativeDriver: true` to the animation config when starting it.
```javascript
Animated.timing(this.state.animatedValue, {
toValue: 1,
duration: 500,
useNativeDriver: true, // <-- Add this
}).start();
```
Animated values are only compatible with one driver so if you use native driver when starting an animation on a value,
make sure every animation on that value also uses the native driver.
The native driver also works with `Animated.event`.
This is specially useful for animations that follow the scroll position as without the native driver,
the animation will always run a frame behind the gesture due to the async nature of React Native.
```javascript
<Animated.ScrollView // <-- Use the Animated ScrollView wrapper
scrollEventThrottle={1} // <-- Use 1 here to make sure no events are ever missed
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.animatedValue } } }],
{ useNativeDriver: true } // <-- Add this
)}
>
{content}
</Animated.ScrollView>
```
You can see the native driver in action by running the [RNTester app](https://github.com/facebook/react-native/blob/master/RNTester/),
then loading the Native Animated Example.
You can also take a look at the [source code](https://github.com/facebook/react-native/blob/master/RNTester/js/NativeAnimationsExample.js) to learn how these examples were produced.
#### Caveats
Not everything you can do with `Animated` is currently supported by the native driver.
The main limitation is that you can only animate non-layout properties:
things like `transform` and `opacity` will work, but flexbox and position properties will not.
When using `Animated.event`, it will only work with direct events and not bubbling events.
This means it does not work with `PanResponder` but does work with things like `ScrollView#onScroll`.
When an animation is running, it can prevent `VirtualizedList` components from rendering more rows. If you need to run a long or looping animation while the user is scrolling through a list, you can use `isInteraction: false` in your animation's config to prevent this issue.
### Bear in mind
While using transform styles such as `rotateY`, `rotateX`, and others ensure the transform style `perspective` is in place.
At this time some animations may not render on Android without it. Example below.
```javascript
<Animated.View
style={{
transform: [
{ scale: this.state.scale },
{ rotateY: this.state.rotateY },
{ perspective: 1000 } // without this line this Animation will not render on Android while working fine on iOS
]
}}
/>
```
### Additional examples
The RNTester app has various examples of `Animated` in use:
- [AnimatedGratuitousApp](https://github.com/facebook/react-native/tree/master/RNTester/js/AnimatedGratuitousApp)
- [NativeAnimationsExample](https://github.com/facebook/react-native/blob/master/RNTester/js/NativeAnimationsExample.js)
## `LayoutAnimation` API
`LayoutAnimation` allows you to globally configure `create` and `update`
animations that will be used for all views in the next render/layout cycle.
This is useful for doing flexbox layout updates without bothering to measure or
calculate specific properties in order to animate them directly, and is
especially useful when layout changes may affect ancestors, for example a "see
more" expansion that also increases the size of the parent and pushes down the
row below which would otherwise require explicit coordination between the
components in order to animate them all in sync.
Note that although `LayoutAnimation` is very powerful and can be quite useful,
it provides much less control than `Animated` and other animation libraries, so
you may need to use another approach if you can't get `LayoutAnimation` to do
what you want.
Note that in order to get this to work on **Android** you need to set the following flags via `UIManager`:
```javascript
UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
```
```SnackPlayer
import React from 'react';
import {
NativeModules,
LayoutAnimation,
Text,
TouchableOpacity,
StyleSheet,
View,
} from 'react-native';
const { UIManager } = NativeModules;
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
export default class App extends React.Component {
state = {
w: 100,
h: 100,
};
_onPress = () => {
// Animate the update
LayoutAnimation.spring();
this.setState({w: this.state.w + 15, h: this.state.h + 15})
}
render() {
return (
<View style={styles.container}>
<View style={[styles.box, {width: this.state.w, height: this.state.h}]} />
<TouchableOpacity onPress={this._onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 200,
height: 200,
backgroundColor: 'red',
},
button: {
backgroundColor: 'black',
paddingHorizontal: 20,
paddingVertical: 15,
marginTop: 15,
},
buttonText: {
color: '#fff',
fontWeight: 'bold',
},
});
```
This example uses a preset value, you can customize the animations as
you need, see [LayoutAnimation.js](https://github.com/facebook/react-native/blob/master/Libraries/LayoutAnimation/LayoutAnimation.js)
for more information.
## Additional notes
### `requestAnimationFrame`
`requestAnimationFrame` is a polyfill from the browser that you might be
familiar with. It accepts a function as its only argument and calls that
function before the next repaint. It is an essential building block for
animations that underlies all of the JavaScript-based animation APIs. In
general, you shouldn't need to call this yourself - the animation APIs will
manage frame updates for you.
### `setNativeProps`
As mentioned [in the Direct Manipulation section](docs/direct-manipulation.html),
`setNativeProps` allows us to modify properties of native-backed
components (components that are actually backed by native views, unlike
composite components) directly, without having to `setState` and
re-render the component hierarchy.
We could use this in the Rebound example to update the scale - this
might be helpful if the component that we are updating is deeply nested
and hasn't been optimized with `shouldComponentUpdate`.
If you find your animations with dropping frames (performing below 60 frames
per second), look into using `setNativeProps` or `shouldComponentUpdate` to
optimize them. Or you could run the animations on the UI thread rather than
the JavaScript thread [with the useNativeDriver
option](http://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html).
You may also want to defer any computationally intensive work until after
animations are complete, using the
[InteractionManager](docs/interactionmanager.html). You can monitor the
frame rate by using the In-App Developer Menu "FPS Monitor" tool.

View File

@ -1,187 +0,0 @@
---
id: colors
title: Color Reference
layout: docs
category: Guides
permalink: docs/colors.html
next: integration-with-existing-apps
previous: direct-manipulation
---
Components in React Native are [styled using JavaScript](docs/style.html). Color properties usually match how [CSS works on the web](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value).
### Red-green-blue
React Native supports `rgb()` and `rgba()` in both hexadecimal and functional notation:
- `'#f0f'` (#rgb)
- `'#ff00ff'` (#rrggbb)
- `'rgb(255, 0, 255)'`
- `'rgba(255, 255, 255, 1.0)'`
- `'#f0ff'` (#rgba)
- `'#ff00ff00'` (#rrggbbaa)
### Hue-saturation-lightness
`hsl()` and `hsla()` is supported in functional notation:
- `'hsl(360, 100%, 100%)'`
- `'hsla(360, 100%, 100%, 1.0)'`
### `transparent`
This is a shortcut for `rgba(0,0,0,0)`:
- `'transparent'`
### Named colors
You can also use color names as values. React Native follows the [CSS3 specification](http://www.w3.org/TR/css3-color/#svg-color):
- <color aliceblue /> aliceblue (#f0f8ff)
- <color antiquewhite /> antiquewhite (#faebd7)
- <color aqua /> aqua (#00ffff)
- <color aquamarine /> aquamarine (#7fffd4)
- <color azure /> azure (#f0ffff)
- <color beige /> beige (#f5f5dc)
- <color bisque /> bisque (#ffe4c4)
- <color black /> black (#000000)
- <color blanchedalmond /> blanchedalmond (#ffebcd)
- <color blue /> blue (#0000ff)
- <color blueviolet /> blueviolet (#8a2be2)
- <color brown /> brown (#a52a2a)
- <color burlywood /> burlywood (#deb887)
- <color cadetblue /> cadetblue (#5f9ea0)
- <color chartreuse /> chartreuse (#7fff00)
- <color chocolate /> chocolate (#d2691e)
- <color coral /> coral (#ff7f50)
- <color cornflowerblue /> cornflowerblue (#6495ed)
- <color cornsilk /> cornsilk (#fff8dc)
- <color crimson /> crimson (#dc143c)
- <color cyan /> cyan (#00ffff)
- <color darkblue /> darkblue (#00008b)
- <color darkcyan /> darkcyan (#008b8b)
- <color darkgoldenrod /> darkgoldenrod (#b8860b)
- <color darkgray /> darkgray (#a9a9a9)
- <color darkgreen /> darkgreen (#006400)
- <color darkgrey /> darkgrey (#a9a9a9)
- <color darkkhaki /> darkkhaki (#bdb76b)
- <color darkmagenta /> darkmagenta (#8b008b)
- <color darkolivegreen /> darkolivegreen (#556b2f)
- <color darkorange /> darkorange (#ff8c00)
- <color darkorchid /> darkorchid (#9932cc)
- <color darkred /> darkred (#8b0000)
- <color darksalmon /> darksalmon (#e9967a)
- <color darkseagreen /> darkseagreen (#8fbc8f)
- <color darkslateblue /> darkslateblue (#483d8b)
- <color darkslategrey /> darkslategrey (#2f4f4f)
- <color darkturquoise /> darkturquoise (#00ced1)
- <color darkviolet /> darkviolet (#9400d3)
- <color deeppink /> deeppink (#ff1493)
- <color deepskyblue /> deepskyblue (#00bfff)
- <color dimgray /> dimgray (#696969)
- <color dimgrey /> dimgrey (#696969)
- <color dodgerblue /> dodgerblue (#1e90ff)
- <color firebrick /> firebrick (#b22222)
- <color floralwhite /> floralwhite (#fffaf0)
- <color forestgreen /> forestgreen (#228b22)
- <color fuchsia /> fuchsia (#ff00ff)
- <color gainsboro /> gainsboro (#dcdcdc)
- <color ghostwhite /> ghostwhite (#f8f8ff)
- <color gold /> gold (#ffd700)
- <color goldenrod /> goldenrod (#daa520)
- <color gray /> gray (#808080)
- <color green /> green (#008000)
- <color greenyellow /> greenyellow (#adff2f)
- <color grey /> grey (#808080)
- <color honeydew /> honeydew (#f0fff0)
- <color hotpink /> hotpink (#ff69b4)
- <color indianred /> indianred (#cd5c5c)
- <color indigo /> indigo (#4b0082)
- <color ivory /> ivory (#fffff0)
- <color khaki /> khaki (#f0e68c)
- <color lavender /> lavender (#e6e6fa)
- <color lavenderblush /> lavenderblush (#fff0f5)
- <color lawngreen /> lawngreen (#7cfc00)
- <color lemonchiffon /> lemonchiffon (#fffacd)
- <color lightblue /> lightblue (#add8e6)
- <color lightcoral /> lightcoral (#f08080)
- <color lightcyan /> lightcyan (#e0ffff)
- <color lightgoldenrodyellow /> lightgoldenrodyellow (#fafad2)
- <color lightgray /> lightgray (#d3d3d3)
- <color lightgreen /> lightgreen (#90ee90)
- <color lightgrey /> lightgrey (#d3d3d3)
- <color lightpink /> lightpink (#ffb6c1)
- <color lightsalmon /> lightsalmon (#ffa07a)
- <color lightseagreen /> lightseagreen (#20b2aa)
- <color lightskyblue /> lightskyblue (#87cefa)
- <color lightslategrey /> lightslategrey (#778899)
- <color lightsteelblue /> lightsteelblue (#b0c4de)
- <color lightyellow /> lightyellow (#ffffe0)
- <color lime /> lime (#00ff00)
- <color limegreen /> limegreen (#32cd32)
- <color linen /> linen (#faf0e6)
- <color magenta /> magenta (#ff00ff)
- <color maroon /> maroon (#800000)
- <color mediumaquamarine /> mediumaquamarine (#66cdaa)
- <color mediumblue /> mediumblue (#0000cd)
- <color mediumorchid /> mediumorchid (#ba55d3)
- <color mediumpurple /> mediumpurple (#9370db)
- <color mediumseagreen /> mediumseagreen (#3cb371)
- <color mediumslateblue /> mediumslateblue (#7b68ee)
- <color mediumspringgreen /> mediumspringgreen (#00fa9a)
- <color mediumturquoise /> mediumturquoise (#48d1cc)
- <color mediumvioletred /> mediumvioletred (#c71585)
- <color midnightblue /> midnightblue (#191970)
- <color mintcream /> mintcream (#f5fffa)
- <color mistyrose /> mistyrose (#ffe4e1)
- <color moccasin /> moccasin (#ffe4b5)
- <color navajowhite /> navajowhite (#ffdead)
- <color navy /> navy (#000080)
- <color oldlace /> oldlace (#fdf5e6)
- <color olive /> olive (#808000)
- <color olivedrab /> olivedrab (#6b8e23)
- <color orange /> orange (#ffa500)
- <color orangered /> orangered (#ff4500)
- <color orchid /> orchid (#da70d6)
- <color palegoldenrod /> palegoldenrod (#eee8aa)
- <color palegreen /> palegreen (#98fb98)
- <color paleturquoise /> paleturquoise (#afeeee)
- <color palevioletred /> palevioletred (#db7093)
- <color papayawhip /> papayawhip (#ffefd5)
- <color peachpuff /> peachpuff (#ffdab9)
- <color peru /> peru (#cd853f)
- <color pink /> pink (#ffc0cb)
- <color plum /> plum (#dda0dd)
- <color powderblue /> powderblue (#b0e0e6)
- <color purple /> purple (#800080)
- <color rebeccapurple /> rebeccapurple (#663399)
- <color red /> red (#ff0000)
- <color rosybrown /> rosybrown (#bc8f8f)
- <color royalblue /> royalblue (#4169e1)
- <color saddlebrown /> saddlebrown (#8b4513)
- <color salmon /> salmon (#fa8072)
- <color sandybrown /> sandybrown (#f4a460)
- <color seagreen /> seagreen (#2e8b57)
- <color seashell /> seashell (#fff5ee)
- <color sienna /> sienna (#a0522d)
- <color silver /> silver (#c0c0c0)
- <color skyblue /> skyblue (#87ceeb)
- <color slateblue /> slateblue (#6a5acd)
- <color slategray /> slategray (#708090)
- <color snow /> snow (#fffafa)
- <color springgreen /> springgreen (#00ff7f)
- <color steelblue /> steelblue (#4682b4)
- <color tan /> tan (#d2b48c)
- <color teal /> teal (#008080)
- <color thistle /> thistle (#d8bfd8)
- <color tomato /> tomato (#ff6347)
- <color turquoise /> turquoise (#40e0d0)
- <color violet /> violet (#ee82ee)
- <color wheat /> wheat (#f5deb3)
- <color white /> white (#ffffff)
- <color whitesmoke /> whitesmoke (#f5f5f5)
- <color yellow /> yellow (#ffff00)
- <color yellowgreen /> yellowgreen (#9acd32)

View File

@ -1,221 +0,0 @@
---
id: contributing
title: How to Contribute
layout: docs
category: Contributing
permalink: docs/contributing.html
next: maintainers
previous: native-modules-android
---
React Native is one of Facebook's first open source projects that is both under very active development and is also being used to ship code to everybody using Facebook's mobile apps. If you're interested in contributing to React Native, hopefully this document makes the process for contributing clear.
## [Code of Conduct](https://code.facebook.com/codeofconduct)
Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please read [the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated.
## Get involved
There are many ways to contribute to React Native, and many of them do not involve writing any code. Here's a few ideas to get started:
* Simply start using React Native. Go through the [Getting Started](http://facebook.github.io/react-native/docs/getting-started.html) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](http://facebook.github.io/react-native/docs/contributing.html#reporting-new-issues).
* Look through the [open issues](https://github.com/facebook/react-native/issues). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](http://facebook.github.io/react-native/docs/contributing.html#triaging-issues-and-pull-requests).
* If you find an issue you would like to fix, [open a pull request](http://facebook.github.io/react-native/docs/contributing.html#your-first-pull-request). Issues tagged as [_Good first issue_](https://github.com/facebook/react-native/labels/Good%20first%20issue) are a good place to get started.
* Read through the [React Native docs](http://facebook.github.io/react-native/docs). If you find anything that is confusing or can be improved, you can make edits by clicking "Improve this page" at the bottom of most docs.
* Browse [Stack Overflow](https://stackoverflow.com/questions/tagged/react-native) and answer questions. This will help you get familiarized with common pitfalls or misunderstandings, which can be useful when contributing updates to the documentation.
* Take a look at the [features requested](https://react-native.canny.io/feature-requests) by others in the community and consider opening a pull request if you see something you want to work on.
Contributions are very welcome. If you think you need help planning your contribution, please hop into [#react-native](https://discord.gg/0ZcbPKXt5bZjGY5n) and let people know you're looking for a mentor.
Core contributors to React Native meet monthly and post their meeting notes on the [React Native blog](https://facebook.github.io/react-native/blog). You can also find ad hoc discussions in the [React Native Core Contributors](https://www.facebook.com/groups/reactnativeoss/) Facebook group.
### Triaging issues and pull requests
One great way you can contribute to the project without writing any code is to help triage issues and pull requests as they come in.
* Ask for more information if the issue does not provide all the details required by the template.
* Suggest [labels](https://github.com/facebook/react-native/labels) that can help categorize issues.
* Flag issues that are stale or that should be closed.
* Ask for test plans and review code.
You can learn more about handling issues in the [maintainer's guide](docs/maintainers.html#handling-issues).
## Our development process
Some of the core team will be working directly on [GitHub](https://github.com/facebook/react-native). These changes will be public from the beginning. Other changesets will come via a bridge with Facebook's internal source control. This is a necessity as it allows engineers at Facebook outside of the core team to move fast and contribute from an environment they are comfortable in.
When a change made on GitHub is approved, it will first be imported into Facebook's internal source control. The change will eventually sync back to GitHub as a single commit once it has passed all internal tests.
### Branch organization
We will do our best to keep `master` in good shape, with tests passing at all times. But in order to move fast, we will make API changes that your application might not be compatible with. We will do our best to [communicate these changes](https://github.com/facebook/react-native/releases) and version appropriately so you can lock into a specific version if need be.
To see what changes are coming and provide better feedback to React Native contributors, use the [latest release candidate](http://facebook.github.io/react-native/versions.html) when possible. By the time a release candidate is released, the changes it contains will have been shipped in production Facebook apps for over two weeks.
## Bugs
We use [GitHub Issues](https://github.com/facebook/react-native/issues) for our public bugs. If you would like to report a problem, take a look around and see if someone already opened an issue about it. If you a are certain this is a new, unreported bug, you can submit a [bug report](http://facebook.github.io/react-native/docs/contributing.html#reporting-new-issues).
If you have questions about using React Native, the [Community page](http://facebook.github.io/react-native/support.html) list various resources that should help you get started.
We also have a [place where you can request features or enhancements](https://react-native.canny.io/feature-requests). If you see anything you'd like to be implemented, vote it up and explain your use case.
## Reporting new issues
When [opening a new issue](https://github.com/facebook/react-native/issues/new), always make sure to fill out the [issue template](https://raw.githubusercontent.com/facebook/react-native/master/.github/ISSUE_TEMPLATE.md). **This step is very important!** Not doing so may result in your issue getting closed. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template.
* **One issue, one bug:** Please report a single bug per issue.
* **Provide a Snack:** The best way to get attention on your issue is to provide a reduced test case. You can use [Snack](https://snack.expo.io/) to demonstrate the issue.
* **Provide reproduction steps:** List all the steps necessary to reproduce the issue. Provide a Snack or upload a sample project to GitHub. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort.
* **Try out the latest version:** Verify that the issue can be reproduced locally by updating your project to use [React Native from `master`](http://facebook.github.io/react-native/versions.html). The bug may have already been fixed!
We're not able to provide support through GitHub Issues. If you're looking for help with your code, consider asking on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) or reaching out to the community through [other channels](https://facebook.github.io/react-native/support.html).
### Security bugs
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. With that in mind, please do not file public issues; go through the process outlined on that page.
## Pull requests
### Your first pull request
So you have decided to contribute code back to upstream by opening a pull request. You've invested a good chunk of time, and we appreciate it. We will do our best to work with you and get the PR looked at.
Working on your first Pull Request? You can learn how from this free video series:
[**How to Contribute to an Open Source Project on GitHub**](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)
We have a list of [beginner friendly issues](https://github.com/facebook/react-native/labels/Good%20First%20Task) to help you get your feet wet in the React Native codebase and familiar with our contribution process. This is a great place to get started.
### Proposing a change
If you would like to request a new feature or enhancement but are not yet thinking about opening a pull request, we have a [place to track feature requests](https://react-native.canny.io/feature-requests).
If you intend to change the public API, or make any non-trivial changes to the implementation, we recommend [filing an issue](https://github.com/facebook/react-native/issues/new?title=%5BProposal%5D) that includes `[Proposal]` in the title. This lets us reach an agreement on your proposal before you put significant effort into it. These types of issues should be rare. If you have been contributing to the project long enough, you will probably already have access to the [React Native Core Contributors](https://www.facebook.com/groups/reactnativeoss/) Facebook Group, where this sort of discussion is usually held.
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
### Sending a pull request
Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
Please make sure the following is done when submitting a pull request:
1. Fork [the repository](https://github.com/facebook/react-native) and create your branch from `master`.
2. Add the copyright notice to the top of any new files you've added.
3. Describe your [**test plan**](/react-native/docs/contributing.html#test-plan) in your pull request description. Make sure to [test your changes](/react-native/docs/testing.html)!
4. Make sure your code lints (`npm run lint`).
5. If you haven't already, [sign the CLA](https://code.facebook.com/cla).
All pull requests should be opened against the `master` branch. After opening your pull request, ensure [**all tests pass**](/react-native/docs/contributing.html#contrinuous-integration-tests) on Circle CI. If a test fails and you believe it is unrelated to your change, leave a comment on the pull request explaining why.
> **Note:** It is not necessary to keep clicking `Merge master to your branch` on the PR page. You would want to merge master if there are conflicts or tests are failing. The Facebook-GitHub-Bot ultimately squashes all commits to a single one before merging your PR.
#### Test plan
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website.
* If you've added code that should be tested, add tests!
* If you've changed APIs, update the documentation.
* If you've updated the docs, verify the website locally and submit screenshots if applicable (see [website/README.md](https://github.com/facebook/react-native/blob/master/website/README.md))
See [What is a Test Plan?](https://medium.com/@martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9) to learn more.
#### Continuous integration tests
Make sure all **tests pass** on [Circle CI][circle]. PRs that break tests are unlikely to be merged. Learn more about [testing your changes here](/react-native/docs/testing.html).
[circle]: http://circleci.com/gh/facebook/react-native
#### Breaking changes
When adding a new breaking change, follow this template in your pull request:
```
### New breaking change here
* **Who does this affect**:
* **How to migrate**:
* **Why make this breaking change**:
* **Severity (number of people affected x effort)**:
```
If your pull request is merged, a core contributor will update the [list of breaking changes](https://github.com/facebook/react-native/wiki/Breaking-Changes) which is then used to populate the release notes.
#### Copyright Notice for files
Copy and paste this to the top of your new file(s):
```JS
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
```
If you've added a new module, add a `@providesModule <moduleName>` at the end of the comment. This will allow the haste package manager to find it.
#### Contributor License Agreement (CLA)
In order to accept your pull request, we need you to submit a CLA. You only need to do this once, so if you've done this for another Facebook open source project, you're good to go. If you are submitting a pull request for the first time, the Facebook GitHub Bot will reply with a link to the CLA form. You may also [complete your CLA here](https://code.facebook.com/cla).
### What happens next?
The core team will be monitoring for pull requests. Read [what to expect from maintainers](/react-native/docs/maintainers.html#handling-pull-requests) to understand what may happen after you open a pull request.
## Style Guide
Our linter will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running `npm run lint`.
However, there are still some styles that the linter cannot pick up.
### Code Conventions
#### General
* **Most important: Look around.** Match the style you see used in the rest of the project. This includes formatting, naming things in code, naming things in documentation.
* Add trailing commas,
* 2 spaces for indentation (no tabs)
* "Attractive"
#### JavaScript
* Use semicolons;
* ES6 standards
* Prefer `'` over `"`
* Do not use the optional parameters of `setTimeout` and `setInterval`
* 80 character line length
#### JSX
* Prefer `"` over `'` for string literal props
* When wrapping opening tags over multiple lines, place one prop per line
* `{}` of props should hug their values (no spaces)
* Place the closing `>` of opening tags on the same line as the last prop
* Place the closing `/>` of self-closing tags on their own line and left-align them with the opening `<`
#### Objective-C
* Space after `@property` declarations
* Brackets on *every* `if`, on the *same* line
* `- method`, `@interface`, and `@implementation` brackets on the following line
* *Try* to keep it around 80 characters line length (sometimes it's just not possible...)
* `*` operator goes with the variable name (e.g. `NSObject *variableName;`)
#### Java
* If a method call spans multiple lines closing bracket is on the same line as the last argument.
* If a method header doesn't fit on one line each argument goes on a separate line.
* 100 character line length
### Documentation
* Do not wrap lines at 80 characters - configure your editor to soft-wrap when editing documentation.
## License
By contributing to React Native, you agree that your contributions will be licensed under its BSD license.

View File

@ -1,238 +0,0 @@
---
id: debugging
title: Debugging
layout: docs
category: Guides
permalink: docs/debugging.html
next: performance
previous: timers
---
## Enabling Keyboard Shortcuts
React Native supports a few keyboard shortcuts in the iOS Simulator. They are described below. To enable them, open the Hardware menu, select Keyboard, and make sure that "Connect Hardware Keyboard" is checked.
## Accessing the In-App Developer Menu
You can access the developer menu by shaking your device or by selecting "Shake Gesture" inside the Hardware menu in the iOS Simulator. You can also use the `⌘D` keyboard shortcut when your app is running in the iOS Simulator, or `⌘M` when running in an Android emulator. Alternatively for Android, you can run the command `adb shell input keyevent 82` to open the dev menu (82 being the Menu key code).
![](img/DeveloperMenu.png)
> The Developer Menu is disabled in release (production) builds.
## Reloading JavaScript
Instead of recompiling your app every time you make a change, you can reload your app's JavaScript code instantly. To do so, select "Reload" from the Developer Menu. You can also press `⌘R` in the iOS Simulator, or tap `R` twice on Android emulators.
### Automatic reloading
You can speed up your development times by having your app reload automatically any time your code changes. Automatic reloading can be enabled by selecting "Enable Live Reload" from the Developer Menu.
You may even go a step further and keep your app running as new versions of your files are injected into the JavaScript bundle automatically by enabling [Hot Reloading](https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html) from the Developer Menu. This will allow you to persist the app's state through reloads.
> There are some instances where hot reloading cannot be implemented perfectly. If you run into any issues, use a full reload to reset your app.
You will need to rebuild your app for changes to take effect in certain situations:
* You have added new resources to your native app's bundle, such as an image in `Images.xcassets` on iOS or the `res/drawable` folder on Android.
* You have modified native code (Objective-C/Swift on iOS or Java/C++ on Android).
## In-app Errors and Warnings
Errors and warnings are displayed inside your app in development builds.
### Errors
In-app errors are displayed in a full screen alert with a red background inside your app. This screen is known as a RedBox. You can use `console.error()` to manually trigger one.
### Warnings
Warnings will be displayed on screen with a yellow background. These alerts are known as YellowBoxes. Click on the alerts to show more information or to dismiss them.
As with a RedBox, you can use `console.warn()` to trigger a YellowBox.
YellowBoxes can be disabled during development by using `console.disableYellowBox = true;`. Specific warnings can be ignored programmatically by setting an array of prefixes that should be ignored: `console.ignoredYellowBox = ['Warning: ...'];`.
In CI/Xcode, YellowBoxes can also be disabled by setting the `IS_TESTING` environment variable.
> RedBoxes and YellowBoxes are automatically disabled in release (production) builds.
## Chrome Developer Tools
To debug the JavaScript code in Chrome, select "Debug JS Remotely" from the Developer Menu. This will open a new tab at [http://localhost:8081/debugger-ui](http://localhost:8081/debugger-ui).
Select `Tools → Developer Tools` from the Chrome Menu to open the [Developer Tools](https://developer.chrome.com/devtools). You may also access the DevTools using keyboard shortcuts (`⌘⌥I` on macOS, `Ctrl` `Shift` `I` on Windows). You may also want to enable [Pause On Caught Exceptions](http://stackoverflow.com/questions/2233339/javascript-is-there-a-way-to-get-chrome-to-break-on-all-errors/17324511#17324511) for a better debugging experience.
> Note: the React Developer Tools Chrome extension does not work with React Native, but you can use its standalone version instead. Read [this section](docs/debugging.html#react-developer-tools) to learn how.
### Debugging using a custom JavaScript debugger
To use a custom JavaScript debugger in place of Chrome Developer Tools, set the `REACT_DEBUGGER` environment variable to a command that will start your custom debugger. You can then select "Debug JS Remotely" from the Developer Menu to start debugging.
The debugger will receive a list of all project roots, separated by a space. For example, if you set `REACT_DEBUGGER="node /path/to/launchDebugger.js --port 2345 --type ReactNative"`, then the command `node /path/to/launchDebugger.js --port 2345 --type ReactNative /path/to/reactNative/app` will be used to start your debugger.
> Custom debugger commands executed this way should be short-lived processes, and they shouldn't produce more than 200 kilobytes of output.
## React Developer Tools
You can use [the standalone version of React Developer Tools](https://github.com/facebook/react-devtools/tree/master/packages/react-devtools) to debug the React component hierarchy. To use it, install the `react-devtools` package globally:
```
npm install -g react-devtools
```
Now run `react-devtools` from the terminal to launch the standalone DevTools app:
```
react-devtools
```
![React DevTools](img/ReactDevTools.png)
It should connect to your simulator within a few seconds.
> Note: if you prefer to avoid global installations, you can add `react-devtools` as a project dependency. Add the `react-devtools` package to your project using `npm install --save-dev react-devtools`, then add `"react-devtools": "react-devtools"` to the `scripts` section in your `package.json`, and then run `npm run react-devtools` from your project folder to open the DevTools.
### Integration with React Native Inspector
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:
![React Native Inspector](img/Inspector.gif)
However, when `react-devtools` is running, Inspector will enter a special collapsed mode, and instead use the DevTools as primary UI. In this mode, clicking on something in the simulator will bring up the relevant components in the DevTools:
![React DevTools Inspector Integration](img/ReactDevToolsInspector.gif)
You can choose "Hide Inspector" in the same menu to exit this mode.
### Inspecting Component Instances
When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.
First, follow the instructions for debugging in Chrome to open the Chrome console.
Make sure that the dropdown in the top left corner of the Chrome console says `debuggerWorker.js`. **This step is essential.**
Then select a React component in React DevTools. There is a search box at the top that helps you find one by name. As soon as you select it, it will be available as `$r` in the Chrome console, letting you inspect its props, state, and instance properties.
![React DevTools Chrome Console Integration](img/ReactDevToolsDollarR.gif)
## Performance Monitor
You can enable a performance overlay to help you debug performance problems by selecting "Perf Monitor" in the Developer Menu.
<hr style="margin-top:25px; margin-bottom:25px;"/>
# Debugging in Ejected Apps
<div class="banner-crna-ejected" style="margin-top:25px">
<h3>Projects with Native Code Only</h3>
<p>
The remainder of this guide only applies to projects made with <code>react-native init</code>
or to those made with Create React Native App which have since ejected. For
more information about ejecting, please see
the <a href="https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md" target="_blank">guide</a> on
the Create React Native App repository.
</p>
</div>
## Accessing console logs
You can display the console logs for an iOS or Android app by using the following commands in a terminal while the app is running:
```
$ react-native log-ios
$ react-native log-android
```
You may also access these through `Debug → Open System Log...` in the iOS Simulator or by running `adb logcat *:S ReactNative:V ReactNativeJS:V` in a terminal while an Android app is running on a device or emulator.
> If you're using Create React Native App, console logs already appear in the same terminal output as the packager.
## Debugging on a device with Chrome Developer Tools
> If you're using Create React Native App, this is configured for you already.
On iOS devices, open the file [`RCTWebSocketExecutor.m`](https://github.com/facebook/react-native/blob/master/Libraries/WebSocket/RCTWebSocketExecutor.m) and change "localhost" to the IP address of your computer, then select "Debug JS Remotely" from the Developer Menu.
On Android 5.0+ devices connected via USB, you can use the [`adb` command line tool](http://developer.android.com/tools/help/adb.html) to setup port forwarding from the device to your computer:
`adb reverse tcp:8081 tcp:8081`
Alternatively, select "Dev Settings" from the Developer Menu, then update the "Debug server host for device" setting to match the IP address of your computer.
> If you run into any issues, it may be possible that one of your Chrome extensions is interacting in unexpected ways with the debugger. Try disabling all of your extensions and re-enabling them one-by-one until you find the problematic extension.
### Debugging with [Stetho](http://facebook.github.io/stetho/) on Android
Follow this guide to enable Stetho for Debug mode:
1. In `android/app/build.gradle`, add these lines in the `dependencies` section:
```gradle
debugCompile 'com.facebook.stetho:stetho:1.5.0'
debugCompile 'com.facebook.stetho:stetho-okhttp3:1.5.0'
```
> The above will configure Stetho v1.5.0. You can check at http://facebook.github.io/stetho/ if a newer version is available.
2. Create the following Java classes to wrap the Stetho call, one for release and one for debug:
```java
// android/app/src/release/java/com/{yourAppName}/StethoWrapper.java
public class StethoWrapper {
public static void initialize(Context context) {
// NO_OP
}
public static void addInterceptor() {
// NO_OP
}
}
```
```java
// android/app/src/debug/java/com/{yourAppName}/StethoWrapper.java
public class StethoWrapper {
public static void initialize(Context context) {
Stetho.initializeWithDefaults(context);
}
public static void addInterceptor() {
OkHttpClient client = OkHttpClientProvider.getOkHttpClient()
.newBuilder()
.addNetworkInterceptor(new StethoInterceptor())
.build();
OkHttpClientProvider.replaceOkHttpClient(client);
}
}
```
3. Open `android/app/src/main/java/com/{yourAppName}/MainApplication.java` and replace the original `onCreate` function:
```java
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
StethoWrapper.initialize(this);
StethoWrapper.addInterceptor();
}
SoLoader.init(this, /* native exopackage */ false);
}
```
4. Open the project in Android Studio and resolve any dependency issues. The IDE should guide you through this steps after hovering your pointer over the red lines.
5. Run `react-native run-android`.
6. In a new Chrome tab, open: `chrome://inspect`, then click on the 'Inspect device' item next to "Powered by Stetho".
## Debugging native code
When working with native code, such as when writing native modules, you can launch the app from Android Studio or Xcode and take advantage of the native debugging features (setting up breakpoints, etc.) as you would in case of building a standard native app.

View File

@ -1,212 +0,0 @@
---
id: images
title: Images
layout: docs
category: Guides
permalink: docs/images.html
next: animations
previous: navigation
---
## Static Image Resources
React Native provides a unified way of managing images and other media assets in your iOS and Android apps. To add a static image to your app, place it somewhere in your source code tree and reference it like this:
```javascript
<Image source={require('./my-icon.png')} />
```
The image name is resolved the same way JS modules are resolved. In the example above, the packager will look for `my-icon.png` in the same folder as the component that requires it. Also, if you have `my-icon.ios.png` and `my-icon.android.png`, the packager will pick the correct file for the platform.
You can also use the `@2x` and `@3x` suffixes to provide images for different screen densities. If you have the following file structure:
```
.
├── button.js
└── img
├── check@2x.png
└── check@3x.png
```
...and `button.js` code contains:
```javascript
<Image source={require('./img/check.png')} />
```
...the packager will bundle and serve the image corresponding to device's screen density. For example, `check@2x.png`, will be used on an iPhone 7, while`check@3x.png` will be used on an iPhone 7 Plus or a Nexus 5. If there is no image matching the screen density, the closest best option will be selected.
On Windows, you might need to restart the packager if you add new images to your project.
Here are some benefits that you get:
1. Same system on iOS and Android.
2. Images live in the same folder as your JavaScript code. Components are self-contained.
3. No global namespace, i.e. you don't have to worry about name collisions.
4. Only the images that are actually used will be packaged into your app.
5. Adding and changing images doesn't require app recompilation, just refresh the simulator as you normally do.
6. The packager knows the image dimensions, no need to duplicate it in the code.
7. Images can be distributed via [npm](https://www.npmjs.com/) packages.
In order for this to work, the image name in `require` has to be known statically.
```javascript
// GOOD
<Image source={require('./my-icon.png')} />
// BAD
var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive';
<Image source={require('./' + icon + '.png')} />
// GOOD
var icon = this.props.active ? require('./my-icon-active.png') : require('./my-icon-inactive.png');
<Image source={icon} />
```
Note that image sources required this way include size (width, height) info for the Image. If you need to scale the image dynamically (i.e. via flex), you may need to manually set `{ width: undefined, height: undefined }` on the style attribute.
## Static Non-Image Resources
The `require` syntax described above can be used to statically include audio, video or document files in your project as well. Most common file types are supported including `.mp3`, `.wav`, `.mp4`, `.mov`, `.html` and `.pdf`. See [packager defaults](https://github.com/facebook/metro/blob/master/packages/metro/src/defaults.js#L13-L18) for the full list.
You can add support for other types by creating a packager config file (see the [packager config file](https://github.com/facebook/react-native/blob/master/local-cli/util/Config.js#L34-L39) for the full list of configuration options).
A caveat is that videos must use absolute positioning instead of `flexGrow`, since size info is not currently passed for non-image assets. This limitation doesn't occur for videos that are linked directly into Xcode or the Assets folder for Android.
## Images From Hybrid App's Resources
If you are building a hybrid app (some UIs in React Native, some UIs in platform code) you can still use images that are already bundled into the app.
For images included via Xcode asset catalogs or in the Android drawable folder, use the image name without the extension:
```javascript
<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />
```
For images in the Android assets folder, use the `asset:/` scheme:
```javascript
<Image source={{uri: 'asset:/app_icon.png'}} style={{width: 40, height: 40}} />
```
These approaches provide no safety checks. It's up to you to guarantee that those images are available in the application. Also you have to specify image dimensions manually.
## Network Images
Many of the images you will display in your app will not be available at compile time, or you will want to load some dynamically to keep the binary size down. Unlike with static resources, *you will need to manually specify the dimensions of your image*. It's highly recommended that you use https as well in order to satisfy [App Transport Security](docs/running-on-device.html#app-transport-security) requirements on iOS.
```javascript
// GOOD
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
style={{width: 400, height: 400}} />
// BAD
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}} />
```
### Network Requests for Images
If you would like to set such things as the HTTP-Verb, Headers or a Body along with the image request, you may do this by defining these properties on the source object:
```javascript
<Image source={{
uri: 'https://facebook.github.io/react/logo-og.png',
method: 'POST',
headers: {
Pragma: 'no-cache'
},
body: 'Your Body goes here'
}}
style={{width: 400, height: 400}} />
```
## Uri Data Images
Sometimes, you might be getting encoded image data from a REST API call. You can use the `'data:'` uri scheme to use these images. Same as for network resources, *you will need to manually specify the dimensions of your image*.
> This is recommended for very small and dynamic images only, like icons in a list from a DB.
```javascript
// include at least width and height!
<Image style={{width: 51, height: 51, resizeMode: Image.resizeMode.contain}} source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}/>
```
### Cache Control (iOS Only)
In some cases you might only want to display an image if it is already in the local cache, i.e. a low resolution placeholder until a higher resolution is available. In other cases you do not care if the image is outdated and are willing to display an outdated image to save bandwidth. The `cache` source property gives you control over how the network layer interacts with the cache.
* `default`: Use the native platforms default strategy.
* `reload`: The data for the URL will be loaded from the originating source.
No existing cache data should be used to satisfy a URL load request.
* `force-cache`: The existing cached data will be used to satisfy the request,
regardless of its age or expiration date. If there is no existing data in the cache
corresponding the request, the data is loaded from the originating source.
* `only-if-cached`: The existing cache data will be used to satisfy a request, regardless of
its age or expiration date. If there is no existing data in the cache corresponding
to a URL load request, no attempt is made to load the data from the originating source,
and the load is considered to have failed.
```javascript
<Image source={{uri: 'https://facebook.github.io/react/logo-og.png', cache: 'only-if-cached'}}
style={{width: 400, height: 400}} />
```
## Local Filesystem Images
See [CameraRoll](docs/cameraroll.html) for an example of
using local resources that are outside of `Images.xcassets`.
### Best Camera Roll Image
iOS saves multiple sizes for the same image in your Camera Roll, it is very important to pick the one that's as close as possible for performance reasons. You wouldn't want to use the full quality 3264x2448 image as source when displaying a 200x200 thumbnail. If there's an exact match, React Native will pick it, otherwise it's going to use the first one that's at least 50% bigger in order to avoid blur when resizing from a close size. All of this is done by default so you don't have to worry about writing the tedious (and error prone) code to do it yourself.
## Why Not Automatically Size Everything?
*In the browser* if you don't give a size to an image, the browser is going to render a 0x0 element, download the image, and then render the image based with the correct size. The big issue with this behavior is that your UI is going to jump all around as images load, this makes for a very bad user experience.
*In React Native* this behavior is intentionally not implemented. It is more work for the developer to know the dimensions (or aspect ratio) of the remote image in advance, but we believe that it leads to a better user experience. Static images loaded from the app bundle via the `require('./my-icon.png')` syntax *can be automatically sized* because their dimensions are available immediately at the time of mounting.
For example, the result of `require('./my-icon.png')` might be:
```javascript
{"__packager_asset":true,"uri":"my-icon.png","width":591,"height":573}
```
## Source as an object
In React Native, one interesting decision is that the `src` attribute is named `source` and doesn't take a string but an object with a `uri` attribute.
```javascript
<Image source={{uri: 'something.jpg'}} />
```
On the infrastructure side, the reason is that it allows us to attach metadata to this object. For example if you are using `require('./my-icon.png')`, then we add information about its actual location and size (don't rely on this fact, it might change in the future!). This is also future proofing, for example we may want to support sprites at some point, instead of outputting `{uri: ...}`, we can output `{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}` and transparently support spriting on all the existing call sites.
On the user side, this lets you annotate the object with useful attributes such as the dimension of the image in order to compute the size it's going to be displayed in. Feel free to use it as your data structure to store more information about your image.
## Background Image via Nesting
A common feature request from developers familiar with the web is `background-image`. To handle this use case, you can use the `<ImageBackground>` component, which has the same props as `<Image>`, and add whatever children to it you would like to layer on top of it.
You might not want to use `<ImageBackground>` in some cases, since the implementation is very simple. Refer to `<ImageBackground>`'s [source code](https://github.com/facebook/react-native/blob/master/Libraries/Image/ImageBackground.js) for more insight, and create your own custom component when needed.
```javascript
return (
<ImageBackground source={...}>
<Text>Inside</Text>
</ImageBackground>
);
```
## iOS Border Radius Styles
Please note that the following corner specific, border radius style properties are currently ignored by iOS's image component:
* `borderTopLeftRadius`
* `borderTopRightRadius`
* `borderBottomLeftRadius`
* `borderBottomRightRadius`
## Off-thread Decoding
Image decoding can take more than a frame-worth of time. This is one of the major sources of frame drops on the web because decoding is done in the main thread. In React Native, image decoding is done in a different thread. In practice, you already need to handle the case when the image is not downloaded yet, so displaying the placeholder for a few more frames while it is decoding does not require any code change.

View File

@ -1,323 +0,0 @@
---
id: maintainers
title: What to Expect from Maintainers
layout: docs
category: Contributing
permalink: docs/maintainers.html
next: testing
previous: contributing
---
So you have read through the [contributor's guide](docs/contributing.html) and you're getting ready to send your first pull request. Perhaps you've found an issue in React Native and want to work with the maintainers to land a fix. Here's what you can expect to happen when you open an issue or send a pull request.
> The following is adapted from the excellent [Open Source Guide](https://opensource.guide/) from GitHub and reflects how the maintainers of React Native are encouraged to handle your contributions.
## Handling Issues
We see dozens of new issues being created every day. In order to help maintainers focus on what is actionable, maintainers ask contributors to do a bit of work prior to opening a new issue:
* New issues should follow the [Issue Template](https://github.com/facebook/react-native/blob/master/.github/ISSUE_TEMPLATE.md).
* Issues should provide clear, easy to follow steps alongside sample code to reproduce the issue. Ideally, provide a [Snack](http://snack.expo.io/).
Issues that do not meet the above criteria can be closed immediately, with a link to the [contributor's guide](docs/contributing.html).
### New issue runbook
You have gathered all the information required to open a new issue, and you are confident it meets the [contributor guidelines](docs/contributing.html). Once you post an issue, this is what our maintainers will consider when deciding how to move forward:
* **Is this issue a feature request?**
Some features may not be a good fit for the core React Native library. This is usually the case for **new modules* that Facebook does not use in production. In this case, a maintainer will explain that this should be released to npm as a separate module, allowing users to easily pull in the module in their projects.
Even if the feature does belong in the core library, adding it means maintaining it. A maintainer will encourage you to submit a pull request or otherwise post your request to [Canny](https://react-native.canny.io/feature-requests) by issuing the `@facebook-github-bot feature` command, closing the issue.
An exception can be made for proposals and long-running discussions, though these should be rare. If you have been contributing to the project long enough, you will probably already have access to the [React Native Core Contributors](https://www.facebook.com/groups/reactnativeoss/) Facebook Group, where this sort of discussion is usually held.
* **Is this issue a request for help?**
Questions should absolutely be asked on Stack Overflow rather than GitHub. Maintainers may encourage you to ask on Stack Overflow by issuing the `@facebook-github-bot stack-overflow` command, closing the issue.
Feel free to also answer some [questions on Stack Overflow](stackoverflow.com/questions/tagged/react-native), you'll get rep!
* **Was the [Issue Template](https://github.com/facebook/react-native/blob/master/.github/ISSUE_TEMPLATE.md) used to fill out the issue? Did the author answer Yes to both questions at the top?**
If not, the maintainer will ask you to provide more information by issuing the `@facebook-github-bot no-template` command, closing the issue.
* **Is the issue a duplicate of an existing, open issue?**
A maintainer will use the `@facebook-github-bot duplicate #123` command to mark the issue as a duplicate of issue #123, closing it.
* **Does the issue include a Snack or list of steps to reproduce the issue?**
Issues should be relatively easy to reproduce. Sometimes the issue affects a particular app but a minimal repro is not provided, perhaps a crash is seen in the logs and the author is not sure where its coming from, maybe the issue is sporadic.
As it happens, if a maintainer cannot easily reproduce the issue, one cannot reasonably expect them to be able to work on a fix. These issues can be closed by issuing the `@facebook-github-bot needs-repro` command.
Exceptions can be made if multiple people appear to be affected by the issue, especially right after a new React Native release is cut.
* **Is the issue for an old release of React Native?**
If so, expect to be asked if the issue can be reproduced in the latest release candidate.
* **Can the issue be reliably reproduced?**
If not, a maintainer may issue the `@facebook-github-bot cannot-repro` command, closing the issue.
* **Does the issue need more information?**
Some issues need additional information in order to reproduce them. Maintainers should explain what additional information is needed, using the `@facebook-github-bot label Needs more information` command to label the issue as such.
Issues with the 'Needs more information' label that have been open for more than a week without a response from the author can be closed using `@facebook-github-bot no-reply`.
* **Has the issue been resolved already in the comments?**
Sometimes another contributor has already provided a solution in the comments. Maintainers may issue the `@facebook-github-bot answered` command to close the issue.
> **Reopening a closed issue:** Sometimes it's necessary to reopen an issue. For example, if an issue was closed waiting for the author, then the author replied and it turns out this is indeed a bug, you can comment `@facebook-github-bot reopen` to reopen it.
Valid bug reports with good repro steps are some of the best issues! Maintainers should thank the author for finding the issue, then explain that React Native is a community project and **ask them if they would be up for sending a fix**.
### Triaging issues
If a issue is still open after going through all of the checks above, it will move on to the triage stage. A maintainer will then do the following:
1. Add relevant labels. For example, if this is an issue that affects Android, use the `@facebook-github-bot label Android` command.
2. Leave a comment saying the issue has been triaged.
3. Tag the relevant people.
You can generally figure out who may be relevant for a given issue by looking at the [CODEOWNERS](https://github.com/facebook/react-native/blob/master/.github/CODEOWNERS) file.
#### What are all the available commands for the bot?
You can find the full command reference in the [Facebook GitHub Bot](/docs/maintainers.html#facebook-github-bot) section below.
### Stale issues
Issues in the "Needs more information" state may be closed after a week with no followup from the author. Issues that have have had no activity in the last two months may be closed periodically. If your issue gets closed in this manner, it's nothing personal. If you strongly believe that the issue should remain open, just let us know why.
Simply commenting that the issue still exists is not very compelling (it's rare for critical, release blocking issues to have no activity for two months!). In order to make a good case for reopening the issue, you may need to do a bit of work:
* Can the issue be reproduced on the latest release candidate? Post a comment with the version you tested.
* If so, is there any information missing from the bug report? Post a comment with all the information required by the [issue template](https://github.com/facebook/react-native/blob/master/.github/ISSUE_TEMPLATE.md).
* Is there a pull request that addressed this issue? Post a comment with the PR number so we can follow up.
A couple of contributors making a good case may be all that is needed to reopen the issue.
## Handling pull requests
The core team will be monitoring for pull requests. When we get one, we'll run some Facebook-specific integration tests on it first. From here, we'll need to get another person to sign off on the changes and then merge the pull request. For API changes we may need to fix internal uses, which could cause some delay. We'll do our best to provide updates and feedback throughout the process.
### How we prioritize pull requests
We use the [Contributors Chrome extension](https://github.com/hzoo/contributors-on-github) to help us understand who is sending a pull request. Pull requests opened by contributors that have a history of having their PRs merged are more likely to be looked at first. Aside from that, we try to go through pull requests on a chronological order.
### How we review pull requests
Reviewing a PR can sometimes require more time from a maintainer than it took you to write the code. Maintainers need to consider all the ramifications of importing your patch into the codebase. Does it potentially introduce breaking changes? What are the performance considerations of adding a new dependency? Will the docs need to be updated as well? Does this belong in core, or would it be a better fit as a third party package?
Once you open a pull request, this is how you can expect maintainers to review it:
* **Is the pull request missing information?**
A test plan is required! Add the labels 'Needs revision' and 'Needs response from author'. You can then follow up with a response like:
> Hey @author, thanks for sending the pull request.
> Can you please add all the info specified in the [template](https://github.com/facebook/react-native/blob/master/.github/PULL_REQUEST_TEMPLATE.md)? This is necessary for people to be able to understand and review your pull request.
* **Does the code style match the [Style guide](docs/contributing.html#style-guide)?**
If not, link to the style guide and add the label 'Needs revision'.
* **Does the pull request add a completely new feature we don't want to add to the core and maintain?**
Ask the author to release it a separate npm module and close the pull request.
* **Does the pull request do several unrelated things at the same time?**
Ask the author to split it.
* **Is the pull request old and need rebasing?**
Ask the author "Can you rebase please?" and add the label 'Needs response from author'.
* **Is a pull request waiting for a response from author?**
Pull requests like these usually have the label 'Needs response from author'. If there has been no reply in the last 30 days, close it with a response like the following:
> Thanks for making the pull request, but we are closing it due to inactivity. If you want to get your proposed changes merged, please rebase your branch with master and send a new pull request.
* **Is the pull request old and waiting for review?**
Review it or cc someone who might be able to review. Finding the right person to review a pull request can sometimes be tricky. A pull request may simultaneously touch iOS, Java, and JavaScript code. If a pull request has been waiting for review for a while, you can help out by looking at the blame history for the files you're touching. Is there anyone that appears to be knowledgeable in the part of the codebase the PR is touching?
### Closing pull requests
Sometimes a maintainer may decide that a pull request will not be accepted. Maybe the pull request is out of scope for the project, or the idea is good but the implementation is poor. Whatever the reason, when closing a pull request maintainers should keep the conversation friendly:
* **Thank** them for their contribution.
* **Explain why** it doesn't fit into the scope of the project.
* **Link to relevant documentation**, if you have it.
* **Close** the request.
## Defusing situations
Sometimes when a maintainer says no to a pull request or close an issue, a contributor may get upset and criticize your decision. Maintainers will take steps to defuse the situation.
If a contributor becomes hostile or disrespectful, they will be referred to the [Code of Conduct](https://code.facebook.com/codeofconduct). Negative users will be blocked, and inappropriate comments will be deleted.
## Facebook GitHub Bot
The Facebook GitHub Bot allows members of the community to perform administrative actions such as labeling and closing issues.
To have access to the bot, please add your GitHub username to the first line of [IssueCommands.txt](https://github.com/facebook/react-native/blob/master/bots/IssueCommands.txt), in alphabetical order, by submitting a Pull Request.
### Using the Facebook GitHub Bot
The bot can be triggered by adding any of the following commands as a standalone comment on an issue:
<div class="botActions">
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> no-template
</h4>
<div><p>
Use this when more information is needed, especially if the issue does not adhere to the <a href="https://raw.githubusercontent.com/facebook/react-native/master/.github/ISSUE_TEMPLATE.md">issue template</a>. The bot will <strong>close</strong> the issue after adding the "Needs more information" label.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> stack-overflow
</h4>
<div><p>
Mark issues that do not belong in the bug tracker, and redirect to Stack Overflow. The bot will <strong>close</strong> the issue after adding the "For Stack Overflow" label.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> needs-repro
</h4>
<div><p>
Prompts the author to provide a reproducible example or <a href="http://snack.expo.io">Snack</a>. The bot will apply the "Needs more information" label.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> cannot-repro
</h4>
<div><p>
Use this when the issue cannot be reproduced, either because it affects a particular app but no minimal repro was provided, or the issue describes something sporadic that is unlikely to be reproduced by a community member. The bot will <strong>close</strong> the issue.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> duplicate (#[0-9]+)
</h4>
<div><p>
Marks an issue as a duplicate. Requires a issue number to be provided. The bot will <strong>close</strong> the issue.
</p>
<p>
Example: <code>@facebook-github-bot duplicate #42</code>
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> label (.*)
</h4>
<div><p>
Use this command to add a <a href="https://github.com/facebook/react-native/labels">label</a>, such as "iOS" or "Android", to an issue.
</p><p>
Example: <code>@facebook-github-bot label Android</code>
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> feature
</h4>
<div><p>
Use this when an issue describes a feature request, as opposed to a reproducible bug. The bot will point the author to the feature request tracker, add the "Feature Request" label, then <strong>close</strong> the issue.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> expected
</h4>
<div><p>
Use this when an issue describes a type of expected behavior. The bot will <strong>close</strong> the issue.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> answered
</h4>
<div><p>
Use this when an issue appears to be a question that has already been answered by someone on the thread. The bot will <strong>close</strong> the issue.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> close
</h4>
<div><p>
<strong>Closes</strong> an issue without providing a particular explanation.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> reopen
</h4>
<div><p>
<strong>Re-opens</strong> a previously closed issue.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> bugfix
</h4>
<div><p>
Mark issues that describe a reproducible bug and encourage the author to send a pull request. The bot will add the "Help Wanted" label.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> no-reply
</h4>
<div><p>
Use this when an issue requires more information from the author but they have not added a comment in a while. The bot will <strong>close</strong> the issue.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> icebox
</h4>
<div><p>
Use this when an issue has been open for over 30 days with no activity and no community member has volunteered to work on a fix. The bot will <strong>close</strong> the issue after adding the "Icebox" label.
</p></div>
</div>
</div>
Additionally, the following commands can be used on a pull request:
<div class="botActions">
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> cla
</h4>
<div><p>
Remind the author that the CLA needs to be signed.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> shipit
</h4>
<div><p>
Flag the PR for merging. If used by a core contributor, the bot will attempt to import the pull request. In general, core contributors are those who have consistently submitted high quality contributions to the project. Access control for this command is configured internally in Facebook, outside of the IssueCommands.txt file mentioned above.
</p></div>
</div>
<div class="botAction">
<h4 class="botCommand">
<span class="botMentionName">@facebook-github-bot</span> large-pr
</h4>
<div><p>
Flag PRs that change too many files at once. These PRs are extremely unlikely to be reviewed. The bot will leave a helpful message indicating next steps such as splitting the PR. The bot will <strong>close</strong> the PR after adding the "Large PR" label.
</p></div>
</div>
</div>

File diff suppressed because one or more lines are too long

View File

@ -1,146 +0,0 @@
---
id: navigation
title: Navigating Between Screens
layout: docs
category: Guides
permalink: docs/navigation.html
next: images
previous: platform-specific-code
---
Mobile apps are rarely made up of a single screen. Managing the presentation of, and transition between, multiple screens is typically handled by what is known as a navigator.
This guide covers the various navigation components available in React Native.
If you are just getting started with navigation, you will probably want to use [React Navigation](docs/navigation.html#react-navigation). React Navigation provides an easy to use navigation solution, with the ability to present common stack navigation and tabbed navigation patterns on both iOS and Android. As this is a JavaScript implementation, it provides the greatest amount of configurability as well as flexibility when integrating with state management libraries such as [redux](https://reactnavigation.org/docs/guides/redux).
If you're only targeting iOS, you may want to also check out [NavigatorIOS](docs/navigation.html#navigatorios) as a way of providing a native look and feel with minimal configuration, as it provides a wrapper around the native `UINavigationController` class. This component will not work on Android, however.
If you'd like to achieve a native look and feel on both iOS and Android, or you're integrating React Native into an app that already manages navigation natively, the following libraries provide native navigation on both platforms: [native-navigation](http://airbnb.io/native-navigation/), [react-native-navigation](https://github.com/wix/react-native-navigation).
## React Navigation
The community solution to navigation is a standalone library that allows developers to set up the screens of an app with just a few lines of code.
The first step is to install in your project:
```
npm install --save react-navigation
```
Then you can quickly create an app with a home screen and a profile screen:
```
import {
StackNavigator,
} from 'react-navigation';
const App = StackNavigator({
Home: { screen: HomeScreen },
Profile: { screen: ProfileScreen },
});
```
Each screen component can set navigation options such as the header title. It can use action creators on the `navigation` prop to link to other screens:
```
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to Jane's profile"
onPress={() =>
navigate('Profile', { name: 'Jane' })
}
/>
);
}
}
```
React Navigation routers make it easy to override navigation logic or integrate it into redux. Because routers can be nested inside each other, developers can override navigation logic for one area of the app without making widespread changes.
The views in React Navigation use native components and the [`Animated`](docs/animated.html) library to deliver 60fps animations that are run on the native thread. Plus, the animations and gestures can be easily customized.
For a complete intro to React Navigation, follow the [React Navigation Getting Started Guide](https://reactnavigation.org/docs/intro/), or browse other docs such as the [Intro to Navigators](https://reactnavigation.org/docs/navigators/).
## NavigatorIOS
`NavigatorIOS` looks and feels just like [`UINavigationController`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/), because it is actually built on top of it.
![](img/NavigationStack-NavigatorIOS.gif)
```javascript
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: { myProp: 'foo' },
}}
/>
```
Like other navigation systems, `NavigatorIOS` uses routes to represent screens, with some important differences. The actual component that will be rendered can be specified using the `component` key in the route, and any props that should be passed to this component can be specified in `passProps`. A "navigator" object is automatically passed as a prop to the component, allowing you to call `push` and `pop` as needed.
As `NavigatorIOS` leverages native UIKit navigation, it will automatically render a navigation bar with a back button and title.
```javascript
import React from 'react';
import PropTypes from 'prop-types';
import { Button, NavigatorIOS, Text, View } from 'react-native';
export default class NavigatorIOSApp extends React.Component {
render() {
return (
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: {index: 1},
}}
style={{flex: 1}}
/>
)
}
}
class MyScene extends React.Component {
static propTypes = {
route: PropTypes.shape({
title: PropTypes.string.isRequired
}),
navigator: PropTypes.object.isRequired,
}
constructor(props, context) {
super(props, context);
this._onForward = this._onForward.bind(this);
}
_onForward() {
let nextIndex = ++this.props.index;
this.props.navigator.push({
component: MyScene,
title: 'Scene ' + nextIndex,
passProps: {index: nextIndex}
});
}
render() {
return (
<View>
<Text>Current Scene: { this.props.title }</Text>
<Button
onPress={this._onForward}
title="Tap me to load the next scene"
/>
</View>
)
}
}
```
Check out the [`NavigatorIOS` reference docs](docs/navigatorios.html) to learn more about this component.

View File

@ -1,614 +0,0 @@
---
id: performance
title: Performance
layout: docs
category: Guides
permalink: docs/performance.html
next: gesture-responder-system
previous: debugging
---
A compelling reason for using React Native instead of WebView-based tools is to achieve 60 frames per second and a native look and feel to your apps.
Where possible, we would like for React Native to do the right thing and help you to focus on your app instead of performance optimization,
but there are areas where we're not quite there yet,
and others where React Native (similar to writing native code directly) cannot possibly determine the best way to optimize for you and so manual intervention will be necessary.
We try our best to deliver buttery-smooth UI performance by default, but sometimes that just isn't possible.
This guide is intended to teach you some basics to help you to [troubleshoot performance issues](docs/performance.html#profiling),
as well as discuss [common sources of problems and their suggested solutions](docs/performance.html#common-sources-of-performance-problems).
## What you need to know about frames
Your grandparents' generation called movies ["moving pictures"](https://www.youtube.com/watch?v=F1i40rnpOsA) for a reason:
realistic motion in video is an illusion created by quickly changing static images at a consistent speed. We refer to each of these images as frames.
The number of frames that is displayed each second has a direct impact on how smooth and ultimately life-like a video (or user interface) seems to be.
iOS devices display 60 frames per second, which gives you and the UI system about 16.67ms to do all of the work needed to generate the static image (frame) that the user will see on the screen for that interval.
If you are unable to do the work necessary to generate that frame within the allotted 16.67ms, then you will "drop a frame" and the UI will appear unresponsive.
Now to confuse the matter a little bit, open up the developer menu in your app and toggle `Show Perf Monitor`.
You will notice that there are two different frame rates.
![](img/PerfUtil.png)
### JS frame rate (JavaScript thread)
For most React Native applications, your business logic will run on the JavaScript thread.
This is where your React application lives, API calls are made, touch events are processed, etc...
Updates to native-backed views are batched and sent over to the native side at the end of each iteration of the event loop,
before the frame deadline (if all goes well).
If the JavaScript thread is unresponsive for a frame, it will be considered a dropped frame.
For example, if you were to call `this.setState` on the root component of a complex application and it resulted in re-rendering computationally expensive component subtrees,
it's conceivable that this might take 200ms and result in 12 frames being dropped.
Any animations controlled by JavaScript would appear to freeze during that time.
If anything takes longer than 100ms, the user will feel it.
This often happens during `Navigator` transitions:
when you push a new route, the JavaScript thread needs to render all of the components necessary for the scene in order to send over the proper commands to the native side to create the backing views.
It's common for the work being done here to take a few frames and cause [jank](http://jankfree.org/) because the transition is controlled by the JavaScript thread.
Sometimes components will do additional work on `componentDidMount`, which might result in a second stutter in the transition.
Another example is responding to touches:
if you are doing work across multiple frames on the JavaScript thread, you might notice a delay in responding to `TouchableOpacity`, for example.
This is because the JavaScript thread is busy and cannot process the raw touch events sent over from the main thread.
As a result, `TouchableOpacity` cannot react to the touch events and command the native view to adjust its opacity.
### UI frame rate (main thread)
Many people have noticed that performance of `NavigatorIOS` is better out of the box than `Navigator`.
The reason for this is that the animations for the transitions are done entirely on the main thread,
and so they are not interrupted by frame drops on the JavaScript thread.
Similarly, you can happily scroll up and down through a `ScrollView` when the JavaScript thread is locked up because the `ScrollView` lives on the main thread.
The scroll events are dispatched to the JS thread, but their receipt is not necessary for the scroll to occur.
## Common sources of performance problems
### Running in development mode (`dev=true`)
JavaScript thread performance suffers greatly when running in dev mode.
This is unavoidable: a lot more work needs to be done at runtime to provide you with good warnings and error messages, such as validating propTypes and various other assertions. Always make sure to test performance in [release builds](docs/running-on-device.html#building-your-app-for-production).
### Using `console.log` statements
When running a bundled app, these statements can cause a big bottleneck in the JavaScript thread.
This includes calls from debugging libraries such as [redux-logger](https://github.com/evgenyrodionov/redux-logger),
so make sure to remove them before bundling.
You can also use this [babel plugin](https://babeljs.io/docs/plugins/transform-remove-console/) that removes all the `console.*` calls. You need to install it first with `npm i babel-plugin-transform-remove-console --save`, and then edit the `.babelrc` file under your project directory like this:
```json
{
"env": {
"production": {
"plugins": ["transform-remove-console"]
}
}
}
```
This will automatically remove all `console.*` calls in the release (production) versions of your project.
### `ListView` initial rendering is too slow or scroll performance is bad for large lists
Use the new [`FlatList`](docs/flatlist.html) or [`SectionList`](docs/sectionlist.html) component instead.
Besides simplifying the API, the new list components also have significant performance enhancements,
the main one being nearly constant memory usage for any number of rows.
If your [`FlatList`](docs/flatlist.html) is rendering slow, be sure that you've implemented
[`getItemLayout`](https://facebook.github.io/react-native/docs/flatlist.html#getitemlayout) to
optimize rendering speed by skipping measurement of the rendered items.
### JS FPS plunges when re-rendering a view that hardly changes
If you are using a ListView, you must provide a `rowHasChanged` function that can reduce a lot of work by quickly determining whether or not a row needs to be re-rendered. If you are using immutable data structures, this would be as simple as a reference equality check.
Similarly, you can implement `shouldComponentUpdate` and indicate the exact conditions under which you would like the component to re-render. If you write pure components (where the return value of the render function is entirely dependent on props and state), you can leverage PureRenderMixin to do this for you. Once again, immutable data structures are useful to keep this fast -- if you have to do a deep comparison of a large list of objects, it may be that re-rendering your entire component would be quicker, and it would certainly require less code.
### Dropping JS thread FPS because of doing a lot of work on the JavaScript thread at the same time
"Slow Navigator transitions" is the most common manifestation of this, but there are other times this can happen. Using InteractionManager can be a good approach, but if the user experience cost is too high to delay work during an animation, then you might want to consider LayoutAnimation.
The Animated API currently calculates each keyframe on-demand on the JavaScript thread unless you [set `useNativeDriver: true`](https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated.html#how-do-i-use-this-in-my-app), while LayoutAnimation leverages Core Animation and is unaffected by JS thread and main thread frame drops.
One case where I have used this is for animating in a modal (sliding down from top and fading in a translucent overlay) while initializing and perhaps receiving responses for several network requests, rendering the contents of the modal, and updating the view where the modal was opened from. See the Animations guide for more information about how to use LayoutAnimation.
Caveats:
- LayoutAnimation only works for fire-and-forget animations ("static" animations) -- if it must be interruptible, you will need to use `Animated`.
### Moving a view on the screen (scrolling, translating, rotating) drops UI thread FPS
This is especially true when you have text with a transparent background positioned on top of an image,
or any other situation where alpha compositing would be required to re-draw the view on each frame.
You will find that enabling `shouldRasterizeIOS` or `renderToHardwareTextureAndroid` can help with this significantly.
Be careful not to overuse this or your memory usage could go through the roof.
Profile your performance and memory usage when using these props.
If you don't plan to move a view anymore, turn this property off.
### Animating the size of an image drops UI thread FPS
On iOS, each time you adjust the width or height of an Image component it is re-cropped and scaled from the original image.
This can be very expensive, especially for large images.
Instead, use the `transform: [{scale}]` style property to animate the size.
An example of when you might do this is when you tap an image and zoom it in to full screen.
### My TouchableX view isn't very responsive
Sometimes, if we do an action in the same frame that we are adjusting the opacity or highlight of a component that is responding to a touch,
we won't see that effect until after the `onPress` function has returned.
If `onPress` does a `setState` that results in a lot of work and a few frames dropped, this may occur.
A solution to this is to wrap any action inside of your `onPress` handler in `requestAnimationFrame`:
```js
handleOnPress() {
// Always use TimerMixin with requestAnimationFrame, setTimeout and
// setInterval
this.requestAnimationFrame(() => {
this.doExpensiveAction();
});
}
```
### Slow navigator transitions
As mentioned above, `Navigator` animations are controlled by the JavaScript thread.
Imagine the "push from right" scene transition:
each frame, the new scene is moved from the right to left,
starting offscreen (let's say at an x-offset of 320) and ultimately settling when the scene sits at an x-offset of 0.
Each frame during this transition, the JavaScript thread needs to send a new x-offset to the main thread.
If the JavaScript thread is locked up, it cannot do this and so no update occurs on that frame and the animation stutters.
One solution to this is to allow for JavaScript-based animations to be offloaded to the main thread.
If we were to do the same thing as in the above example with this approach,
we might calculate a list of all x-offsets for the new scene when we are starting the transition and send them to the main thread to execute in an optimized way.
Now that the JavaScript thread is freed of this responsibility,
it's not a big deal if it drops a few frames while rendering the scene -- you probably won't even notice because you will be too distracted by the pretty transition.
Solving this is one of the main goals behind the new [React Navigation](docs/navigation.html) library.
The views in React Navigation use native components and the [`Animated`](docs/animated.html) library to deliver 60 FPS animations that are run on the native thread.
## Profiling
Use the built-in profiler to get detailed information about work done in the JavaScript thread and main thread side-by-side.
Access it by selecting Perf Monitor from the Debug menu.
For iOS, Instruments is an invaluable tool, and on Android you should learn to use [`systrace`](docs/performance.html#profiling-android-ui-performance-with-systrace).
Another way to profile JavaScript is to use the Chrome profiler while debugging.
This won't give you accurate results as the code is running in Chrome but will give you a general idea of where bottlenecks might be.
But first, [**make sure that Development Mode is OFF!**](docs/performance.html#running-in-development-mode-dev-true) You should see `__DEV__ === false, development-level warning are OFF, performance optimizations are ON` in your application logs.
### Profiling Android UI Performance with `systrace`
Android supports 10k+ different phones and is generalized to support software rendering:
the framework architecture and need to generalize across many hardware targets unfortunately means you get less for free relative to iOS.
But sometimes, there are things you can improve -- and many times it's not native code's fault at all!
The first step for debugging this jank is to answer the fundamental question of where your time is being spent during each 16ms frame.
For that, we'll be using a standard Android profiling tool called `systrace`.
`systrace` is a standard Android marker-based profiling tool (and is installed when you install the Android platform-tools package).
Profiled code blocks are surrounded by start/end markers which are then visualized in a colorful chart format.
Both the Android SDK and React Native framework provide standard markers that you can visualize.
#### 1. Collecting a trace
First, connect a device that exhibits the stuttering you want to investigate to your computer via USB and get it to the point right before the navigation/animation you want to profile.
Run `systrace` as follows:
```
$ <path_to_android_sdk>/platform-tools/systrace/systrace.py --time=10 -o trace.html sched gfx view -a <your_package_name>
```
A quick breakdown of this command:
- `time` is the length of time the trace will be collected in seconds
- `sched`, `gfx`, and `view` are the android SDK tags (collections of markers) we care about: `sched` gives you information about what's running on each core of your phone, `gfx` gives you graphics info such as frame boundaries, and `view` gives you information about measure, layout, and draw passes
- `-a <your_package_name>` enables app-specific markers, specifically the ones built into the React Native framework. `your_package_name` can be found in the `AndroidManifest.xml` of your app and looks like `com.example.app`
Once the trace starts collecting, perform the animation or interaction you care about. At the end of the trace, systrace will give you a link to the trace which you can open in your browser.
#### 2. Reading the trace
After opening the trace in your browser (preferably Chrome), you should see something like this:
![Example](img/SystraceExample.png)
> **HINT**:
> Use the WASD keys to strafe and zoom
If your trace .html file isn't opening correctly, check your browser console for the following:
![ObjectObserveError](img/ObjectObserveError.png)
Since `Object.observe` was deprecated in recent browsers, you may have to open the file from the Google Chrome Tracing tool. You can do so by:
- Opening tab in chrome chrome://tracing
- Selecting load
- Selecting the html file generated from the previous command.
> **Enable VSync highlighting**
>
> Check this checkbox at the top right of the screen to highlight the 16ms frame boundaries:
>
> ![Enable VSync Highlighting](img/SystraceHighlightVSync.png)
>
> You should see zebra stripes as in the screenshot above.
> If you don't, try profiling on a different device: Samsung has been known to have issues displaying vsyncs while the Nexus series is generally pretty reliable.
#### 3. Find your process
Scroll until you see (part of) the name of your package.
In this case, I was profiling `com.facebook.adsmanager`,
which shows up as `book.adsmanager` because of silly thread name limits in the kernel.
On the left side, you'll see a set of threads which correspond to the timeline rows on the right.
There are a few threads we care about for our purposes:
the UI thread (which has your package name or the name UI Thread), `mqt_js`, and `mqt_native_modules`.
If you're running on Android 5+, we also care about the Render Thread.
- **UI Thread.**
This is where standard android measure/layout/draw happens.
The thread name on the right will be your package name (in my case book.adsmanager) or UI Thread.
The events that you see on this thread should look something like this and have to do with `Choreographer`, `traversals`, and `DispatchUI`:
![UI Thread Example](img/SystraceUIThreadExample.png)
- **JS Thread.**
This is where JavaScript is executed.
The thread name will be either `mqt_js` or `<...>` depending on how cooperative the kernel on your device is being.
To identify it if it doesn't have a name, look for things like `JSCall`, `Bridge.executeJSCall`, etc:
![JS Thread Example](img/SystraceJSThreadExample.png)
- **Native Modules Thread.**
This is where native module calls (e.g. the `UIManager`) are executed.
The thread name will be either `mqt_native_modules` or `<...>`.
To identify it in the latter case, look for things like `NativeCall`, `callJavaModuleMethod`, and `onBatchComplete`:
![Native Modules Thread Example](img/SystraceNativeModulesThreadExample.png)
- **Bonus: Render Thread.**
If you're using Android L (5.0) and up, you will also have a render thread in your application.
This thread generates the actual OpenGL commands used to draw your UI.
The thread name will be either `RenderThread` or `<...>`.
To identify it in the latter case, look for things like `DrawFrame` and `queueBuffer`:
![Render Thread Example](img/SystraceRenderThreadExample.png)
#### Identifying a culprit
A smooth animation should look something like the following:
![Smooth Animation](img/SystraceWellBehaved.png)
Each change in color is a frame -- remember that in order to display a frame,
all our UI work needs to be done by the end of that 16ms period.
Notice that no thread is working close to the frame boundary.
An application rendering like this is rendering at 60 FPS.
If you noticed chop, however, you might see something like this:
![Choppy Animation from JS](img/SystraceBadJS.png)
Notice that the JS thread is executing basically all the time, and across frame boundaries!
This app is not rendering at 60 FPS.
In this case, **the problem lies in JS**.
You might also see something like this:
![Choppy Animation from UI](img/SystraceBadUI.png)
In this case, the UI and render threads are the ones that have work crossing frame boundaries.
The UI that we're trying to render on each frame is requiring too much work to be done.
In this case, **the problem lies in the native views being rendered**.
At this point, you'll have some very helpful information to inform your next steps.
#### Resolving JavaScript issues
If you identified a JS problem,
look for clues in the specific JS that you're executing.
In the scenario above, we see `RCTEventEmitter` being called multiple times per frame.
Here's a zoom-in of the JS thread from the trace above:
![Too much JS](img/SystraceBadJS2.png)
This doesn't seem right.
Why is it being called so often?
Are they actually different events?
The answers to these questions will probably depend on your product code.
And many times, you'll want to look into [shouldComponentUpdate](https://facebook.github.io/react/docs/component-specs.html#updating-shouldcomponentupdate).
#### Resolving native UI Issues
If you identified a native UI problem, there are usually two scenarios:
1. the UI you're trying to draw each frame involves too much work on the GPU, or
2. You're constructing new UI during the animation/interaction (e.g. loading in new content during a scroll).
##### Too much GPU work
In the first scenario, you'll see a trace that has the UI thread and/or Render Thread looking like this:
![Overloaded GPU](img/SystraceBadUI.png)
Notice the long amount of time spent in `DrawFrame` that crosses frame boundaries. This is time spent waiting for the GPU to drain its command buffer from the previous frame.
To mitigate this, you should:
- investigate using `renderToHardwareTextureAndroid` for complex, static content that is being animated/transformed (e.g. the `Navigator` slide/alpha animations)
- make sure that you are **not** using `needsOffscreenAlphaCompositing`, which is disabled by default, as it greatly increases the per-frame load on the GPU in most cases.
If these don't help and you want to dig deeper into what the GPU is actually doing, you can check out [Tracer for OpenGL ES](http://developer.android.com/tools/help/gltracer.html).
##### Creating new views on the UI thread
In the second scenario, you'll see something more like this:
![Creating Views](img/SystraceBadCreateUI.png)
Notice that first the JS thread thinks for a bit, then you see some work done on the native modules thread, followed by an expensive traversal on the UI thread.
There isn't an easy way to mitigate this unless you're able to postpone creating new UI until after the interaction, or you are able to simplify the UI you're creating. The react native team is working on a infrastructure level solution for this that will allow new UI to be created and configured off the main thread, allowing the interaction to continue smoothly.
## Unbundling + inline requires
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).
### Loading JavaScript
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.
### Inline Requires
Inline requires delay the requiring of a module or file until that file is actually needed. A basic example would look like this:
#### VeryExpensive.js
```
import React, { Component } from 'react';
import { Text } from 'react-native';
// ... import some very expensive modules
// You may want to log at the file level to verify when this is happening
console.log('VeryExpensive component loaded');
export default class VeryExpensive extends Component {
// lots and lots of code
render() {
return <Text>Very Expensive Component</Text>;
}
}
```
#### Optimized.js
```
import React, { Component } from 'react';
import { TouchableOpacity, View, Text } from 'react-native';
let VeryExpensive = null;
export default class Optimized extends Component {
state = { needsExpensive: false };
didPress = () => {
if (VeryExpensive == null) {
VeryExpensive = require('./VeryExpensive').default;
}
this.setState(() => ({
needsExpensive: true,
}));
};
render() {
return (
<View style={{ marginTop: 20 }}>
<TouchableOpacity onPress={this.didPress}>
<Text>Load</Text>
</TouchableOpacity>
{this.state.needsExpensive ? <VeryExpensive /> : null}
</View>
);
}
}
```
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.
### Enable Unbundling
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.
Enable unbundling in Xcode by editing the build phase "Bundle React Native code and images". Before `../node_modules/react-native/packager/react-native-xcode.sh` add `export BUNDLE_COMMAND="unbundle"`:
```
export BUNDLE_COMMAND="unbundle"
export NODE_BINARY=node
../node_modules/react-native/packager/react-native-xcode.sh
```
On Android enable unbundling by editing your android/app/build.gradle file. Before the line `apply from: "../../node_modules/react-native/react.gradle"` add or amend the `project.ext.react` block:
```
project.ext.react = [
bundleCommand: "unbundle",
]
```
Use the following lines on Android if you want to use a single indexed file:
```
project.ext.react = [
bundleCommand: "unbundle",
extraPackagerArgs: ["--indexed-unbundle"]
]
```
### Configure Preloading and Inline Requires
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.
### Adding a packager config file
Create a folder in your project called packager, and create a single file named config.js. Add the following:
```
const config = {
getTransformOptions: () => {
return {
transform: { inlineRequires: true },
};
},
};
module.exports = config;
```
In Xcode, in the build phase, include `export BUNDLE_CONFIG="packager/config.js"`.
```
export BUNDLE_COMMAND="unbundle"
export BUNDLE_CONFIG="packager/config.js"
export NODE_BINARY=node
../node_modules/react-native/packager/react-native-xcode.sh
```
Edit your android/app/build.gradle file to include `bundleConfig: "packager/config.js",`.
```
project.ext.react = [
bundleCommand: "unbundle",
bundleConfig: "packager/config.js"
]
```
Finally, you can update "start" under "scripts" on your package.json to use the config:
`"start": "node node_modules/react-native/local-cli/cli.js start --config ../../../../packager/config.js",`
Start your package server with `npm start`. Note that when the dev packager is automatically launched via xcode and `react-native run-android`, etc, it does not use `npm start`, so it won't use the config.
### Investigating the Loaded Modules
In your root file (index.(ios|android).js) you can add the following after the initial imports:
```
const modules = require.getModules();
const moduleIds = Object.keys(modules);
const loadedModuleNames = moduleIds
.filter(moduleId => modules[moduleId].isInitialized)
.map(moduleId => modules[moduleId].verboseName);
const waitingModuleNames = moduleIds
.filter(moduleId => !modules[moduleId].isInitialized)
.map(moduleId => modules[moduleId].verboseName);
// make sure that the modules you expect to be waiting are actually waiting
console.log(
'loaded:',
loadedModuleNames.length,
'waiting:',
waitingModuleNames.length
);
// grab this text blob, and put it in a file named packager/moduleNames.js
console.log(`module.exports = ${JSON.stringify(loadedModuleNames.sort())};`);
```
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.
```
require.Systrace.beginEvent = (message) => {
if(message.includes(problematicModule)) {
throw new Error();
}
}
```
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.
### Transforming to Module Paths
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 `packager/generateModulePaths.js` to your project with the following:
```
// @flow
/* eslint-disable no-console */
const execSync = require('child_process').execSync;
const fs = require('fs');
const moduleNames = require('./moduleNames');
const pjson = require('../package.json');
const localPrefix = `${pjson.name}/`;
const modulePaths = moduleNames.map(moduleName => {
if (moduleName.startsWith(localPrefix)) {
return `./${moduleName.substring(localPrefix.length)}`;
}
if (moduleName.endsWith('.js')) {
return `./node_modules/${moduleName}`;
}
try {
const result = execSync(
`grep "@providesModule ${moduleName}" $(find . -name ${moduleName}\\\\.js) -l`
)
.toString()
.trim()
.split('\n')[0];
if (result != null) {
return result;
}
} catch (e) {
return null;
}
return null;
});
const paths = modulePaths
.filter(path => path != null)
.map(path => `'${path}'`)
.join(',\n');
const fileData = `module.exports = [${paths}];`;
fs.writeFile('./packager/modulePaths.js', fileData, err => {
if (err) {
console.log(err);
}
console.log('Done');
});
```
You can run via `node packager/modulePaths.js`.
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 `packager/modulePaths.js`. 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.
### Updating the config.js
Returning to packager/config.js we should update it to use our newly generated modulePaths.js file.
```
const modulePaths = require('./modulePaths');
const resolve = require('path').resolve;
const fs = require('fs');
const config = {
getTransformOptions: () => {
const moduleMap = {};
modulePaths.forEach(path => {
if (fs.existsSync(path)) {
moduleMap[resolve(path)] = true;
}
});
return {
preloadedModules: moduleMap,
transform: { inlineRequires: { blacklist: moduleMap } },
};
},
};
module.exports = config;
```
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.
### Test and Measure Improvements
You should now be ready to build your app using unbundling and inline requires. Make sure you measure the before and after startup times.

View File

@ -1,75 +0,0 @@
---
id: props
title: Props
layout: docs
category: The Basics
permalink: docs/props.html
next: state
previous: tutorial
---
Most components can be customized when they are created, with different parameters. These creation parameters are called `props`.
For example, one basic React Native component is the `Image`. When you
create an image, you can use a prop named `source` to control what image it shows.
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, Image } from 'react-native';
export default class Bananas extends Component {
render() {
let pic = {
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};
return (
<Image source={pic} style={{width: 193, height: 110}}/>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => Bananas);
```
Notice that `{pic}` is surrounded by braces, to embed the variable `pic` into JSX. You can put any JavaScript expression inside braces in JSX.
Your own components can also use `props`. This lets you make a single component
that is used in many different places in your app, with slightly different
properties in each place. Just refer to `this.props` in your `render` function. Here's an example:
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
class Greeting extends Component {
render() {
return (
<Text>Hello {this.props.name}!</Text>
);
}
}
export default class LotsOfGreetings extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Greeting name='Rexxar' />
<Greeting name='Jaina' />
<Greeting name='Valeera' />
</View>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => LotsOfGreetings);
```
Using `name` as a prop lets us customize the `Greeting` component, so we can reuse that component for each of our greetings. This example also uses the `Greeting` component in JSX, just like the built-in components. The power to do this is what makes React so cool - if you find yourself wishing that you had a different set of UI primitives to work with, you just invent new ones.
The other new thing going on here is the [`View`](docs/view.html) component. A [`View`](docs/view.html) is useful
as a container for other components, to help control style and layout.
With `props` and the basic [`Text`](docs/text.html), [`Image`](docs/image.html), and [`View`](docs/view.html) components, you can
build a wide variety of static screens. To learn how to make your app change over time, you need to [learn about State](docs/state.html).

View File

@ -1,64 +0,0 @@
---
id: state
title: State
layout: docs
category: The Basics
permalink: docs/state.html
next: style
previous: props
---
There are two types of data that control a component: `props` and `state`. `props` are set by the parent and they are fixed throughout the lifetime of a component. For data that is going to change, we have to use `state`.
In general, you should initialize `state` in the constructor, and then call `setState` when you want to change it.
For example, let's say we want to make text that blinks all the time. The text itself gets set once when the blinking component gets created, so the text itself is a `prop`. The "whether the text is currently on or off" changes over time, so that should be kept in `state`.
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
class Blink extends Component {
constructor(props) {
super(props);
this.state = {showText: true};
// Toggle the state every second
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
}, 1000);
}
render() {
let display = this.state.showText ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
export default class BlinkApp extends Component {
render() {
return (
<View>
<Blink text='I love to blink' />
<Blink text='Yes blinking is so great' />
<Blink text='Why did they ever take this out of HTML' />
<Blink text='Look at me look at me look at me' />
</View>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => BlinkApp);
```
In a real application, you probably won't be setting state with a timer. You might set state when you have new data arrive from the server, or from user input. You can also use a state container like [Redux](http://redux.js.org/index.html) to control your data flow. In that case you would use Redux to modify your state rather than calling `setState` directly.
When setState is called, BlinkApp will re-render its Component. By calling setState within the Timer, the component will re-render every time the Timer ticks.
State works the same way as it does in React, so for more details on handling state, you can look at the [React.Component API](https://facebook.github.io/react/docs/component-api.html).
At this point, you might be annoyed that most of our examples so far use boring default black text. To make things more beautiful, you will have to [learn about Style](docs/style.html).

View File

@ -1,54 +0,0 @@
---
id: style
title: Style
layout: docs
category: The Basics
permalink: docs/style.html
next: height-and-width
previous: state
---
With React Native, you don't use a special language or syntax for defining styles. You just style your application using JavaScript. All of the core components accept a prop named `style`. The style names and [values](docs/colors.html) usually match how CSS works on the web, except names are written using camel casing, e.g `backgroundColor` rather than `background-color`.
The `style` prop can be a plain old JavaScript object. That's the simplest and what we usually use for example code. You can also pass an array of styles - the last style in the array has precedence, so you can use this to inherit styles.
As a component grows in complexity, it is often cleaner to use `StyleSheet.create` to define several styles in one place. Here's an example:
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View } from 'react-native';
export default class LotsOfStyles extends Component {
render() {
return (
<View>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
);
}
}
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => LotsOfStyles);
```
One common pattern is to make your component accept a `style` prop which in
turn is used to style subcomponents. You can use this to make styles "cascade" the way they do in CSS.
There are a lot more ways to customize text style. Check out the [Text component reference](docs/text.html) for a complete list.
Now you can make your text beautiful. The next step in becoming a style master is to [learn how to control component size](docs/height-and-width.html).

View File

@ -1,139 +0,0 @@
---
id: testing
title: Testing your Changes
layout: docs
category: Contributing
permalink: docs/testing.html
next: understanding-cli
previous: maintainers
---
This document is about testing your changes to React Native as a [contributor](docs/contributing.html). If you're interested in testing a React Native app, check out the [React Native Tutorial](http://facebook.github.io/jest/docs/tutorial-react-native.html) on the Jest website.
The React Native repo has several tests you can run to verify you haven't caused a regression with your PR. These tests are run using [Circle](https://circleci.com/gh/facebook/react-native), a continuous integration system. Circle will automatically annotate pull requests with the test results.
Whenever you are fixing a bug or adding new functionality to React Native, you should add a test that covers it. Depending on the change you're making, there are different types of tests that may be appropriate.
- [JavaScript](docs/testing.html#javascript)
- [Android](docs/testing.html#android)
- [iOS](docs/testing.html#ios)
- [Apple TV](docs/testing.html#apple-tv)
- [End-to-end tests](docs/testing.html#end-to-end-tests)
- [Website](docs/testing.html#website)
## JavaScript
### Jest
Jest tests are JavaScript-only tests run on the command line with node. You can run the existing React Native jest tests with:
$ cd react-native
$ npm test
It's a good idea to add a Jest test when you are working on a change that only modifies JavaScript code.
The tests themselves live in the `__tests__` directories of the files they test. See [`TouchableHighlight-test.js`](https://github.com/facebook/react-native/blob/master/Libraries/Components/Touchable/__tests__/TouchableHighlight-test.js) for a basic example.
### Flow
You should also make sure your code passes [Flow](https://flowtype.org/) tests. These can be run using:
$ cd react-native
$ npm run flow
## Android
### Unit Tests
The Android unit tests do not run in an emulator. They just use a normal Java installation. The default macOS Java install is insufficient, you may need to install [Java 8 (JDK8)](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html). You can type `javac -version` in a terminal to see what version you have:
```
$ javac -version
javac 1.8.0_111
```
The version string `1.8.x_xxx` corresponds to JDK 8.
You also need to install the [Buck build tool](https://buckbuild.com/setup/install.html).
To run the Android unit tests:
$ cd react-native
$ ./scripts/run-android-local-unit-tests.sh
It's a good idea to add an Android unit test whenever you are working on code that can be tested by Java code alone. The Android unit tests live under [`ReactAndroid/src/tests`](https://github.com/facebook/react-native/tree/master/ReactAndroid/src/test/java/com/facebook/react), so you can browse through that directory for good examples of tests.
### Integration Tests
To run the integration tests, you need to install the Android NDK. See [Prerequisites](docs/android-building-from-source.html#prerequisites).
You also need to install the [Buck build tool](https://buckbuild.com/setup/install.html).
We recommend running the Android integration tests in an emulator, although you can also use a real Android device. It's a good idea to keep the emulator running with a visible window. That way if your tests stall, you can look at the emulator to debug.
Some devices and some emulator configurations may not work with the tests. We do maintain an emulator configuration that works, as the standard for testing. To run this emulator config:
$ cd react-native
$ ./scripts/run-android-emulator.sh
Once you have an emulator running, to run the integration tests:
$ cd react-native
$ ./scripts/run-android-local-integration-tests.sh
The integration tests should only take a few minutes to run on a modern developer machine.
It's a good idea to add an Android integration test whenever you are working on code that needs both JavaScript and Java to be tested in conjunction. The Android integration tests live under [`ReactAndroid/src/androidTest`](https://github.com/facebook/react-native/tree/master/ReactAndroid/src/androidTest/java/com/facebook/react/tests), so you can browse through that directory for good examples of tests.
## iOS
### Integration Tests
React Native provides facilities to make it easier to test integrated components that require both native and JS components to communicate across the bridge. The two main components are `RCTTestRunner` and `RCTTestModule`. `RCTTestRunner` sets up the ReactNative environment and provides facilities to run the tests as `XCTestCase`s in Xcode (`runTest:module` is the simplest method). `RCTTestModule` is exported to JS as `NativeModules.TestModule`.
The tests themselves are written in JS, and must call `TestModule.markTestCompleted()` when they are done, otherwise the test will timeout and fail. Test failures are primarily indicated by throwing a JS exception. It is also possible to test error conditions with `runTest:module:initialProps:expectErrorRegex:` or `runTest:module:initialProps:expectErrorBlock:` which will expect an error to be thrown and verify the error matches the provided criteria.
See the following for example usage and integration points:
- [`IntegrationTestHarnessTest.js`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestHarnessTest.js)
- [`RNTesterIntegrationTests.m`](https://github.com/facebook/react-native/blob/master/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m)
- [`IntegrationTestsApp.js`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestsApp.js)
You can run integration tests locally with cmd+U in the IntegrationTest and RNTester apps in Xcode, or by running the following in the command line on macOS:
$ cd react-native
$ ./scripts/objc-test-ios.sh
> Your Xcode install will come with a variety of Simulators running the latest OS. You may need to manually create a new Simulator to match what the `XCODE_DESTINATION` param in the test script.
### Screenshot/Snapshot Tests
A common type of integration test is the snapshot test. These tests render a component, and verify snapshots of the screen against reference images using `TestModule.verifySnapshot()`, using the [`FBSnapshotTestCase`](https://github.com/facebook/ios-snapshot-test-case) library behind the scenes. Reference images are recorded by setting `recordMode = YES` on the `RCTTestRunner`, then running the tests. Snapshots will differ slightly between 32 and 64 bit, and various OS versions, so it's recommended that you enforce tests are run with the correct configuration. It's also highly recommended that all network data be mocked out, along with other potentially troublesome dependencies. See [`SimpleSnapshotTest`](https://github.com/facebook/react-native/blob/master/IntegrationTests/SimpleSnapshotTest.js) for a basic example.
If you make a change that affects a snapshot test in a PR, such as adding a new example case to one of the examples that is snapshotted, you'll need to re-record the snapshot reference image. To do this, simply change to `_runner.recordMode = YES;` in [RNTester/RNTesterSnapshotTests.m](https://github.com/facebook/react-native/blob/master/RNTester/RNTesterIntegrationTests/RNTesterSnapshotTests.m#L42), re-run the failing tests, then flip record back to `NO` and submit/update your PR and wait to see if the Circle build passes.
## Apple TV
The same tests discussed above for iOS will also run on tvOS. In the RNTester Xcode project, select the RNTester-tvOS target, and you can follow the same steps above to run the tests in Xcode.
You can run Apple TV unit and integration tests locally by running the following in the command line on macOS:
$ cd react-native
$ ./scripts/objc-test-tvos.sh (make sure the line `TEST="test"` is uncommented)
## End-to-end tests
Finally, make sure end-to-end tests run successfully by executing the following script:
$ cd react-native
$ ./scripts/test-manual-e2e.sh
## Website
The React Native website is hosted on GitHub pages and is automatically generated from Markdown sources as well as comments in the JavaScript source files. It's always a good idea to check that the website is generated properly whenever you edit the docs.
$ cd website
$ npm install
$ npm start
Then open http://localhost:8079/react-native/index.html in your browser.

View File

@ -1,80 +0,0 @@
---
id: timers
title: Timers
layout: docs
category: Guides
permalink: docs/timers.html
next: debugging
previous: improvingux
---
Timers are an important part of an application and React Native implements the [browser timers](https://developer.mozilla.org/en-US/Add-ons/Code_snippets/Timers).
## Timers
- setTimeout, clearTimeout
- setInterval, clearInterval
- setImmediate, clearImmediate
- requestAnimationFrame, cancelAnimationFrame
`requestAnimationFrame(fn)` is not the same as `setTimeout(fn, 0)` - the former will fire after all the frame has flushed, whereas the latter will fire as quickly as possible (over 1000x per second on a iPhone 5S).
`setImmediate` is executed at the end of the current JavaScript execution block, right before sending the batched response back to native. Note that if you call `setImmediate` within a `setImmediate` callback, it will be executed right away, it won't yield back to native in between.
The `Promise` implementation uses `setImmediate` as its asynchronicity primitive.
## InteractionManager
One reason why well-built native apps feel so smooth is by avoiding expensive operations during interactions and animations. In React Native, we currently have a limitation that there is only a single JS execution thread, but you can use `InteractionManager` to make sure long-running work is scheduled to start after any interactions/animations have completed.
Applications can schedule tasks to run after interactions with the following:
```javascript
InteractionManager.runAfterInteractions(() => {
// ...long-running synchronous task...
});
```
Compare this to other scheduling alternatives:
- requestAnimationFrame(): for code that animates a view over time.
- setImmediate/setTimeout/setInterval(): run code later, note this may delay animations.
- runAfterInteractions(): run code later, without delaying active animations.
The touch handling system considers one or more active touches to be an 'interaction' and will delay `runAfterInteractions()` callbacks until all touches have ended or been cancelled.
InteractionManager also allows applications to register animations by creating an interaction 'handle' on animation start, and clearing it upon completion:
```javascript
var handle = InteractionManager.createInteractionHandle();
// run animation... (`runAfterInteractions` tasks are queued)
// later, on animation completion:
InteractionManager.clearInteractionHandle(handle);
// queued tasks run if all handles were cleared
```
## TimerMixin
We found out that the primary cause of fatals in apps created with React Native was due to timers firing after a component was unmounted. To solve this recurring issue, we introduced `TimerMixin`. If you include `TimerMixin`, then you can replace your calls to `setTimeout(fn, 500)` with `this.setTimeout(fn, 500)` (just prepend `this.`) and everything will be properly cleaned up for you when the component unmounts.
This library does not ship with React Native - in order to use it on your project, you will need to install it with `npm i react-timer-mixin --save` from your project directory.
```javascript
import TimerMixin from 'react-timer-mixin';
var Component = createReactClass({
mixins: [TimerMixin],
componentDidMount: function() {
this.setTimeout(
() => { console.log('I do not leak!'); },
500
);
}
});
```
This will eliminate a lot of hard work tracking down bugs, such as crashes caused by timeouts firing after a component has been unmounted.
Keep in mind that if you use ES6 classes for your React components [there is no built-in API for mixins](https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#mixins). To use `TimerMixin` with ES6 classes, we recommend [react-mixin](https://github.com/brigand/react-mixin).

View File

@ -1,110 +0,0 @@
---
id: troubleshooting
title: Troubleshooting
layout: docs
category: Guides
permalink: docs/troubleshooting.html
next: native-modules-ios
previous: upgrading
---
These are some common issues you may run into while setting up React Native. If you encounter something that is not listed here, try [searching for the issue in GitHub](https://github.com/facebook/react-native/issues/).
### Port already in use
The React Native packager runs on port 8081. If another process is already using that port, you can either terminate that process, or change the port that the packager uses.
#### Terminating a process on port 8081
Run the following command on a Mac to find the id for the process that is listening on port 8081:
```
$ sudo lsof -i :8081
```
Then run the following to terminate the process:
```
$ kill -9 <PID>
```
On Windows you can find the process using port 8081 using [Resource Monitor](https://stackoverflow.com/questions/48198/how-can-you-find-out-which-process-is-listening-on-a-port-on-windows) and stop it using Task Manager.
#### Using a port other than 8081
You can configure the packager to use a port other than 8081 by using the `port` parameter:
```
$ react-native start --port=8088
```
You will also need to update your applications to load the JavaScript bundle from the new port. If running on device from Xcode, you can do this by updating occurrences of `8081` to your chosen port in the `node_modules/react-native/React/React.xcodeproj/project.pbxproj` file.
### NPM locking error
If you encounter an error such as `npm WARN locking Error: EACCES` while using the React Native CLI, try running the following:
```
sudo chown -R $USER ~/.npm
sudo chown -R $USER /usr/local/lib/node_modules
```
### Missing libraries for React
If you added React Native manually to your project, make sure you have included all the relevant dependencies that you are using, like `RCTText.xcodeproj`, `RCTImage.xcodeproj`. Next, the binaries built by these dependencies have to be linked to your app binary. Use the `Linked Frameworks and Binaries` section in the Xcode project settings. More detailed steps are here: [Linking Libraries](docs/linking-libraries-ios.html#content).
If you are using CocoaPods, verify that you have added React along with the subspecs to the `Podfile`. For example, if you were using the `<Text />`, `<Image />` and `fetch()` APIs, you would need to add these in your `Podfile`:
```
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'RCTText',
'RCTImage',
'RCTNetwork',
'RCTWebSocket',
]
```
Next, make sure you have run `pod install` and that a `Pods/` directory has been created in your project with React installed. CocoaPods will instruct you to use the generated `.xcworkspace` file henceforth to be able to use these installed dependencies.
#### Argument list too long: recursive header expansion failed
In the project's build settings, `User Search Header Paths` and `Header Search Paths` are two configs that specify where Xcode should look for `#import` header files specified in the code. For Pods, CocoaPods uses a default array of specific folders to look in. Verify that this particular config is not overwritten, and that none of the folders configured are too large. If one of the folders is a large folder, Xcode will attempt to recursively search the entire directory and throw above error at some point.
To revert the `User Search Header Paths` and `Header Search Paths` build settings to their defaults set by CocoaPods - select the entry in the Build Settings panel, and hit delete. It will remove the custom override and return to the CocoaPod defaults.
### No transports available
React Native implements a polyfill for WebSockets. These [polyfills](https://github.com/facebook/react-native/blob/master/Libraries/Core/InitializeCore.js) are initialized as part of the react-native module that you include in your application through `import React from 'react'`. If you load another module that requires WebSockets, such as [Firebase](https://github.com/facebook/react-native/issues/3645), be sure to load/require it after react-native:
```
import React from 'react';
import Firebase from 'firebase';
```
## Shell Command Unresponsive Exception
If you encounter a ShellCommandUnresponsiveException exception such as:
```
Execution failed for task ':app:installDebug'.
com.android.builder.testing.api.DeviceException: com.android.ddmlib.ShellCommandUnresponsiveException
```
Try [downgrading your Gradle version to 1.2.3](https://github.com/facebook/react-native/issues/2720) in `android/build.gradle`.
## react-native init hangs
If you run into issues where running `react-native init` hangs in your system, try running it again in verbose mode and refering to [#2797](https://github.com/facebook/react-native/issues/2797) for common causes:
```
react-native init --verbose
```
## Unable to start react-native package manager (on Linux)
### Case 1: Error "code":"ENOSPC","errno":"ENOSPC"
Issue caused by the number of directories [inotify](https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers) (used by watchman on Linux) can monitor. To solve it, just run this command in your terminal window
```
echo fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
```

View File

@ -1,53 +0,0 @@
---
id: tutorial
title: Learn the Basics
layout: docs
category: The Basics
permalink: docs/tutorial.html
next: props
previous: getting-started
---
React Native is like React, but it uses native components instead of web components as building blocks. So to understand the basic structure of a React Native app, you need to understand some of the basic React concepts, like JSX, components, `state`, and `props`. If you already know React, you still need to learn some React-Native-specific stuff, like the native components. This
tutorial is aimed at all audiences, whether you have React experience or not.
Let's do this thing.
## Hello World
In accordance with the ancient traditions of our people, we must first build an app that does nothing except say "Hello world". Here it is:
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';
export default class HelloWorldApp extends Component {
render() {
return (
<Text>Hello world!</Text>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
```
If you are feeling curious, you can play around with sample code directly in the web simulators. You can also paste it into your `App.js` file to create a real app on your local machine.
## What's going on here?
Some of the things in here might not look like JavaScript to you. Don't panic. _This is the future_.
First of all, ES2015 (also known as ES6) is a set of improvements to JavaScript that is now part of the official standard, but not yet supported by all browsers, so often it isn't used yet in web development. React Native ships with ES2015 support, so you can use this stuff without worrying about compatibility. `import`, `from`, `class`, `extends`, and the `() =>` syntax in the example above are all ES2015 features. If you aren't familiar with ES2015, you can probably pick it up just by reading through sample code like this tutorial has. If you want, [this page](https://babeljs.io/learn-es2015/) has a good overview of ES2015 features.
The other unusual thing in this code example is `<Text>Hello world!</Text>`. This is JSX - a syntax for embedding XML within JavaScript. Many frameworks use a special templating language which lets you embed code inside markup language. In React, this is reversed. JSX lets you write your markup language inside code. It looks like HTML on the web, except instead of web things like `<div>` or `<span>`, you use React components. In this case, `<Text>`
is a built-in component that just displays some text.
## Components
So this code is defining `HelloWorldApp`, a new `Component`. When you're building a React Native app, you'll be making new components a lot. Anything you see on the screen is some sort of component. A component can be pretty simple - the only thing that's required is a `render` function which returns some JSX to render.
## This app doesn't do very much
Good point. To make components do more interesting things, you need to [learn about Props](docs/props.html).

View File

@ -1,136 +0,0 @@
---
id: upgrading
title: Upgrading to new React Native versions
layout: docs
category: Guides
permalink: docs/upgrading.html
next: troubleshooting
previous: running-on-device
---
Upgrading to new versions of React Native will give you access to more APIs, views, developer tools and other goodies. Upgrading requires a small amount of effort, but we try to make it easy for you. The instructions are a bit different depending on whether you used `create-react-native-app` or `react-native init` to create your project.
## Create React Native App projects
Upgrading your Create React Native App project to a new version of React Native requires updating the `react-native`, `react`, and `expo` package versions in your `package.json` file. Please refer to [this document](https://github.com/react-community/create-react-native-app/blob/master/VERSIONS.md) to find out what versions are supported. You will also need to set the correct `sdkVersion` in your `app.json` file.
See the [CRNA user guide](https://github.com/react-community/create-react-native-app/blob/master/react-native-scripts/template/README.md#updating-to-new-releases) for up-to-date information about upgrading your project.
## Projects built with native code
<div class="banner-crna-ejected">
<h3>Projects with Native Code Only</h3>
<p>
This section only applies to projects made with <code>react-native init</code> or to those made with Create React Native App which have since ejected. For more information about ejecting, please see the <a href="https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md" target="_blank">guide</a> on the Create React Native App repository.
</p>
</div>
Because React Native projects built with native code are essentially made up of an Android project, an iOS project, and a JavaScript project, upgrading can be rather tricky. Here's what you need to do to upgrade from an older version of React Native.
### Upgrade based on Git
The module `react-native-git-upgrade` provides a one-step operation to upgrade the source files with a minimum of conflicts. Under the hood, it consists in 2 phases:
* First, it computes a Git patch between both old and new template files,
* Then, the patch is applied on the user's sources.
> **IMPORTANT:** You don't have to install the new version of the `react-native` package, it will be installed automatically.
#### 1. Install Git
While your project does not have to be handled by the Git versioning system -- you can use Mercurial, SVN, or nothing -- you will still need to [install Git](https://git-scm.com/downloads) on your system in order to use `react-native-git-upgrade`. Git will also need to be available in the `PATH`.
#### 2. Install the `react-native-git-upgrade` module
The `react-native-git-upgrade` module provides a CLI and must be installed globally:
```sh
$ npm install -g react-native-git-upgrade
```
#### 3. Run the command
Run the following command to start the process of upgrading to the latest version:
```sh
$ react-native-git-upgrade
```
> You may specify a React Native version by passing an argument: `react-native-git-upgrade X.Y`
The templates are upgraded in a optimized way. You still may encounter conflicts but only where the Git 3-way merge have failed, depending on the version and how you modified your sources.
#### 4. Resolve the conflicts
Conflicted files include delimiters which make very clear where the changes come from. For example:
```
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
<<<<<<< ours
CODE_SIGN_IDENTITY = "iPhone Developer";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/HockeySDK.embeddedframework",
"$(PROJECT_DIR)/HockeySDK-iOS/HockeySDK.embeddedframework",
);
=======
CURRENT_PROJECT_VERSION = 1;
>>>>>>> theirs
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
"$(SRCROOT)/../node_modules/react-native/React/**",
"$(SRCROOT)/../node_modules/react-native-code-push/ios/CodePush/**",
);
```
You can think of "ours" as "your team" and "theirs" as "the React Native dev team".
### Alternative
Use this only in case the above didn't work.
#### 1. Upgrade the `react-native` dependency
Note the latest version of the `react-native` npm package [from here](https://www.npmjs.com/package/react-native) (or use `npm info react-native` to check).
Now install that version of `react-native` in your project with `npm install --save`:
```sh
$ npm install --save react-native@X.Y
# where X.Y is the semantic version you are upgrading to
npm WARN peerDependencies The peer dependency react@~R included from react-native...
```
If you saw a warning about the peerDependency, also upgrade `react` by running:
```sh
$ npm install --save react@R
# where R is the new version of react from the peerDependency warning you saw
```
#### 2. Upgrade your project templates
The new npm package may contain updates to the files that are normally generated when you
run `react-native init`, like the iOS and the Android sub-projects.
You may consult [rn-diff](https://github.com/ncuillery/rn-diff) to see if there were changes in the project template files.
In case there weren't any, simply rebuild the project and continue developing. In case of minor changes, you may update your project manually and rebuild.
If there were major changes, run this in a terminal to get these:
```sh
$ react-native upgrade
```
This will check your files against the latest template and perform the following:
* If there is a new file in the template, it is simply created.
* If a file in the template is identical to your file, it is skipped.
* If a file is different in your project than the template, you will be prompted; you have options to keep your file or overwrite it with the template version.
## Manual Upgrades
Some upgrades require manual steps, e.g. 0.13 to 0.14, or 0.28 to 0.29. Be sure to check the [release notes](https://github.com/facebook/react-native/releases) when upgrading so that you can identify any manual changes your particular project may require.

View File

@ -1,157 +0,0 @@
---
id: accessibilityinfo
title: AccessibilityInfo
layout: docs
category: APIs
permalink: docs/accessibilityinfo.html
next: actionsheetios
previous: webview
---
Sometimes it's useful to know whether or not the device has a screen reader that is currently active. The `AccessibilityInfo` API is designed for this purpose. You can use it to query the current state of the screen reader as well as to register to be notified when the state of the screen reader changes.
Here's a small example illustrating how to use `AccessibilityInfo`:
```javascript
class ScreenReaderStatusExample extends React.Component {
state = {
screenReaderEnabled: false,
}
componentDidMount() {
AccessibilityInfo.addEventListener(
'change',
this._handleScreenReaderToggled
);
AccessibilityInfo.fetch().done((isEnabled) => {
this.setState({
screenReaderEnabled: isEnabled
});
});
}
componentWillUnmount() {
AccessibilityInfo.removeEventListener(
'change',
this._handleScreenReaderToggled
);
}
_handleScreenReaderToggled = (isEnabled) => {
this.setState({
screenReaderEnabled: isEnabled,
});
}
render() {
return (
<View>
<Text>
The screen reader is {this.state.screenReaderEnabled ? 'enabled' : 'disabled'}.
</Text>
</View>
);
}
}
```
### Methods
- [`fetch`](docs/accessibilityinfo.html#fetch)
- [`addEventListener`](docs/accessibilityinfo.html#addeventlistener)
- [`setAccessibilityFocus`](docs/accessibilityinfo.html#setaccessibilityfocus)
- [`announceForAccessibility`](docs/accessibilityinfo.html#announceforaccessibility)
- [`removeEventListener`](docs/accessibilityinfo.html#removeeventlistener)
---
# Reference
## Methods
### `fetch()`
```javascript
AccessibilityInfo.fetch()
```
Query whether a screen reader is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when a screen reader is enabled and `false` otherwise.
---
### `addEventListener()`
```javascript
AccessibilityInfo.addEventListener(eventName, handler)
```
Add an event handler.
| Name | Type | Required | Description |
| - | - | - | - |
| eventName | string | Yes | Name of the event |
| handler | function | Yes | Event handler |
Supported events:
- `change`: Fires when the state of the screen reader changes. The argument
to the event handler is a boolean. The boolean is `true` when a screen
reader is enabled and `false` otherwise.
- `announcementFinished`: iOS-only event. Fires when the screen reader has
finished making an announcement. The argument to the event handler is a dictionary
with these keys:
- `announcement`: The string announced by the screen reader.
- `success`: A boolean indicating whether the announcement was successfully made.
---
### `setAccessibilityFocus()`
```javascript
AccessibilityInfo.setAccessibilityFocus(reactTag)
```
Set accessibility focus to a React component.
| Name | Type | Required | Description |
| - | - | - | - |
| reactTag | number | Yes | React component tag |
| Platform |
| - |
| iOS |
---
### `announceForAccessibility()`
```javascript
AccessibilityInfo.announceForAccessibility(announcement)
```
Post a string to be announced by the screen reader.
| Name | Type | Required | Description |
| - | - | - | - |
| announcement | string | Yes | String to be announced |
| Platform |
| - |
| iOS |
---
### `removeEventListener()`
```javascript
AccessibilityInfo.removeEventListener(eventName, handler)
```
Remove an event handler.
| Name | Type | Required | Description |
| - | - | - | - |
| eventName | string | Yes | Name of the event |
| handler | function | Yes | Event handler |

View File

@ -1,96 +0,0 @@
---
id: actionsheetios
title: ActionSheetIOS
layout: docs
category: APIs
permalink: docs/actionsheetios.html
next: alert
previous: accessibilityinfo
---
Display action sheets and share sheets on iOS.
### Methods
- [`showActionSheetWithOptions`](docs/actionsheetios.html#showactionsheetwithoptions)
- [`showShareActionSheetWithOptions`](docs/actionsheetios.html#showshareactionsheetwithoptions)
---
# Reference
## Methods
### `showActionSheetWithOptions()`
```javascript
ActionSheetIOS.showActionSheetWithOptions(options, callback)
```
Display an iOS action sheet.
| Name | Type | Required | Description |
| - | - | - | - |
| options | object | Yes | See below. |
| callback | function | Yes | Provides index for the selected item. |
The `options` object must contain one or more of:
- `options` (array of strings) - a list of button titles (required)
- `cancelButtonIndex` (int) - index of cancel button in `options`
- `destructiveButtonIndex` (int) - index of destructive button in `options`
- `title` (string) - a title to show above the action sheet
- `message` (string) - a message to show below the title
The 'callback' function takes one parameter, the zero-based index
of the selected item.
Minimal example:
```
ActionSheetIOS.showActionSheetWithOptions({
options: ['Remove', 'Cancel'],
destructiveButtonIndex: 1,
cancelButtonIndex: 0,
},
(buttonIndex) => {
if (buttonIndex === 1) { // destructive action }
});
```
---
### `showShareActionSheetWithOptions()`
```javascript
ActionSheetIOS.showShareActionSheetWithOptions(options, failureCallback, successCallback)
```
Display the iOS share sheet.
| Name | Type | Required | Description |
| - | - | - | - |
| options | object | Yes | See below. |
| failureCallback | function | Yes | See below. |
| successCallback | function | Yes | See below. |
The `options` object should contain one or both of `message` and `url` and can additionally have a `subject` or `excludedActivityTypes`:
- `url` (string) - a URL to share
- `message` (string) - a message to share
- `subject` (string) - a subject for the message
- `excludedActivityTypes` (array) - the activities to exclude from the ActionSheet
> NOTE:
> If `url` points to a local file, or is a base64-encoded uri, the file it points to will be loaded and shared directly. In this way, you can share images, videos, PDF files, etc.
The 'failureCallback' function takes one parameter, an error object. The only property defined on this object is an optional `stack` property of type `string`.
The 'successCallback' function takes two parameters:
- a boolean value signifying success or failure
- a string that, in the case of success, indicates the method of sharing

View File

@ -1,106 +0,0 @@
---
id: activityindicator
title: ActivityIndicator
layout: docs
category: components
permalink: docs/activityindicator.html
next: button
---
Displays a circular loading indicator.
### Example
```ReactNativeWebPlayer
import React, { Component } from 'react'
import {
ActivityIndicator,
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native'
class App extends Component {
render() {
return (
<View style={[styles.container, styles.horizontal]}>
<ActivityIndicator size="large" color="#0000ff" />
<ActivityIndicator size="small" color="#00ff00" />
<ActivityIndicator size="large" color="#0000ff" />
<ActivityIndicator size="small" color="#00ff00" />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center'
},
horizontal: {
flexDirection: 'row',
justifyContent: 'space-around',
padding: 10
}
})
AppRegistry.registerComponent('App', () => App)
```
### Props
- [`View` props...](docs/view.html#props)
- [`animating`](docs/activityindicator.html#animating)
- [`color`](docs/activityindicator.html#color)
- [`size`](docs/activityindicator.html#size)
- [`hidesWhenStopped`](docs/activityindicator.html#hideswhenstopped)
---
# Reference
## Props
### `animating`
Whether to show the indicator (`true`, the default) or hide it (`false`).
| Type | Required |
| - | - |
| bool | No |
---
### `color`
The foreground color of the spinner (default is gray).
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
---
### `size`
Size of the indicator (default is 'small').
Passing a number to the size prop is only supported on Android.
| Type | Required |
| - | - |
| enum('small', 'large'), number | No |
---
### `hidesWhenStopped`
Whether the indicator should hide when not animating (true by default).
| Type | Required | Platform |
| - | - | - |
| bool | No | iOS |

View File

@ -1,79 +0,0 @@
---
id: alert
title: Alert
layout: docs
category: APIs
permalink: docs/alert.html
next: alertios
previous: actionsheetios
---
Use `Alert` to display an alert dialog.
This is an API that works both on iOS and Android and can show static alerts. To show an alert that prompts the user to enter some information, see [`AlertIOS`](docs/alertios.html), as entering text in an alert is common on iOS only.
Optionally provide a list of buttons. Tapping any button will fire the respective `onPress` callback, and dismiss the alert. If no buttons are provided, a single 'OK' button will be displayed by default.
On iOS, you can specify any number of buttons.
On Android, at most three buttons can be specified. Android has a concept of a neutral, negative and a positive button:
- If you specify one button, it will be the 'positive' one (such as 'OK')
- Two buttons mean 'negative', 'positive' (such as 'Cancel', 'OK')
- Three buttons mean 'neutral', 'negative', 'positive' (such as 'Later', 'Cancel', 'OK')
Alerts on Android can be dismissed by tapping outside of the alert box. This event can be handled by providing an optional `options` parameter, with an `onDismiss` callback property `{ onDismiss: () => {} }`.
Alternatively, the dismissing behavior can be disabled altogether by providing an optional `options` parameter with the `cancelable` property set to `false`, i.e. `{ cancelable: false }`
Example usage:
```
// Works on both iOS and Android
Alert.alert(
'Alert Title',
'My Alert Msg',
[
{text: 'Ask me later', onPress: () => console.log('Ask me later pressed')},
{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: () => console.log('OK Pressed')},
],
{ cancelable: false }
)
```
### Methods
- [`alert`](docs/alert.html#alert)
---
# Reference
## Methods
### `alert()`
```javascript
Alert.alert(title, [message], [buttons], [options])
```
Launches an alert dialog with the specified title, and optionally a message.
| Name | Type | Required | Description |
| - | - | - | - |
| title | string | Yes | Alert title |
| message | string | No | Alert message |
| buttons | array | No | Array of buttons |
| options | object | No | See below. |
The optional `buttons` array should be composed of objects with any of the following:
- `text` (string) - text to display for this button
- `onPress` (function) - callback to be fired when button is tapped
- `style` (string) - on iOS, specifies the button style, one of 'default', 'cancel', or 'destructive'
The `options` object may include the following keys:
- `onDismiss` - provide a callback function to handle dismissal on Android
- `cancelable` - set to false to disable the default dismissal behavior on Android

View File

@ -1,196 +0,0 @@
---
id: alertios
title: AlertIOS
layout: docs
category: APIs
permalink: docs/alertios.html
next: animated
previous: alert
---
Use `AlertIOS` to display an alert dialog with a message or to create a prompt for user input on iOS. If you don't need to prompt for user input, we recommend using [`Alert.alert()`](docs/alert.html#alert) for cross-platform support.
### Examples
Creating an iOS alert:
```
AlertIOS.alert(
'Sync Complete',
'All your data are belong to us.'
);
```
Creating an iOS prompt:
```
AlertIOS.prompt(
'Enter a value',
null,
text => console.log("You entered "+text)
);
```
Example with custom buttons:
```javascript
AlertIOS.alert(
'Update available',
'Keep your app up to date to enjoy the latest features',
[
{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'Install', onPress: () => console.log('Install Pressed')},
],
);
```
Example with custom buttons:
```javascript
AlertIOS.prompt(
'Enter password',
'Enter your password to claim your $1.5B in lottery winnings',
[
{text: 'Cancel', onPress: () => console.log('Cancel Pressed'), style: 'cancel'},
{text: 'OK', onPress: password => console.log('OK Pressed, password: ' + password)},
],
'secure-text'
);
```
Example with the default button and a custom callback:
```javascript
AlertIOS.prompt(
'Update username',
null,
text => console.log("Your username is "+text),
null,
'default'
);
```
### Methods
- [`alert`](docs/alertios.html#alert)
- [`prompt`](docs/alertios.html#prompt)
### Type Definitions
- [`AlertType`](docs/alertios.html#alerttype)
- [`AlertButtonStyle`](docs/alertios.html#alertbuttonstyle)
- [`ButtonsArray`](docs/alertios.html#buttonsarray)
---
# Reference
## Methods
### `alert()`
```javascript
AlertIOS.alert(title, [message], [callbackOrButtons])
```
Create and display a popup alert with a title and an optional message.
If passed a function in the `callbackOrButtons` param, it will be called when the user taps 'OK'. If passed an array of button configurations, each button should include a `text` key, as well as optional `onPress` and `style` keys. `style` should be one of 'default', 'cancel' or 'destructive'. See [ButtonsArray](docs/alertios.html#buttonsarray)
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| title | string | Yes | The dialog's title. Passing null or '' will hide the title. |
| message | string | No | An optional message that appears below the dialog's title. |
| callbackOrButtons | function, [ButtonsArray](docs/alertios.html#buttonsarray) | No | This optional argument should be either a single-argument function or an [array of buttons](docs/alertios.html#buttonsarray). |
---
### `prompt()`
```javascript
AlertIOS.prompt(title, [message], [callbackOrButtons], [type], [defaultValue], [keyboardType])
```
Create and display a prompt to enter some text.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| title | string | Yes | The dialog's title. |
| message | string | No | An optional message that appears above the text input. |
| callbackOrButtons | function, [ButtonsArray](docs/alertios.html#buttonsarray) | No | This optional argument should be either a single-argument function or an [array of buttons](docs/alertios.html#buttonsarray). |
| type | [AlertType](docs/alertios.html#alerttype) | No | This configures the text input. |
| defaultValue | string | No | The default text in text input. |
| keyboardType | string | No | The keyboard type of first text field(if exists). One of 'default', 'email-address', 'numeric', 'phone-pad', 'ascii-capable', 'numbers-and-punctuation', 'url', 'number-pad', 'name-phone-pad', 'decimal-pad', 'twitter' or 'web-search'. |
## Type Definitions
### AlertType
An Alert button type.
| Type |
| - |
| enum('default', 'plain-text', 'secure-text', 'login-password') |
**Constants:**
| Value | Description |
| - | - |
| 'default' | Default alert with no inputs |
| 'plain-text' | Plain text input alert |
| 'secure-text' | Secure text input alert |
| 'login-password' | Login and password alert |
---
### AlertButtonStyle
An Alert button style.
| Type |
| - |
| enum('default', 'cancel', 'destructive') |
**Constants:**
| Value | Description |
| - | - |
| 'default' | Default button style |
| 'cancel' | Cancel button style |
| 'destructive' | Destructive button style |
---
### ButtonsArray
Array of objects that describe a button.
| Type |
| - |
| array of objects |
**Properties:**
| Name | Type | Description |
| - | - | - |
| [text] | string | Button label |
| [onPress] | function | Callback function when button pressed |
| [style] | [AlertButtonStyle](docs/alertios.html#alertbuttonstyle) | Button style |

View File

@ -1,164 +0,0 @@
---
id: android-building-from-source
title: Building React Native from source
layout: docs
category: Guides (Android)
permalink: docs/android-building-from-source.html
banner: ejected
next: communication-android
previous: android-ui-performance
---
You will need to build React Native from source if you want to work on a new feature/bug fix, try out the latest features which are not released yet, or maintain your own fork with patches that cannot be merged to the core.
## Prerequisites
Assuming you have the Android SDK installed, run `android` to open the Android SDK Manager.
Make sure you have the following installed:
1. Android SDK version 23 (compileSdkVersion in [`build.gradle`](https://github.com/facebook/react-native/blob/master/ReactAndroid/build.gradle))
2. SDK build tools version 23.0.1 (buildToolsVersion in [`build.gradle`](https://github.com/facebook/react-native/blob/master/ReactAndroid/build.gradle))
3. Android Support Repository >= 17 (for Android Support Library)
4. Android NDK (download links and installation instructions below)
### Point Gradle to your Android SDK:
**Step 1:** Set environment variables through your local shell.
Note: Files may vary based on shell flavor. See below for examples from common shells.
- bash: `.bash_profile` or `.bashrc`
- zsh: `.zprofile` or `.zshrc`
- ksh: `.profile` or `$ENV`
Example:
```
export ANDROID_SDK=/Users/your_unix_name/android-sdk-macosx
export ANDROID_NDK=/Users/your_unix_name/android-ndk/android-ndk-r10e
```
**Step 2:** Create a `local.properties` file in the `android` directory of your react-native app with the following contents:
Example:
```
sdk.dir=/Users/your_unix_name/android-sdk-macosx
ndk.dir=/Users/your_unix_name/android-ndk/android-ndk-r10e
```
### Download links for Android NDK
1. Mac OS (64-bit) - http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip
2. Linux (64-bit) - http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip
3. Windows (64-bit) - http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip
4. Windows (32-bit) - http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip
You can find further instructions on the [official page](https://developer.android.com/ndk/index.html).
## Building the source
#### 1. Installing the fork
First, you need to install `react-native` from your fork. For example, to install the master branch from the official repo, run the following:
```sh
npm install --save github:facebook/react-native#master
```
Alternatively, you can clone the repo to your `node_modules` directory and run `npm install` inside the cloned repo.
#### 2. Adding gradle dependencies
Add `gradle-download-task` as dependency in `android/build.gradle`:
```gradle
...
dependencies {
classpath 'com.android.tools.build:gradle:1.3.1'
classpath 'de.undercouch:gradle-download-task:3.1.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
...
```
#### 3. Adding the `:ReactAndroid` project
Add the `:ReactAndroid` project in `android/settings.gradle`:
```gradle
...
include ':ReactAndroid'
project(':ReactAndroid').projectDir = new File(
rootProject.projectDir, '../node_modules/react-native/ReactAndroid')
...
```
Modify your `android/app/build.gradle` to use the `:ReactAndroid` project instead of the pre-compiled library, e.g. - replace `compile 'com.facebook.react:react-native:+'` with `compile project(':ReactAndroid')`:
```gradle
...
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.0.1'
compile project(':ReactAndroid')
...
}
...
```
#### 4. Making 3rd-party modules use your fork
If you use 3rd-party React Native modules, you need to override their dependencies so that they don't bundle the pre-compiled library. Otherwise you'll get an error while compiling - `Error: more than one library with package name 'com.facebook.react'`.
Modify your `android/app/build.gradle`, and add:
```gradle
configurations.all {
exclude group: 'com.facebook.react', module: 'react-native'
}
```
## Building from Android Studio
From the Welcome screen of Android Studio choose "Import project" and select the `android` folder of your app.
You should be able to use the _Run_ button to run your app on a device. Android Studio won't start the packager automatically, you'll need to start it by running `npm start` on the command line.
## Additional notes
Building from source can take a long time, especially for the first build, as it needs to download ~200 MB of artifacts and compile the native code. Every time you update the `react-native` version from your repo, the build directory may get deleted, and all the files are re-downloaded. To avoid this, you might want to change your build directory path by editing the `~/.gradle/init.gradle ` file:
```gradle
gradle.projectsLoaded {
rootProject.allprojects {
buildDir = "/path/to/build/directory/${rootProject.name}/${project.name}"
}
}
```
## Building for Maven/Nexus deployment
If you find that you need to push up a locally compiled React Native .aar and related files to a remote Nexus repository, you can.
Start by following the `Point Gradle to your Android SDK` section of this page. Once you do this, assuming you have Gradle configured properly, you can then run the following command from the root of your React Native checkout to build and package all required files:
```
./gradlew ReactAndroid:installArchives
```
This will package everything that would typically be included in the `android` directory of your `node_modules/react-native/` installation in the root directory of your React Native checkout.
## Testing
If you made changes to React Native and submit a pull request, all tests will run on your pull request automatically. To run the tests locally, see [Running Tests](docs/testing.html).
## Troubleshooting
Gradle build fails in `ndk-build`. See the section about `local.properties` file above.

View File

@ -1,8 +0,0 @@
---
id: android-ui-performance
title: Profiling Android UI Performance
layout: redirect
permalink: docs/android-ui-performance.html
destinationUrl: performance.html
---
Redirecting...

View File

@ -1,603 +0,0 @@
---
id: animated
title: Animated
layout: docs
category: APIs
permalink: docs/animated.html
next: animatedvalue
previous: alertios
---
The `Animated` library is designed to make animations fluid, powerful, and easy to build and maintain. `Animated` focuses on declarative relationships between inputs and outputs, with configurable transforms in between, and simple `start`/`stop` methods to control time-based animation execution.
The simplest workflow for creating an animation is to create an `Animated.Value`, hook it up to one or more style attributes of an animated component, and then drive updates via animations using `Animated.timing()`:
```javascript
Animated.timing( // Animate value over time
this.state.fadeAnim, // The value to drive
{
toValue: 1, // Animate to final value of 1
}
).start(); // Start the animation
```
Refer to the [Animations](docs/animations.html#animated-api) guide to see additional examples of `Animated` in action.
## Overview
There are two value types you can use with `Animated`:
- [`Animated.Value()`](docs/animatedvalue.html) for single values
- [`Animated.ValueXY()`](docs/animatedvaluexy.html) for vectors
`Animated.Value` can bind to style properties or other props, and can be interpolated as well. A single `Animated.Value` can drive any number of properties.
### Configuring animations
`Animated` provides three types of animation types. Each animation type provides a particular animation curve that controls how your values animate from their initial value to the final value:
- [`Animated.decay()`](docs/animated.html#decay) starts with an initial velocity and gradually slows to a stop.
- [`Animated.spring()`](docs/animated.html#spring) provides a simple spring physics model.
- [`Animated.timing()`](docs/animated.html#timing) animates a value over time using [easing functions](docs/easing.html).
In most cases, you will be using `timing()`. By default, it uses a symmetric easeInOut curve that conveys the gradual acceleration of an object to full speed and concludes by gradually decelerating to a stop.
### Working with animations
Animations are started by calling `start()` on your animation. `start()` takes a completion callback that will be called when the animation is done. If the animation finished running normally, the completion callback will be invoked with `{finished: true}`. If the animation is done because `stop()` was called on it before it could finish (e.g. because it was interrupted by a gesture or another animation), then it will receive `{finished: false}`.
```javascript
this.animateValue.spring({}).start(({finished}) => {
if (finished) {
console.log('Animation was completed')
} else {
console.log('Animation was aborted')
}
})
```
### Using the native driver
By using the native driver, we send everything about the animation to native before starting the animation, allowing native code to perform the animation on the UI thread without having to go through the bridge on every frame. Once the animation has started, the JS thread can be blocked without affecting the animation.
You can use the native driver by specifying `useNativeDriver: true` in your animation configuration. See the [Animations](docs/animations.html#using-the-native-driver) guide to learn more.
### Animatable components
Only animatable components can be animated. These special components do the magic of binding the animated values to the properties, and do targeted native updates to avoid the cost of the react render and reconciliation process on every frame. They also handle cleanup on unmount so they are safe by default.
- [`createAnimatedComponent()`](docs/animated.html#createanimatedcomponent) can be used to make a component animatable.
`Animated` exports the following animatable components using the above wrapper:
- `Animated.Image`
- `Animated.ScrollView`
- `Animated.Text`
- `Animated.View`
### Composing animations
Animations can also be combined in complex ways using composition functions:
- [`Animated.delay()`](docs/animated.html#delay) starts an animation after a given delay.
- [`Animated.parallel()`](docs/animated.html#parallel) starts a number of animations at the same time.
- [`Animated.sequence()`](docs/animated.html#sequence) starts the animations in order, waiting for each to complete before starting the next.
- [`Animated.stagger()`](docs/animated.html#stagger) starts animations in order and in parallel, but with successive delays.
Animations can also be chained together simply by setting the `toValue` of one animation to be another `Animated.Value`. See [Tracking dynamic values](docs/animations.html#tracking-dynamic-values) in the Animations guide.
By default, if one animation is stopped or interrupted, then all other animations in the group are also stopped.
### Combining animated values
You can combine two animated values via addition, multiplication, division, or modulo to make a new animated value:
- [`Animated.add()`](docs/animated.html#add)
- [`Animated.divide()`](docs/animated.html#divide)
- [`Animated.modulo()`](docs/animated.html#modulo)
- [`Animated.multiply()`](docs/animated.html#multiply)
### Interpolation
The `interpolate()` function allows input ranges to map to different output ranges. By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value. It uses lineal interpolation by default but also supports easing functions.
- [`interpolate()`](docs/animatedvalue.html#interpolate)
Read more about interpolation in the [Animation](docs/animations.html#interpolation) guide.
### Handling gestures and other events
Gestures, like panning or scrolling, and other events can map directly to animated values using `Animated.event()`. This is done with a structured map syntax so that values can be extracted from complex event objects. The first level is an array to allow mapping across multiple args, and that array contains nested objects.
- [`Animated.event()`](docs/animated.html#event)
For example, when working with horizontal scrolling gestures, you would do the following in order to map `event.nativeEvent.contentOffset.x` to `scrollX` (an `Animated.Value`):
```javascript
onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{ nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}
```
### Methods
#### Configuring animations
- [`decay()`](docs/animated.html#decay)
- [`timing()`](docs/animated.html#timing)
- [`spring()`](docs/animated.html#spring)
#### Combining animated values
- [`add`](docs/animated.html#add)
- [`divide`](docs/animated.html#divide)
- [`multiply`](docs/animated.html#multiply)
- [`modulo`](docs/animated.html#modulo)
- [`diffClamp`](docs/animated.html#diffclamp)
#### Composing animations
- [`delay`](docs/animated.html#delay)
- [`sequence`](docs/animated.html#sequence)
- [`parallel`](docs/animated.html#parallel)
- [`stagger`](docs/animated.html#stagger)
#### Handling gestures and other events
- [`event`](docs/animated.html#event)
- [`attachNativeEvent`](docs/animated.html#attachnativeevent)
- [`forkEvent`](docs/animated.html#forkevent)
- [`unforkEvent`](docs/animated.html#unforkevent)
#### Others
- [`loop`](docs/animated.html#loop)
- [`createAnimatedComponent`](docs/animated.html#createanimatedcomponent)
### Properties
- [`Value`](docs/animated.html#value)
- [`ValueXY`](docs/animated.html#valuexy)
- [`Interpolation`](docs/animated.html#interpolation)
- [`Node`](docs/animated.html#node)
---
# Reference
## Methods
### `decay()`
```javascript
Animated.decay(value, config)
```
Animates a value from an initial velocity to zero based on a decay coefficient.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| value | AnimatedValue or AnimatedValueXY | Yes | Value to animate. |
| config | object | Yes | See below. |
Config is an object that may have the following options:
- `velocity`: Initial velocity. Required.
- `deceleration`: Rate of decay. Default 0.997.
- `isInteraction`: Whether or not this animation creates an "interaction handle" on the
`InteractionManager`. Default true.
- `useNativeDriver`: Uses the native driver when true. Default false.
---
### `timing()`
```javascript
Animated.timing(value, config)
```
Animates a value along a timed easing curve. The [`Easing`](docs/easing.html) module has tons of predefined curves, or you can use your own function.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| value | AnimatedValue or AnimatedValueXY | Yes | Value to animate. |
| config | object | Yes | See below. |
Config is an object that may have the following options:
- `duration`: Length of animation (milliseconds). Default 500.
- `easing`: Easing function to define curve.
Default is `Easing.inOut(Easing.ease)`.
- `delay`: Start the animation after delay (milliseconds). Default 0.
- `isInteraction`: Whether or not this animation creates an "interaction handle" on the
`InteractionManager`. Default true.
- `useNativeDriver`: Uses the native driver when true. Default false.
---
### `spring()`
```javascript
Animated.spring(value, config)
```
Animates a value according to an analytical spring model based on [damped harmonic oscillation](https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator). Tracks velocity state to create fluid motions as the `toValue` updates, and can be chained together.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| value | AnimatedValue or AnimatedValueXY | Yes | Value to animate. |
| config | object | Yes | See below. |
`config` is an object that may have the following options.
Note that you can only define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one:
The friction/tension or bounciness/speed options match the spring model in [Facebook Pop](https://github.com/facebook/pop), [Rebound](http://facebook.github.io/rebound/), and [Origami](http://origami.design/).
- `friction`: Controls "bounciness"/overshoot. Default 7.
- `tension`: Controls speed. Default 40.
- `speed`: Controls speed of the animation. Default 12.
- `bounciness`: Controls bounciness. Default 8.
Specifying stiffness/damping/mass as parameters makes `Animated.spring` use an analytical spring model based on the motion equations of a [damped harmonic oscillator](https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator). This behavior is slightly more precise and faithful to the physics behind spring dynamics, and closely mimics the implementation in iOS's CASpringAnimation primitive.
- `stiffness`: The spring stiffness coefficient. Default 100.
- `damping`: Defines how the springs motion should be damped due to the forces of friction. Default 10.
- `mass`: The mass of the object attached to the end of the spring. Default 1.
Other configuration options are as follows:
- `velocity`: The initial velocity of the object attached to the spring. Default 0 (object is at rest).
- `overshootClamping`: Boolean indiciating whether the spring should be clamped and not bounce. Default false.
- `restDisplacementThreshold`: The threshold of displacement from rest below which the spring should be considered at rest. Default 0.001.
- `restSpeedThreshold`: The speed at which the spring should be considered at rest in pixels per second. Default 0.001.
- `delay`: Start the animation after delay (milliseconds). Default 0.
- `isInteraction`: Whether or not this animation creates an "interaction handle" on the `InteractionManager`. Default true.
- `useNativeDriver`: Uses the native driver when true. Default false.
---
### `add()`
```javascript
Animated.add(a, b)
```
Creates a new Animated value composed from two Animated values added together.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| a | AnimatedValue | Yes | Operand. |
| b | AnimatedValue | Yes | Operand. |
---
### `divide()`
```javascript
Animated.divide(a, b)
```
Creates a new Animated value composed by dividing the first Animated value by the second Animated value.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| a | AnimatedValue | Yes | Operand. |
| b | AnimatedValue | Yes | Operand. |
---
### `multiply()`
```javascript
Animated.multiply(a, b)
```
Creates a new Animated value composed from two Animated values multiplied together.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| a | AnimatedValue | Yes | Operand. |
| b | AnimatedValue | Yes | Operand. |
---
### `modulo()`
```javascript
Animated.modulo(a, modulus)
```
Creates a new Animated value that is the (non-negative) modulo of the provided Animated value.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| a | AnimatedValue | Yes | Operand. |
| modulus | AnimatedValue | Yes | Operand. |
---
### `diffClamp()`
```javascript
Animated.diffClamp(a, min, max)
```
Create a new Animated value that is limited between 2 values. It uses the difference between the last value so even if the value is far from the bounds it will start changing when the value starts getting closer again. (`value = clamp(value + diff, min, max)`).
This is useful with scroll events, for example, to show the navbar when scrolling up and to hide it when scrolling down.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| a | AnimatedValue | Yes | Operand. |
| min | number | Yes | Minimum value. |
| max | number | Yes | Maximum value. |
---
### `delay()`
```javascript
Animated.delay(time)
```
Starts an animation after the given delay.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| time | number | Yes | Delay in milliseconds. |
---
### `sequence()`
```javascript
Animated.sequence(animations)
```
Starts an array of animations in order, waiting for each to complete before starting the next. If the current running animation is stopped, no following animations will be started.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| animations | array | Yes | Array of animations. |
---
### `parallel()`
```javascript
Animated.parallel(animations, [config])
```
Starts an array of animations all at the same time. By default, if one
of the animations is stopped, they will all be stopped. You can override
this with the `stopTogether` flag through `config`.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| animations | array | Yes | Array of animations. |
| config | object | No | An object with a `stopTogether` key (boolean). |
---
### `stagger()`
```javascript
Animated.stagger(time, animations)
```
Array of animations may run in parallel (overlap), but are started in
sequence with successive delays. Nice for doing trailing effects.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| time | number | Yes | Delay in milliseconds. |
| animations | array | Yes | Array of animations. |
---
### `loop()`
```javascript
Animated.loop(animation)
```
Loops a given animation continuously, so that each time it reaches the end, it resets and begins again from the start. Can specify number of times to loop using the key `iterations` in the config. Will loop without blocking the UI thread if the child animation is set to `useNativeDriver: true`. In addition, loops can prevent `VirtualizedList`-based components from rendering more rows while the animation is running. You can pass `isInteraction: false` in the child animation config to fix this.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| animation | animation | Yes | Animation to loop. |
---
### `event()`
```javascript
Animated.event(argMapping, [config])
```
Takes an array of mappings and extracts values from each arg accordingly, then calls `setValue` on the mapped outputs. e.g.
```javascript
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: this._scrollX}}}],
{listener: (event) => console.log(event)}, // Optional async listener
)}
...
onPanResponderMove: Animated.event([
null, // raw event arg ignored
{dx: this._panX}, // gestureState arg
{listener: (event, gestureState) => console.log(event, gestureState)}, // Optional async listener
]),
```
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| argMapping | array | Yes | Array of mappings. |
| config | object | No | See below. |
Config is an object that may have the following options:
- `listener`: Optional async listener.
- `useNativeDriver`: Uses the native driver when true. Default false.
---
### `createAnimatedComponent()`
```javascript
createAnimatedComponent(component)
```
Make any React component Animatable. Used to create `Animated.View`, etc.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| component | component | Yes | React component |
---
### `attachNativeEvent()`
```javascript
attachNativeEvent(viewRef, eventName, argMapping)
```
Imperative API to attach an animated value to an event on a view. Prefer using `Animated.event` with `useNativeDrive: true` if possible.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| viewRef | any | Yes | View reference. |
| eventName | string | Yes | Event name. |
| argMapping | array | Yes | Array of mappings. |
---
### `forkEvent()`
```javascript
Animated.forkEvent(event, listener)
```
Advanced imperative API for snooping on animated events that are passed in through props. Use values directly where possible.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| event | event or function | Yes | Event. |
| listener | function | Yes | Handler. |
---
### `unforkEvent()`
```javascript
Animated.unforkEvent(event, listener)
```
Advanced imperative API for snooping on animated events that are passed in through props. Use values directly where possible.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| event | event or function | Yes | Event. |
| listener | function | Yes | Handler. |
## Properties
### Value
Standard value for driving animations.
| Type |
| - |
| [`AnimatedValue`](docs/animatedvalue.html) |
---
### ValueXY
2D value class for driving 2D animations, such as pan gestures.
| Type |
| - |
| [`AnimatedValueXY`](docs/animatedvaluexy.html) |
---
### Interpolation
Exported to use the Interpolation type in flow.
| Type |
| - |
| AnimatedInterpolation |
---
### Node
Exported for ease of type checking. All animated values derive from this class. See `AnimatedNode.js`.
| Type |
| - |
| AnimatedNode |

View File

@ -1,234 +0,0 @@
---
id: animatedvalue
title: AnimatedValue
layout: docs
category: APIs
permalink: docs/animatedvalue.html
next: animatedvaluexy
previous: animated
---
Standard value for driving animations. One `Animated.Value` can drive multiple properties in a synchronized fashion, but can only be driven by one mechanism at a time. Using a new mechanism (e.g. starting a new animation, or calling `setValue`) will stop any previous ones.
Typically initialized with `new Animated.Value(0);`
See also [`Animated`](docs/animated.html).
### Methods
- [`setValue`](docs/animatedvalue.html#setvalue)
- [`setOffset`](docs/animatedvalue.html#setoffset)
- [`flattenOffset`](docs/animatedvalue.html#flattenoffset)
- [`extractOffset`](docs/animatedvalue.html#extractoffset)
- [`addListener`](docs/animatedvalue.html#addlistener)
- [`removeListener`](docs/animatedvalue.html#removelistener)
- [`removeAllListeners`](docs/animatedvalue.html#removealllisteners)
- [`stopAnimation`](docs/animatedvalue.html#stopanimation)
- [`resetAnimation`](docs/animatedvalue.html#resetanimation)
- [`interpolate`](docs/animatedvalue.html#interpolate)
- [`animate`](docs/animatedvalue.html#animate)
- [`stopTracking`](docs/animatedvalue.html#stoptracking)
- [`track`](docs/animatedvalue.html#track)
---
# Reference
## Methods
### `setValue()`
```javascript
setValue(value)
```
Directly set the value. This will stop any animations running on the value and update all the bound properties.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| value | number | Yes | Value |
---
### `setOffset()`
```javascript
setOffset(offset)
```
Sets an offset that is applied on top of whatever value is set, whether via `setValue`, an animation, or `Animated.event`. Useful for compensating things like the start of a pan gesture.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| offset | number | Yes | Offset value |
---
### `flattenOffset()`
```javascript
flattenOffset()
```
Merges the offset value into the base value and resets the offset to zero. The final output of the value is unchanged.
---
### `extractOffset()`
```javascript
extractOffset()
```
Sets the offset value to the base value, and resets the base value to zero. The final output of the value is unchanged.
---
### `addListener()`
```javascript
addListener(callback)
```
Adds an asynchronous listener to the value so you can observe updates from animations. This is useful because there is no way to synchronously read the value because it might be driven natively.
Returns a string that serves as an identifier for the listener.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | function | Yes | The callback function which will receive an object with a `value` key set to the new value. |
---
### `removeListener()`
```javascript
removeListener(id)
```
Unregister a listener. The `id` param shall match the identifier previously returned by `addListener()`.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| id | string | Yes | Id for the listener being removed. |
---
### `removeAllListeners()`
```javascript
removeAllListeners()
```
Remove all registered listeners.
---
### `stopAnimation()`
```javascript
stopAnimation([callback])
```
Stops any running animation or tracking. `callback` is invoked with the final value after stopping the animation, which is useful for updating state to match the animation position with layout.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | function | No | A function that will receive the final value. |
---
### `resetAnimation()`
```javascript
resetAnimation([callback])
```
Stops any animation and resets the value to its original.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | function | No | A function that will receive the original value. |
---
### `interpolate()`
```javascript
interpolate(config)
```
Interpolates the value before updating the property, e.g. mapping 0-1 to 0-10.
See `AnimatedInterpolation.js`
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| config | object | Yes | See below. |
The `config` object is composed of the following keys:
- `inputRange`: an array of numbers
- `outputRange`: an array of numbers or strings
- `easing` (optional): a function that returns a number, given an input number
- `extrapolate` (optional): a string such as 'extend', 'identity', or 'clamp'
- `extrapolateLeft` (optional): a string such as 'extend', 'identity', or 'clamp'
- `extrapolateRight` (optional): a string such as 'extend', 'identity', or 'clamp'
---
### `animate()`
```javascript
animate(animation, callback)
```
Typically only used internally, but could be used by a custom Animation class.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| animation | Animation | Yes | See `Animation.js`. |
| callback | function | Yes | Callback function. |
---
### `stopTracking()`
```javascript
stopTracking()
```
Typically only used internally.
---
### `track()`
```javascript
track(tracking)
```
Typically only used internally.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| tracking | AnimatedNode | Yes | See `AnimatedNode.js` |

View File

@ -1,228 +0,0 @@
---
id: animatedvaluexy
title: AnimatedValueXY
layout: docs
category: APIs
permalink: docs/animatedvaluexy.html
next: appregistry
previous: animatedvalue
---
2D Value for driving 2D animations, such as pan gestures. Almost identical API to normal [`Animated.Value`](docs/animatedvalue.html), but multiplexed. Contains two regular `Animated.Value`s under the hood.
See also [`Animated`](docs/animated.html).
## Example
```javascript
class DraggableView extends React.Component {
constructor(props) {
super(props);
this.state = {
pan: new Animated.ValueXY(), // inits to zero
};
this.state.panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: Animated.event([null, {
dx: this.state.pan.x, // x,y are Animated.Value
dy: this.state.pan.y,
}]),
onPanResponderRelease: () => {
Animated.spring(
this.state.pan, // Auto-multiplexed
{toValue: {x: 0, y: 0}} // Back to zero
).start();
},
});
}
render() {
return (
<Animated.View
{...this.state.panResponder.panHandlers}
style={this.state.pan.getLayout()}>
{this.props.children}
</Animated.View>
);
}
}
```
### Methods
- [`setValue`](docs/animatedvaluexy.html#setvalue)
- [`setOffset`](docs/animatedvaluexy.html#setoffset)
- [`flattenOffset`](docs/animatedvaluexy.html#flattenoffset)
- [`extractOffset`](docs/animatedvaluexy.html#extractoffset)
- [`addListener`](docs/animatedvaluexy.html#addlistener)
- [`removeListener`](docs/animatedvaluexy.html#removelistener)
- [`removeAllListeners`](docs/animatedvaluexy.html#removealllisteners)
- [`stopAnimation`](docs/animatedvaluexy.html#stopanimation)
- [`resetAnimation`](docs/animatedvaluexy.html#resetanimation)
- [`getLayout`](docs/animatedvaluexy.html#getlayout)
- [`getTranslateTransform`](docs/animatedvaluexy.html#gettranslatetransform)
---
# Reference
## Methods
### `setValue()`
```javascript
setValue(value)
```
Directly set the value. This will stop any animations running on the value and update all the bound properties.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| value | number | Yes | |
---
### `setOffset()`
```javascript
setOffset(offset)
```
Sets an offset that is applied on top of whatever value is set, whether via `setValue`, an animation, or `Animated.event`. Useful for compensating things like the start of a pan gesture.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| offset | number | Yes | |
---
### `flattenOffset()`
```javascript
flattenOffset()
```
Merges the offset value into the base value and resets the offset to zero. The final output of the value is unchanged.
---
### `extractOffset()`
```javascript
extractOffset()
```
Sets the offset value to the base value, and resets the base value to zero. The final output of the value is unchanged.
---
### `addListener()`
```javascript
addListener(callback)
```
Adds an asynchronous listener to the value so you can observe updates from animations. This is useful because there is no way to synchronously read the value because it might be driven natively.
Returns a string that serves as an identifier for the listener.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | function | Yes | The callback function which will receive an object with a `value` key set to the new value. |
---
### `removeListener()`
```javascript
removeListener(id)
```
Unregister a listener. The `id` param shall match the identifier previously returned by `addListener()`.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| id | string | Yes | Id for the listener being removed. |
---
### `removeAllListeners()`
```javascript
removeAllListeners()
```
Remove all registered listeners.
---
### `stopAnimation()`
```javascript
stopAnimation([callback])
```
Stops any running animation or tracking. `callback` is invoked with the final value after stopping the animation, which is useful for updating state to match the animation position with layout.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | function | No | A function that will receive the final value. |
---
### `resetAnimation()`
```javascript
resetAnimation([callback])
```
Stops any animation and resets the value to its original.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | function | No | A function that will receive the original value. |
---
### `getLayout()`
```javascript
getLayout()
```
Converts `{x, y}` into `{left, top}` for use in style, e.g.
```javascript
style={this.state.anim.getLayout()}
```
---
### `getTranslateTransform()`
```javascript
getTranslateTransform()
```
Converts `{x, y}` into a useable translation transform, e.g.
```javascript
style={{
transform: this.state.anim.getTranslateTransform()
}}
```

View File

@ -1,31 +0,0 @@
---
id: app-extensions
title: App Extensions
layout: docs
category: Guides (iOS)
permalink: docs/app-extensions.html
next: native-modules-android
previous: building-for-apple-tv
---
App extensions let you provide custom functionality and content outside of your main app. There are different types of app extensions on iOS, and they are all covered in the [App Extension Programming Guide](https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/index.html#//apple_ref/doc/uid/TP40014214-CH20-SW1). In this guide, we'll briefly cover how you may take advantage of app extensions on iOS.
## Memory use in extensions
As these extensions are loaded outside of the regular app sandbox, it's highly likely that several of these app extensions will be loaded simultaneously. As you might expect, these extensions have small memory usage limits. Keep these in mind when developing your app extensions. It's always highly recommended to test your application on an actual device, and more so when developing app extensions: too frequently, developers find that their extension works just fine in the iOS Simulator, only to get user reports that their extension is not loading on actual devices.
We highly recommend that you watch Conrad Kramer's talk on [Memory Use in Extensions](https://cocoaheads.tv/memory-use-in-extensions-by-conrad-kramer/) to learn more about this topic.
### Today widget
The memory limit of a Today widget is 16 MB. As it happens, Today widget implementations using React Native may work unreliably because the memory usage tends to be too high. You can tell if your Today widget is exceeding the memory limit if it yields the message 'Unable to Load':
![](img/TodayWidgetUnableToLoad.jpg)
Always make sure to test your app extensions in a real device, but be aware that this may not be sufficient, especially when dealing with Today widgets. Debug-configured builds are more likely to exceed the memory limits, while release-configured builds don't fail right away. We highly recommend that you use [Xcode's Instruments](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html) to analyze your real world memory usage, as it's very likely that your release-configured build is very close to the 16 MB limit. In situations like these, it is easy to go over the 16 MB limit by performing common operations, such as fetching data from an API.
To experiment with the limits of React Native Today widget implementations, try extending the example project in [react-native-today-widget](https://github.com/matejkriz/react-native-today-widget/).
### Other app extensions
Other types of app extensions have greater memory limits than the Today widget. For instance, Custom Keyboard extensions are limited to 48 MB, and Share extensions are limited to 120 MB. Implementing such app extensions with React Native is more viable. One proof of concept example is [react-native-ios-share-extension](https://github.com/andrewsardone/react-native-ios-share-extension).

View File

@ -1,234 +0,0 @@
---
id: appregistry
title: AppRegistry
layout: docs
category: APIs
permalink: docs/appregistry.html
next: appstate
previous: animated
---
<div class="banner-crna-ejected">
<h3>Project with Native Code Required</h3>
<p>
This API only works in projects made with <code>react-native init</code> or in those made with Create React Native App which have since ejected. For more information about ejecting, please see the <a href="https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md" target="_blank">guide</a> on the Create React Native App repository.
</p>
</div>
`AppRegistry` is the JavaScript entry point to running all React Native apps. App root components should register themselves with `AppRegistry.registerComponent()`, then the native system can load the bundle for the app and then actually run the app when it's ready by invoking `AppRegistry.runApplication()`.
To "stop" an application when a view should be destroyed, call `AppRegistry.unmountApplicationComponentAtRootTag()` with the tag that was passed into `runApplication()`. These should always be used as a pair.
`AppRegistry` should be `require`d early in the `require` sequence to make sure the JavaScript execution environment is set up before other modules are `require`d.
### Methods
- [`registerComponent`](docs/appregistry.html#registercomponent)
- [`runApplication`](docs/appregistry.html#runapplication)
- [`unmountApplicationComponentAtRootTag`](docs/appregistry.html#unmountapplicationcomponentatroottag)
- [`registerHeadlessTask`](docs/appregistry.html#registerheadlesstask)
- [`startHeadlessTask`](docs/appregistry.html#startheadlesstask)
- [`setWrapperComponentProvider`](docs/appregistry.html#setwrappercomponentprovider)
- [`registerConfig`](docs/appregistry.html#registerconfig)
- [`registerRunnable`](docs/appregistry.html#registerrunnable)
- [`registerSection`](docs/appregistry.html#registersection)
- [`getAppKeys`](docs/appregistry.html#getappkeys)
- [`getSectionKeys`](docs/appregistry.html#getsectionkeys)
- [`getSections`](docs/appregistry.html#getsections)
- [`getRunnable`](docs/appregistry.html#getrunnable)
- [`getRegistry`](docs/appregistry.html#getregistry)
- [`setComponentProviderInstrumentationHook`](docs/appregistry.html#setcomponentproviderinstrumentationhook)
---
# Reference
## Methods
### `registerComponent()`
```javascript
AppRegistry.registerComponent(appKey, componentProvider, [section])
```
Registers an app's root component.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| appKey | string | Yes | Application key. |
| componentProvider | function | Yes | A function that returns a React component or element. |
| section | boolean | No | Is this a section? |
---
### `runApplication()`
```javascript
AppRegistry.runApplication(appKey, appParameters)
```
Loads the JavaScript bundle and runs the app.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| appKey | string | Yes | Application key. |
| appParameters | any | Yes | Params. |
---
### `unmountApplicationComponentAtRootTag()`
```javascript
AppRegistry.unmountApplicationComponentAtRootTag(rootTag)
```
Stops an application when a view should be destroyed. The `rootTag` should match the tag that was passed into `runApplication()`. These should always be used as a pair.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| rootTag | number | Yes | React tag. |
---
### `registerHeadlessTask()`
```javascript
AppRegistry.registerHeadlessTask(taskKey, task)
```
Register a headless task. A headless task is a bit of code that runs without a UI.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| taskKey | string | No | The key associated with this task. |
| task | function | No | A promise returning function that takes some data passed from the native side as the only argument; when the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. |
---
### `startHeadlessTask()`
```javascript
AppRegistry.startHeadlessTask(taskId, taskKey, data)
```
Only called from native code. Starts a headless task.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| taskId | number | No | The native id for this task instance to keep track of its execution. |
| taskKey | string | No | The key for the task to start. |
| data | any | No | The data to pass to the task. |
---
### `setWrapperComponentProvider()`
```javascript
AppRegistry.setWrapperComponentProvider(provider)
```
---
### `registerConfig()`
```javascript
AppRegistry.registerConfig(config)
```
---
### `registerRunnable()`
```javascript
AppRegistry.registerRunnable(appKey, run)
```
---
### `registerSection()`
```javascript
AppRegistry.registerSection(appKey, component)
```
---
### `getAppKeys()`
```javascript
AppRegistry.getAppKeys()
```
---
### `getSectionKeys()`
```javascript
AppRegistry.getSectionKeys()
```
---
### `getSections()`
```javascript
AppRegistry.getSections()
```
---
### `getRunnable()`
```javascript
AppRegistry.getRunnable(appKey)
```
---
### `getRegistry()`
```javascript
AppRegistry.getRegistry()
```
---
### `setComponentProviderInstrumentationHook()`
```javascript
AppRegistry.setComponentProviderInstrumentationHook(hook)
```

View File

@ -1,107 +0,0 @@
---
id: appstate
title: AppState
layout: docs
category: APIs
permalink: docs/appstate.html
next: asyncstorage
previous: appregistry
---
`AppState` can tell you if the app is in the foreground or background, and notify you when the state changes.
App state is frequently used to determine the intent and proper behavior when handling push notifications.
### App States
- `active` - The app is running in the foreground
- `background` - The app is running in the background. The user is either
in another app or on the home screen
- `inactive` - This is a state that occurs when transitioning between foreground & background, and during periods of inactivity such as entering the Multitasking view or in the event of an incoming call
For more information, see [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html).
### Basic Usage
To see the current state, you can check `AppState.currentState`, which will be kept up-to-date. However, `currentState` will be null at launch while `AppState` retrieves it over the bridge.
```javascript
import React, {Component} from 'react'
import {AppState, Text} from 'react-native'
class AppStateExample extends Component {
state = {
appState: AppState.currentState
}
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this._handleAppStateChange);
}
_handleAppStateChange = (nextAppState) => {
if (this.state.appState.match(/inactive|background/) && nextAppState === 'active') {
console.log('App has come to the foreground!')
}
this.setState({appState: nextAppState});
}
render() {
return (
<Text>Current state is: {this.state.appState}</Text>
);
}
}
```
This example will only ever appear to say "Current state is: active" because the app is only visible to the user when in the `active` state, and the null state will happen only momentarily.
### Methods
- [`addEventListener`](docs/appstate.html#addeventlistener)
- [`removeEventListener`](docs/appstate.html#removeeventlistener)
---
# Reference
## Methods
### `addEventListener()`
```javascript
addEventListener(type, handler)
```
Add a handler to AppState changes by listening to the `change` event type and providing the handler.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| type | string | Yes | |
| handler | function | Yes | |
---
### `removeEventListener()`
```javascript
removeEventListener(type, handler)
```
Remove a handler by passing the `change` event type and the handler.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| type | string | Yes | |
| handler | function | Yes | |

View File

@ -1,404 +0,0 @@
---
id: asyncstorage
title: AsyncStorage
layout: docs
category: APIs
permalink: docs/asyncstorage.html
next: backandroid
previous: appstate
---
`AsyncStorage` is a simple, unencrypted, asynchronous, persistent, key-value storage system that is global to the app. It should be used instead of LocalStorage.
It is recommended that you use an abstraction on top of `AsyncStorage` instead of `AsyncStorage` directly for anything more than light usage since it operates globally.
On iOS, `AsyncStorage` is backed by native code that stores small values in a serialized dictionary and larger values in separate files. On Android, `AsyncStorage` will use either [RocksDB](http://rocksdb.org/) or SQLite based on what is available.
The `AsyncStorage` JavaScript code is a simple facade that provides a clear JavaScript API, real `Error` objects, and simple non-multi functions. Each method in the API returns a `Promise` object.
Persisting data:
```javascript
try {
await AsyncStorage.setItem('@MySuperStore:key', 'I like to save it.');
} catch (error) {
// Error saving data
}
```
Fetching data:
```javascript
try {
const value = await AsyncStorage.getItem('@MySuperStore:key');
if (value !== null){
// We have data!!
console.log(value);
}
} catch (error) {
// Error retrieving data
}
```
Merging data:
```javascript
let UID123_object = {
name: 'Chris',
age: 30,
traits: {hair: 'brown', eyes: 'brown'},
};
// You only need to define what will be added or updated
let UID123_delta = {
age: 31,
traits: {eyes: 'blue', shoe_size: 10}
};
AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => {
AsyncStorage.mergeItem('UID123', JSON.stringify(UID123_delta), () => {
AsyncStorage.getItem('UID123', (err, result) => {
console.log(result);
});
});
});
// Console log result:
// => {'name':'Chris','age':31,'traits':
// {'shoe_size':10,'hair':'brown','eyes':'blue'}}
```
Multi merge example:
```javascript
// first user, initial values
let UID234_object = {
name: 'Chris',
age: 30,
traits: {hair: 'brown', eyes: 'brown'},
};
// first user, delta values
let UID234_delta = {
age: 31,
traits: {eyes: 'blue', shoe_size: 10},
};
// second user, initial values
let UID345_object = {
name: 'Marge',
age: 25,
traits: {hair: 'blonde', eyes: 'blue'},
};
// second user, delta values
let UID345_delta = {
age: 26,
traits: {eyes: 'green', shoe_size: 6},
};
let multi_set_pairs = [['UID234', JSON.stringify(UID234_object)], ['UID345', JSON.stringify(UID345_object)]]
let multi_merge_pairs = [['UID234', JSON.stringify(UID234_delta)], ['UID345', JSON.stringify(UID345_delta)]]
AsyncStorage.multiSet(multi_set_pairs, (err) => {
AsyncStorage.multiMerge(multi_merge_pairs, (err) => {
AsyncStorage.multiGet(['UID234','UID345'], (err, stores) => {
stores.map( (result, i, store) => {
let key = store[i][0];
let val = store[i][1];
console.log(key, val);
});
});
});
});
// Console log results:
// => UID234 {"name":"Chris","age":31,"traits":{"shoe_size":10,"hair":"brown","eyes":"blue"}}
// => UID345 {"name":"Marge","age":26,"traits":{"shoe_size":6,"hair":"blonde","eyes":"green"}}
```
Fetching multiple items:
```javascript
AsyncStorage.getAllKeys((err, keys) => {
AsyncStorage.multiGet(keys, (err, stores) => {
stores.map((result, i, store) => {
// get at each store's key/value so you can work with it
let key = store[i][0];
let value = store[i][1];
});
});
});
```
Removing multiple items:
```javascript
let keys = ['k1', 'k2'];
AsyncStorage.multiRemove(keys, (err) => {
// keys k1 & k2 removed, if they existed
// do most stuff after removal (if you want)
});
```
### Methods
- [`getItem`](docs/asyncstorage.html#getitem)
- [`setItem`](docs/asyncstorage.html#setitem)
- [`removeItem`](docs/asyncstorage.html#removeitem)
- [`mergeItem`](docs/asyncstorage.html#mergeitem)
- [`clear`](docs/asyncstorage.html#clear)
- [`getAllKeys`](docs/asyncstorage.html#getallkeys)
The following batched functions are useful for executing a lot of operations at once, allowing for native optimizations and provide the convenience of a single callback after all operations are complete.
These functions return arrays of errors, potentially one for every key. For key-specific errors, the Error object will have a key property to indicate which key caused the error.
- [`flushGetRequests`](docs/asyncstorage.html#flushgetrequests)
- [`multiGet`](docs/asyncstorage.html#multiget)
- [`multiSet`](docs/asyncstorage.html#multiset)
- [`multiRemove`](docs/asyncstorage.html#multiremove)
- [`multiMerge`](docs/asyncstorage.html#multimerge)
---
# Reference
## Methods
### `getItem()`
```javascript
AsyncStorage.getItem(key, [callback])
```
Fetches an item for a `key` and invokes a callback upon completion.
Returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| key | string | Yes | Key of the item to fetch. |
| callback | (error, result) => void | No | Function that will be called with a result if found or any error. |
---
### `setItem()`
```javascript
AsyncStorage.setItem(key, value, [callback])
```
Sets the value for a `key` and invokes a callback upon completion.
Returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| key | string | Yes | Key of the item to set. |
| value | string | Yes | Value to set for the `key`. |
| callback | (error) => void | No | Function that will be called with any error. |
---
### `removeItem()`
```javascript
AsyncStorage.removeItem(key, [callback])
```
Removes an item for a `key` and invokes a callback upon completion.
Returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| key | string | Yes | Key of the item to remove. |
| callback | (error) => void | No | Function that will be called with any error. |
---
### `mergeItem()`
```javascript
AsyncStorage.mergeItem(key, value, [callback])
```
Merges an existing `key` value with an input value, assuming both values are stringified JSON. Returns a `Promise` object.
> Note:
> This is not supported by all native implementations.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| key | string | Yes | Key of the item to modify. |
| value | string | Yes | New value to merge for the `key`. |
| callback | (error) => void | No | Function that will be called with any error. |
---
### `clear()`
```javascript
AsyncStorage.clear([callback])
```
Erases *all* `AsyncStorage` for all clients, libraries, etc. You probably don't want to call this; use `removeItem` or `multiRemove` to clear only your app's keys. Returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | (error) => void | No | Function that will be called with any error. |
---
### `getAllKeys()`
```javascript
AsyncStorage.getAllKeys([callback])
```
Gets *all* keys known to your app; for all callers, libraries, etc.
Returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| callback | (error, keys) => void | No | Function that will be called with an array of keys found, and any error. |
---
### `flushGetRequests()`
```javascript
AsyncStorage.flushGetRequests()
```
Flushes any pending requests using a single batch call to get the data.
---
### `multiGet()`
```javascript
AsyncStorage.multiGet(keys, [callback])
```
This allows you to batch the fetching of items given an array of `key` inputs. Your callback will be invoked with an array of corresponding key-value pairs found:
```
multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']])
```
The method returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| keys | Array<string> | Yes | Array of key for the items to get. |
| callback | (errors, result) => void | No | Function that will be called with a key-value array of the results, plus an array of any key-specific errors found. |
---
### `multiSet()`
```javascript
AsyncStorage.multiSet(keyValuePairs, [callback])
```
Use this as a batch operation for storing multiple key-value pairs. When
the operation completes you'll get a single callback with any errors:
```
multiSet([['k1', 'val1'], ['k2', 'val2']], cb);
```
The method returns a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| keyValuePairs | Array<Array<string>> | Yes | Array of key-value array for the items to set. |
| callback | (errors) => void | No | Function that will be called with an array of any key-specific errors found. |
---
### `multiRemove()`
```javascript
AsyncStorage.multiRemove(keys, [callback])
```
Call this to batch the deletion of all keys in the `keys` array. Returns
a `Promise` object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| keys | Array<string> | Yes | Array of key for the items to delete. |
| callback | (errors) => void | No | Function that will be called an array of any key-specific errors found. |
---
### `multiMerge()`
```javascript
AsyncStorage.multiMerge(keyValuePairs, [callback])
```
Batch operation to merge in existing and new values for a given set of
keys. This assumes that the values are stringified JSON. Returns a
`Promise` object.
**NOTE**: This is not supported by all native implementations.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| keyValuePairs | Array<Array<string>> | Yes | Array of key-value array for the items to merge. |
| callback | (errors) => void | No | Function that will be called with an array of any key-specific errors found. |

View File

@ -1,56 +0,0 @@
---
id: backandroid
title: BackAndroid
layout: docs
category: APIs
permalink: docs/backandroid.html
next: backhandler
previous: asyncstorage
---
**Deprecated.** Use [BackHandler](docs/backhandler.html) instead.
### Methods
- [`exitApp`](docs/backandroid.html#exitapp)
- [`addEventListener`](docs/backandroid.html#addeventlistener)
- [`removeEventListener`](docs/backandroid.html#removeeventlistener)
---
# Reference
## Methods
### `exitApp()`
```javascript
BackAndroid.exitApp()
```
---
### `addEventListener()`
```javascript
BackAndroid.addEventListener(eventName, handler)
```
---
### `removeEventListener()`
```javascript
BackAndroid.removeEventListener(eventName, handler)
```

View File

@ -1,79 +0,0 @@
---
id: backhandler
title: BackHandler
layout: docs
category: APIs
permalink: docs/backhandler.html
next: cameraroll
previous: backhandler
---
Detect hardware button presses for back navigation.
**Android:** Detect hardware back button presses, and programmatically invoke the default back button functionality to exit the app if there are no listeners or if none of the listeners return true.
**tvOS:** Detect presses of the menu button on the TV remote. Still to be implemented: programmatically disable menu button handling functionality to exit the app if there are no listeners or if none of the listeners return true.
**iOS:** Not applicable.
The event subscriptions are called in reverse order (i.e. last registered subscription first), and if one subscription returns true then subscriptions registered earlier will not be called.
Example:
```javascript
BackHandler.addEventListener('hardwareBackPress', function() {
// this.onMainScreen and this.goBack are just examples, you need to use your own implementation here
// Typically you would use the navigator here to go to the last state.
if (!this.onMainScreen()) {
this.goBack();
return true;
}
return false;
});
```
### Methods
- [`exitApp`](docs/backhandler.html#exitapp)
- [`addEventListener`](docs/backhandler.html#addeventlistener)
- [`removeEventListener`](docs/backhandler.html#removeeventlistener)
---
# Reference
## Methods
### `exitApp()`
```javascript
BackHandler.exitApp()
```
---
### `addEventListener()`
```javascript
BackHandler.addEventListener(eventName, handler)
```
---
### `removeEventListener()`
```javascript
BackHandler.removeEventListener(eventName, handler)
```

View File

@ -1,96 +0,0 @@
---
id: building-for-apple-tv
title: Building For Apple TV
layout: docs
category: Guides (iOS)
permalink: docs/building-for-apple-tv.html
banner: ejected
next: app-extensions
previous: communication-ios
---
Apple TV support has been implemented with the intention of making existing React Native iOS applications "just work" on tvOS, with few or no changes needed in the JavaScript code for the applications.
The RNTester app supports Apple TV; use the `RNTester-tvOS` build target to build for tvOS.
## Build changes
- *Native layer*: React Native Xcode projects all now have Apple TV build targets, with names ending in the string '-tvOS'.
- *react-native init*: New React Native projects created with `react-native init` will have Apple TV target automatically created in their XCode projects.
- *JavaScript layer*: Support for Apple TV has been added to `Platform.ios.js`. You can check whether code is running on AppleTV by doing
```js
var Platform = require('Platform');
var running_on_apple_tv = Platform.isTVOS;
```
## Code changes
- *General support for tvOS*: Apple TV specific changes in native code are all wrapped by the TARGET_OS_TV define. These include changes to suppress APIs that are not supported on tvOS (e.g. web views, sliders, switches, status bar, etc.), and changes to support user input from the TV remote or keyboard.
- *Common codebase*: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS.
- *Access to touchable controls*: When running on Apple TV, the native view class is `RCTTVView`, which has additional methods to make use of the tvOS focus engine. The `Touchable` mixin has code added to detect focus changes and use existing methods to style the components properly and initiate the proper actions when the view is selected using the TV remote, so `TouchableHighlight` and `TouchableOpacity` will "just work". In particular:
- `touchableHandleActivePressIn` will be executed when the touchable view goes into focus
- `touchableHandleActivePressOut` will be executed when the touchable view goes out of focus
- `touchableHandlePress` will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote.
- *TV remote/keyboard input*: A new native class, `RCTTVRemoteHandler`, sets up gesture recognizers for TV remote events. When TV remote events occur, this class fires notifications that are picked up by `RCTTVNavigationEventEmitter` (a subclass of `RCTEventEmitter`), that fires a JS event. This event will be picked up by instances of the `TVEventHandler` JavaScript object. Application code that needs to implement custom handling of TV remote events can create an instance of `TVEventHandler` and listen for these events, as in the following code:
```js
var TVEventHandler = require('TVEventHandler');
.
.
.
class Game2048 extends React.Component {
_tvEventHandler: any;
_enableTVEventHandler() {
this._tvEventHandler = new TVEventHandler();
this._tvEventHandler.enable(this, function(cmp, evt) {
if (evt && evt.eventType === 'right') {
cmp.setState({board: cmp.state.board.move(2)});
} else if(evt && evt.eventType === 'up') {
cmp.setState({board: cmp.state.board.move(1)});
} else if(evt && evt.eventType === 'left') {
cmp.setState({board: cmp.state.board.move(0)});
} else if(evt && evt.eventType === 'down') {
cmp.setState({board: cmp.state.board.move(3)});
} else if(evt && evt.eventType === 'playPause') {
cmp.restartGame();
}
});
}
_disableTVEventHandler() {
if (this._tvEventHandler) {
this._tvEventHandler.disable();
delete this._tvEventHandler;
}
}
componentDidMount() {
this._enableTVEventHandler();
}
componentWillUnmount() {
this._disableTVEventHandler();
}
```
- *Dev Menu support*: On the simulator, cmd-D will bring up the developer menu, just like on iOS. To bring it up on a real Apple TV device, make a long press on the play/pause button on the remote. (Please do not shake the Apple TV device, that will not work :) )
- *TV remote animations*: `RCTTVView` native code implements Apple-recommended parallax animations to help guide the eye as the user navigates through views. The animations can be disabled or adjusted with new optional view properties.
- *Back navigation with the TV remote menu button*: The `BackHandler` component, originally written to support the Android back button, now also supports back navigation on the Apple TV using the menu button on the TV remote.
- *TabBarIOS behavior*: The `TabBarIOS` component wraps the native `UITabBar` API, which works differently on Apple TV. To avoid jittery rerendering of the tab bar in tvOS (see [this issue](https://github.com/facebook/react-native/issues/15081)), the selected tab bar item can only be set from Javascript on initial render, and is controlled after that by the user through native code.
- *Known issues*:
- [ListView scrolling](https://github.com/facebook/react-native/issues/12793). The issue can be easily worked around by setting `removeClippedSubviews` to false in ListView and similar components. For more discussion of this issue, see [this PR](https://github.com/facebook/react-native/pull/12944).

View File

@ -1,148 +0,0 @@
---
id: button
title: Button
layout: docs
category: components
permalink: docs/button.html
next: checkbox
previous: activityindicator
---
A basic button component that should render nicely on any platform. Supports
a minimal level of customization.
<center><img src="img/buttonExample.png"></img></center>
If this button doesn't look right for your app, you can build your own
button using [TouchableOpacity](docs/touchableopacity.html)
or [TouchableNativeFeedback](docs/touchablenativefeedback.html).
For inspiration, look at the [source code for this button component](https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js).
Or, take a look at the [wide variety of button components built by the community](https://js.coach/react-native?search=button).
Example usage:
```
import { Button } from 'react-native';
...
<Button
onPress={onPressLearnMore}
title="Learn More"
color="#841584"
accessibilityLabel="Learn more about this purple button"
/>
```
### Props
- [`onPress`](docs/button.html#onpress)
- [`title`](docs/button.html#title)
- [`accessibilityLabel`](docs/button.html#accessibilitylabel)
- [`color`](docs/button.html#color)
- [`disabled`](docs/button.html#disabled)
- [`testID`](docs/button.html#testid)
- [`hasTVPreferredFocus`](docs/button.html#hastvpreferredfocus)
---
# Reference
## Props
### `onPress`
Handler to be called when the user taps the button
| Type | Required |
| - | - |
| function | Yes |
---
### `title`
Text to display inside the button
| Type | Required |
| - | - |
| string | Yes |
---
### `accessibilityLabel`
Text to display for blindness accessibility features
| Type | Required |
| - | - |
| string | No |
---
### `color`
Color of the text (iOS), or background color of the button (Android)
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
---
### `disabled`
If true, disable all interactions for this component.
| Type | Required |
| - | - |
| bool | No |
---
### `testID`
Used to locate this view in end-to-end tests.
| Type | Required |
| - | - |
| string | No |
---
### `hasTVPreferredFocus`
*(Apple TV only)* TV preferred focus (see documentation for the View component).
| Type | Required | Platform |
| - | - | - |
| bool | No | iOS |

View File

@ -1,152 +0,0 @@
---
id: cameraroll
title: CameraRoll
layout: docs
category: APIs
permalink: docs/cameraroll.html
next: clipboard
previous: backhandler
---
`CameraRoll` provides access to the local camera roll / gallery.
Before using this you must link the `RCTCameraRoll` library.
You can refer to [Linking](docs/linking-libraries-ios.html) for help.
### Permissions
The user's permission is required in order to access the Camera Roll on devices running iOS 10 or later.
Add the `NSPhotoLibraryUsageDescription` key in your `Info.plist` with a string that describes how your
app will use this data. This key will appear as `Privacy - Photo Library Usage Description` in Xcode.
### Methods
- [`saveToCameraRoll`](docs/cameraroll.html#savetocameraroll)
- [`getPhotos`](docs/cameraroll.html#getphotos)
---
# Reference
## Methods
### `saveToCameraRoll()`
```javascript
CameraRoll.saveToCameraRoll(tag, type?)
```
Saves the photo or video to the camera roll / gallery.
On Android, the tag must be a local image or video URI, such as `"file:///sdcard/img.png"`.
On iOS, the tag can be any image URI (including local, remote asset-library and base64 data URIs)
or a local video file URI (remote or data URIs are not supported for saving video at this time).
If the tag has a file extension of .mov or .mp4, it will be inferred as a video. Otherwise
it will be treated as a photo. To override the automatic choice, you can pass an optional
`type` parameter that must be one of 'photo' or 'video'.
Returns a Promise which will resolve with the new URI.
---
### `getPhotos()`
```javascript
CameraRoll.getPhotos(params)
```
Returns a Promise with photo identifier objects from the local camera
roll of the device matching shape defined by `getPhotosReturnChecker`.
Expects a params object of the following shape:
- `first` : {number} : The number of photos wanted in reverse order of the photo application (i.e. most recent first for SavedPhotos).
- `after` : {string} : A cursor that matches `page_info { end_cursor }` returned from a previous call to `getPhotos`.
- `groupTypes` : {string} : Specifies which group types to filter the results to. Valid values are:
- `Album`
- `All`
- `Event`
- `Faces`
- `Library`
- `PhotoStream`
- `SavedPhotos` // default
- `groupName` : {string} : Specifies filter on group names, like 'Recent Photos' or custom album titles.
- `assetType` : {string} : Specifies filter on asset type. Valid values are:
- `All`
- `Videos`
- `Photos` // default
- `mimeTypes` : {string} : Filter by mimetype (e.g. image/jpeg).
Returns a Promise which when resolved will be of the following shape:
- `edges` : {Array<node>} An array of node objects
- `node`: {object} An object with the following shape:
- `type`: {string}
- `group_name`: {string}
- `image`: {object} : An object with the following shape:
- `uri`: {string}
- `height`: {number}
- `width`: {number}
- `isStored`: {boolean}
- `timestamp`: {number}
- `location`: {object} : An object with the following shape:
- `latitude`: {number}
- `longitude`: {number}
- `altitude`: {number}
- `heading`: {number}
- `speed`: {number}
- `page_info` : {object} : An object with the following shape:
- `has_next_page`: {boolean}
- `start_cursor`: {boolean}
- `end_cursor`: {boolean}
Loading images:
```
_handleButtonPress = () => {
CameraRoll.getPhotos({
first: 20,
assetType: 'All',
})
.then(r => {
this.setState({ photos: r.edges });
})
.catch((err) => {
//Error Loading Images
});
};
render() {
return (
<View>
<Button title="Load Images" onPress={this._handleButtonPress} />
<ScrollView>
{this.state.photos.map((p, i) => {
return (
<Image
key={i}
style={{
width: 300,
height: 100,
}}
source={{ uri: p.node.image.uri }}
/>
);
})}
</ScrollView>
</View>
);
}
```

View File

@ -1,106 +0,0 @@
---
id: checkbox
title: CheckBox
layout: docs
category: components
permalink: docs/checkbox.html
next: datepickerios
previous: button
---
Renders a boolean input (Android only).
This is a controlled component that requires an `onValueChange` callback that
updates the `value` prop in order for the component to reflect user actions.
If the `value` prop is not updated, the component will continue to render
the supplied `value` prop instead of the expected result of any user actions.
@keyword checkbox
@keyword toggle
### Props
- [View props...](docs/view.html#props)
- [`disabled`](docs/checkbox.html#disabled)
- [`onChange`](docs/checkbox.html#onchange)
- [`onValueChange`](docs/checkbox.html#onvaluechange)
- [`testID`](docs/checkbox.html#testid)
- [`value`](docs/checkbox.html#value)
---
# Reference
## Props
### `disabled`
If true the user won't be able to toggle the checkbox.
Default value is false.
| Type | Required |
| - | - |
| bool | No |
---
### `onChange`
Used in case the props change removes the component.
| Type | Required |
| - | - |
| function | No |
---
### `onValueChange`
Invoked with the new value when the value changes.
| Type | Required |
| - | - |
| function | No |
---
### `testID`
Used to locate this view in end-to-end tests.
| Type | Required |
| - | - |
| string | No |
---
### `value`
The value of the checkbox. If true the checkbox will be turned on.
Default value is false.
| Type | Required |
| - | - |
| bool | No |

View File

@ -1,70 +0,0 @@
---
id: clipboard
title: Clipboard
layout: docs
category: APIs
permalink: docs/clipboard.html
next: datepickerandroid
previous: cameraroll
---
`Clipboard` gives you an interface for setting and getting content from Clipboard on both iOS and Android
### Methods
- [`getString`](docs/clipboard.html#getstring)
- [`setString`](docs/clipboard.html#setstring)
---
# Reference
## Methods
### `getString()`
```javascript
Clipboard.getString()
```
Get content of string type, this method returns a `Promise`, so you can use following code to get clipboard content
```javascript
async _getContent() {
var content = await Clipboard.getString();
}
```
---
### `setString()`
```javascript
Clipboard.setString(content)
```
Set content of string type. You can use following code to set clipboard content:
```javascript
_setContent() {
Clipboard.setString('hello world');
}
```
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| content | string | yes | The content to be stored in the clipboard. |

View File

@ -1,125 +0,0 @@
---
id: communication-android
title: Communication between native and React Native
layout: docs
category: Guides (Android)
permalink: docs/communication-android.html
banner: ejected
next: contributing
previous: android-building-from-source
---
In [Integrating with Existing Apps guide](docs/integration-with-existing-apps.html) and [Native UI Components guide](docs/native-components-android.html) we learn how to embed React Native in a native component and vice versa. When we mix native and React Native components, we'll eventually find a need to communicate between these two worlds. Some ways to achieve that have been already mentioned in other guides. This article summarizes available techniques.
## Introduction
React Native is inspired by React, so the basic idea of the information flow is similar. The flow in React is one-directional. We maintain a hierarchy of components, in which each component depends only on its parent and its own internal state. We do this with properties: data is passed from a parent to its children in a top-down manner. If an ancestor component relies on the state of its descendant, one should pass down a callback to be used by the descendant to update the ancestor.
The same concept applies to React Native. As long as we are building our application purely within the framework, we can drive our app with properties and callbacks. But, when we mix React Native and native components, we need some special, cross-language mechanisms that would allow us to pass information between them.
## Properties
Properties are the simplest way of cross-component communication. So we need a way to pass properties both from native to React Native, and from React Native to native.
### Passing properties from native to React Native
You can pass properties down to the React Native app by providing a custom implementation of `ReactActivityDelegate` in your main activity. This implementation should override `getLaunchOptions` to return a `Bundle` with the desired properties.
```
public class MainActivity extends ReactActivity {
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected Bundle getLaunchOptions() {
Bundle initialProperties = new Bundle();
ArrayList<String> imageList = new ArrayList<String>(Arrays.asList(
"http://foo.com/bar1.png",
"http://foo.com/bar2.png"
));
initialProperties.putStringArrayList("images", imageList);
return initialProperties;
}
};
}
}
```
```
import React from 'react';
import {
AppRegistry,
View,
Image
} from 'react-native';
class ImageBrowserApp extends React.Component {
renderImage(imgURI) {
return (
<Image source={{uri: imgURI}} />
);
}
render() {
return (
<View>
{this.props.images.map(this.renderImage)}
</View>
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => ImageBrowserApp);
```
`ReactRootView` provides a read-write property `appProperties`. After `appProperties` is set, the React Native app is re-rendered with new properties. The update is only performed when the new updated properties differ from the previous ones.
```
Bundle updatedProps = mReactRootView.getAppProperties();
ArrayList<String> imageList = new ArrayList<String>(Arrays.asList(
"http://foo.com/bar3.png",
"http://foo.com/bar4.png"
));
updatedProps.putStringArrayList("images", imageList);
mReactRootView.setAppProperties(updatedProps);
```
It is fine to update properties anytime. However, updates have to be performed on the main thread. You use the getter on any thread.
There is no way to update only a few properties at a time. We suggest that you build it into your own wrapper instead.
> ***Note:***
> Currently, JS functions `componentWillReceiveProps` and `componentWillUpdateProps` of the top level RN component will not be called after a prop update. However, you can access the new props in `componentWillMount` function.
### Passing properties from React Native to native
The problem exposing properties of native components is covered in detail in [this article](docs/native-components-android.html#3-expose-view-property-setters-using-reactprop-or-reactpropgroup-annotation). In short, properties that are to be reflected in JavaScript needs to be exposed as setter method annotated with `@ReactProp`, then just use them in React Native as if the component was an ordinary React Native component.
### Limits of properties
The main drawback of cross-language properties is that they do not support callbacks, which would allow us to handle bottom-up data bindings. Imagine you have a small RN view that you want to be removed from the native parent view as a result of a JS action. There is no way to do that with props, as the information would need to go bottom-up.
Although we have a flavor of cross-language callbacks ([described here](docs/native-modules-android.html#callbacks)), these callbacks are not always the thing we need. The main problem is that they are not intended to be passed as properties. Rather, this mechanism allows us to trigger a native action from JS, and handle the result of that action in JS.
## Other ways of cross-language interaction (events and native modules)
As stated in the previous chapter, using properties comes with some limitations. Sometimes properties are not enough to drive the logic of our app and we need a solution that gives more flexibility. This chapter covers other communication techniques available in React Native. They can be used for internal communication (between JS and native layers in RN) as well as for external communication (between RN and the 'pure native' part of your app).
React Native enables you to perform cross-language function calls. You can execute custom native code from JS and vice versa. Unfortunately, depending on the side we are working on, we achieve the same goal in different ways. For native - we use events mechanism to schedule an execution of a handler function in JS, while for React Native we directly call methods exported by native modules.
### Calling React Native functions from native (events)
Events are described in detail in [this article](docs/native-components-android.html#events). Note that using events gives us no guarantees about execution time, as the event is handled on a separate thread.
Events are powerful, because they allow us to change React Native components without needing a reference to them. However, there are some pitfalls that you can fall into while using them:
* As events can be sent from anywhere, they can introduce spaghetti-style dependencies into your project.
* Events share namespace, which means that you may encounter some name collisions. Collisions will not be detected statically, which makes them hard to debug.
* If you use several instances of the same React Native component and you want to distinguish them from the perspective of your event, you'll likely need to introduce identifiers and pass them along with events (you can use the native view's `reactTag` as an identifier).
### Calling native functions from React Native (native modules)
Native modules are Java classes that are available in JS. Typically one instance of each module is created per JS bridge. They can export arbitrary functions and constants to React Native. They have been covered in detail in [this article](docs/native-modules-android.html).
> ***Warning***:
> All native modules share the same namespace. Watch out for name collisions when creating new ones.

View File

@ -1,220 +0,0 @@
---
id: communication-ios
title: Communication between native and React Native
layout: docs
category: Guides (iOS)
permalink: docs/communication-ios.html
banner: ejected
next: building-for-apple-tv
previous: linking-libraries-ios
---
In [Integrating with Existing Apps guide](docs/integration-with-existing-apps.html) and [Native UI Components guide](docs/native-components-ios.html) we learn how to embed React Native in a native component and vice versa. When we mix native and React Native components, we'll eventually find a need to communicate between these two worlds. Some ways to achieve that have been already mentioned in other guides. This article summarizes available techniques.
## Introduction
React Native is inspired by React, so the basic idea of the information flow is similar. The flow in React is one-directional. We maintain a hierarchy of components, in which each component depends only on its parent and its own internal state. We do this with properties: data is passed from a parent to its children in a top-down manner. If an ancestor component relies on the state of its descendant, one should pass down a callback to be used by the descendant to update the ancestor.
The same concept applies to React Native. As long as we are building our application purely within the framework, we can drive our app with properties and callbacks. But, when we mix React Native and native components, we need some special, cross-language mechanisms that would allow us to pass information between them.
## Properties
Properties are the simplest way of cross-component communication. So we need a way to pass properties both from native to React Native, and from React Native to native.
### Passing properties from native to React Native
In order to embed a React Native view in a native component, we use `RCTRootView`. `RCTRootView` is a `UIView` that holds a React Native app. It also provides an interface between native side and the hosted app.
`RCTRootView` has an initializer that allows you to pass arbitrary properties down to the React Native app. The `initialProperties` parameter has to be an instance of `NSDictionary`. The dictionary is internally converted into a JSON object that the top-level JS component can reference.
```
NSArray *imageList = @[@"http://foo.com/bar1.png",
@"http://foo.com/bar2.png"];
NSDictionary *props = @{@"images" : imageList};
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"ImageBrowserApp"
initialProperties:props];
```
```
import React from 'react';
import {
AppRegistry,
View,
Image
} from 'react-native';
class ImageBrowserApp extends React.Component {
renderImage(imgURI) {
return (
<Image source={{uri: imgURI}} />
);
}
render() {
return (
<View>
{this.props.images.map(this.renderImage)}
</View>
);
}
}
AppRegistry.registerComponent('AwesomeProject', () => ImageBrowserApp);
```
`RCTRootView` also provides a read-write property `appProperties`. After `appProperties` is set, the React Native app is re-rendered with new properties. The update is only performed when the new updated properties differ from the previous ones.
```
NSArray *imageList = @[@"http://foo.com/bar3.png",
@"http://foo.com/bar4.png"];
rootView.appProperties = @{@"images" : imageList};
```
It is fine to update properties anytime. However, updates have to be performed on the main thread. You use the getter on any thread.
There is no way to update only a few properties at a time. We suggest that you build it into your own wrapper instead.
> ***Note:***
> Currently, JS functions `componentWillReceiveProps` and `componentWillUpdateProps` of the top level RN component will not be called after a prop update. However, you can access the new props in `componentWillMount` function.
### Passing properties from React Native to native
The problem exposing properties of native components is covered in detail in [this article](docs/native-components-ios.html#properties). In short, export properties with `RCT_CUSTOM_VIEW_PROPERTY` macro in your custom native component, then just use them in React Native as if the component was an ordinary React Native component.
### Limits of properties
The main drawback of cross-language properties is that they do not support callbacks, which would allow us to handle bottom-up data bindings. Imagine you have a small RN view that you want to be removed from the native parent view as a result of a JS action. There is no way to do that with props, as the information would need to go bottom-up.
Although we have a flavor of cross-language callbacks ([described here](docs/native-modules-ios.html#callbacks)), these callbacks are not always the thing we need. The main problem is that they are not intended to be passed as properties. Rather, this mechanism allows us to trigger a native action from JS, and handle the result of that action in JS.
## Other ways of cross-language interaction (events and native modules)
As stated in the previous chapter, using properties comes with some limitations. Sometimes properties are not enough to drive the logic of our app and we need a solution that gives more flexibility. This chapter covers other communication techniques available in React Native. They can be used for internal communication (between JS and native layers in RN) as well as for external communication (between RN and the 'pure native' part of your app).
React Native enables you to perform cross-language function calls. You can execute custom native code from JS and vice versa. Unfortunately, depending on the side we are working on, we achieve the same goal in different ways. For native - we use events mechanism to schedule an execution of a handler function in JS, while for React Native we directly call methods exported by native modules.
### Calling React Native functions from native (events)
Events are described in detail in [this article](docs/native-components-ios.html#events). Note that using events gives us no guarantees about execution time, as the event is handled on a separate thread.
Events are powerful, because they allow us to change React Native components without needing a reference to them. However, there are some pitfalls that you can fall into while using them:
* As events can be sent from anywhere, they can introduce spaghetti-style dependencies into your project.
* Events share namespace, which means that you may encounter some name collisions. Collisions will not be detected statically, which makes them hard to debug.
* If you use several instances of the same React Native component and you want to distinguish them from the perspective of your event, you'll likely need to introduce identifiers and pass them along with events (you can use the native view's `reactTag` as an identifier).
The common pattern we use when embedding native in React Native is to make the native component's RCTViewManager a delegate for the views, sending events back to JavaScript via the bridge. This keeps related event calls in one place.
### Calling native functions from React Native (native modules)
Native modules are Objective-C classes that are available in JS. Typically one instance of each module is created per JS bridge. They can export arbitrary functions and constants to React Native. They have been covered in detail in [this article](docs/native-modules-ios.html#content).
The fact that native modules are singletons limits the mechanism in the context of embedding. Let's say we have a React Native component embedded in a native view and we want to update the native, parent view. Using the native module mechanism, we would export a function that not only takes expected arguments, but also an identifier of the parent native view. The identifier would be used to retrieve a reference to the parent view to update. That said, we would need to keep a mapping from identifiers to native views in the module.
Although this solution is complex, it is used in `RCTUIManager`, which is an internal React Native class that manages all React Native views.
Native modules can also be used to expose existing native libraries to JS. The [Geolocation library](https://github.com/facebook/react-native/tree/master/Libraries/Geolocation) is a living example of the idea.
> ***Warning***:
> All native modules share the same namespace. Watch out for name collisions when creating new ones.
## Layout computation flow
When integrating native and React Native, we also need a way to consolidate two different layout systems. This section covers common layout problems and provides a brief description of mechanisms to address them.
### Layout of a native component embedded in React Native
This case is covered in [this article](docs/native-components-ios.html#styles). Basically, as all our native react views are subclasses of `UIView`, most style and size attributes will work like you would expect out of the box.
### Layout of a React Native component embedded in native
#### React Native content with fixed size
The simplest scenario is when we have a React Native app with a fixed size, which is known to the native side. In particular, a full-screen React Native view falls into this case. If we want a smaller root view, we can explicitly set RCTRootView's frame.
For instance, to make an RN app 200 (logical) pixels high, and the hosting view's width wide, we could do:
```
// SomeViewController.m
- (void)viewDidLoad
{
[...]
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:appName
initialProperties:props];
rootView.frame = CGRectMake(0, 0, self.view.width, 200);
[self.view addSubview:rootView];
}
```
When we have a fixed size root view, we need to respect its bounds on the JS side. In other words, we need to ensure that the React Native content can be contained within the fixed-size root view. The easiest way to ensure this is to use flexbox layout. If you use absolute positioning, and React components are visible outside the root view's bounds, you'll get overlap with native views, causing some features to behave unexpectedly. For instance, 'TouchableHighlight' will not highlight your touches outside the root view's bounds.
It's totally fine to update root view's size dynamically by re-setting its frame property. React Native will take care of the content's layout.
#### React Native content with flexible size
In some cases we'd like to render content of initially unknown size. Let's say the size will be defined dynamically in JS. We have two solutions to this problem.
1. You can wrap your React Native view in a `ScrollView` component. This guarantees that your content will always be available and it won't overlap with native views.
2. React Native allows you to determine, in JS, the size of the RN app and provide it to the owner of the hosting `RCTRootView`. The owner is then responsible for re-laying out the subviews and keeping the UI consistent. We achieve this with `RCTRootView`'s flexibility modes.
`RCTRootView` supports 4 different size flexibility modes:
```
// RCTRootView.h
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
RCTRootViewSizeFlexibilityNone = 0,
RCTRootViewSizeFlexibilityWidth,
RCTRootViewSizeFlexibilityHeight,
RCTRootViewSizeFlexibilityWidthAndHeight,
};
```
`RCTRootViewSizeFlexibilityNone` is the default value, which makes a root view's size fixed (but it still can be updated with `setFrame:`). The other three modes allow us to track React Native content's size updates. For instance, setting mode to `RCTRootViewSizeFlexibilityHeight` will cause React Native to measure the content's height and pass that information back to `RCTRootView`'s delegate. An arbitrary action can be performed within the delegate, including setting the root view's frame, so the content fits. The delegate is called only when the size of the content has changed.
> ***Warning:***
> Making a dimension flexible in both JS and native leads to undefined behavior. For example - don't make a top-level React component's width flexible (with `flexbox`) while you're using `RCTRootViewSizeFlexibilityWidth` on the hosting `RCTRootView`.
Let's look at an example.
```
// FlexibleSizeExampleView.m
- (instancetype)initWithFrame:(CGRect)frame
{
[...]
_rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"FlexibilityExampleApp"
initialProperties:@{}];
_rootView.delegate = self;
_rootView.sizeFlexibility = RCTRootViewSizeFlexibilityHeight;
_rootView.frame = CGRectMake(0, 0, self.frame.size.width, 0);
}
#pragma mark - RCTRootViewDelegate
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView
{
CGRect newFrame = rootView.frame;
newFrame.size = rootView.intrinsicContentSize;
rootView.frame = newFrame;
}
```
In the example we have a `FlexibleSizeExampleView` view that holds a root view. We create the root view, initialize it and set the delegate. The delegate will handle size updates. Then, we set the root view's size flexibility to `RCTRootViewSizeFlexibilityHeight`, which means that `rootViewDidChangeIntrinsicSize:` method will be called every time the React Native content changes its height. Finally, we set the root view's width and position. Note that we set there height as well, but it has no effect as we made the height RN-dependent.
You can checkout full source code of the example [here](https://github.com/facebook/react-native/blob/master/RNTester/RNTester/NativeExampleViews/FlexibleSizeExampleView.m).
It's fine to change root view's size flexibility mode dynamically. Changing flexibility mode of a root view will schedule a layout recalculation and the delegate `rootViewDidChangeIntrinsicSize:` method will be called once the content size is known.
> ***Note:*** React Native layout calculation is performed on a special thread, while native UI view updates are done on the main thread. This may cause temporary UI inconsistencies between native and React Native. This is a known problem and our team is working on synchronizing UI updates coming from different sources.
> ***Note:*** React Native does not perform any layout calculations until the root view becomes a subview of some other views. If you want to hide React Native view until its dimensions are known, add the root view as a subview and make it initially hidden (use `UIView`'s `hidden` property). Then change its visibility in the delegate method.

View File

@ -1,235 +0,0 @@
---
id: components-and-apis
title: Components and APIs
layout: docs
category: Guides
permalink: docs/components-and-apis.html
next: platform-specific-code
previous: more-resources
---
React Native provides a number of built-in components. You will find a full list of components and APIs on the sidebar to the left. If you're not sure where to get started, take a look at the following categories:
- [Basic Components](docs/components-and-apis.html#basic-components)
- [User Interface](docs/components-and-apis.html#user-interface)
- [Lists Views](docs/components-and-apis.html#lists-views)
- [iOS-specific](docs/components-and-apis.html#ios-components-and-apis)
- [Android-specific](docs/components-and-apis.html#android-components-and-apis)
- [Others](docs/components-and-apis.html#others)
You're not limited to the components and APIs bundled with React Native. React Native is a community of thousands of developers. If you're looking for a library that does something specific, search the npm registry for packages mentioning [react-native](https://www.npmjs.com/search?q=react-native&page=1&ranking=optimal), or check out [Awesome React Native](http://www.awesome-react-native.com/) for a curated list.
## Basic Components
Most apps will end up using one of these basic components. You'll want to get yourself familiarized with all of these if you're new to React Native.
<div class="component-grid component-grid-border">
<div class="component">
<h3><a href="docs/view.html">View</a></h3>
<p>The most fundamental component for building a UI.</p>
</div>
<div class="component">
<h3><a href="docs/text.html">Text</a></h3>
<p>A component for displaying text.</p>
</div>
<div class="component">
<h3><a href="docs/image.html">Image</a></h3>
<p>A component for displaying images.</p>
</div>
<div class="component">
<h3><a href="docs/textinput.html">TextInput</a></h3>
<p>A component for inputting text into the app via a keyboard.</p>
</div>
<div class="component">
<h3><a href="docs/scrollview.html">ScrollView</a></h3>
<p>Provides a scrolling container that can host multiple components and views.</p>
</div>
<div class="component">
<h3><a href="docs/stylesheet.html">StyleSheet</a></h3>
<p>Provides an abstraction layer similar to CSS stylesheets.</p>
</div>
</div>
## User Interface
Render common user interface controls on any platform using the following components. For platform specific components, keep reading.
<div class="component-grid component-grid-border">
<div class="component">
<h3><a href="docs/button.html">Button</a></h3>
<p>A basic button component for handling touches that should render nicely on any platform.</p>
</div>
<div class="component">
<h3><a href="docs/picker.html">Picker</a></h3>
<p>Renders the native picker component on iOS and Android.</p>
</div>
<div class="component">
<h3><a href="docs/slider.html">Slider</a></h3>
<p>A component used to select a single value from a range of values.</p>
</div>
<div class="component">
<h3><a href="docs/switch.html">Switch</a></h3>
<p>Renders a boolean input.</p>
</div>
</div>
## List Views
Unlike the more generic `ScrollView`, the following list view components only render elements that are currently showing on the screen. This makes them a great choice for displaying long lists of data.
<div class="component-grid component-grid-border">
<div class="component">
<h3><a href="docs/flatlist.html">FlatList</a></h3>
<p>A component for rendering performant scrollable lists.</p>
</div>
<div class="component">
<h3><a href="docs/sectionlist.html">SectionList</a></h3>
<p>Like <code>FlatList</code>, but for sectioned lists.</p>
</div>
</div>
## iOS Components and APIs
Many of the following components provide wrappers for commonly used UIKit classes.
<div class="component-grid component-grid-border">
<div class="component">
<h3><a href="docs/actionsheetios.html">ActionSheetIOS</a></h3>
<p>API to display an iOS action sheet or share sheet.</p>
</div>
<div class="component">
<h3><a href="docs/alertios.html">AlertIOS</a></h3>
<p>Create an iOS alert dialog with a message or create a prompt for user input.</p>
</div>
<div class="component">
<h3><a href="docs/datepickerios.html">DatePickerIOS</a></h3>
<p>Renders a date/time picker (selector) on iOS.</p>
</div>
<div class="component">
<h3><a href="docs/imagepickerios.html">ImagePickerIOS</a></h3>
<p>Renders a image picker on iOS.</p>
</div>
<div class="component">
<h3><a href="docs/navigatorios.html">NavigatorIOS</a></h3>
<p>A wrapper around <code>UINavigationController</code>, enabling you to implement a navigation stack.</p>
</div>
<div class="component">
<h3><a href="docs/progressviewios.html">ProgressViewIOS</a></h3>
<p>Renders a <code>UIProgressView</a></code> on iOS.</p>
</div>
<div class="component">
<h3><a href="docs/pushnotificationios.html">PushNotificationIOS</a></h3>
<p>Handle push notifications for your app, including permission handling and icon badge number.</p>
</div>
<div class="component">
<h3><a href="docs/segmentedcontrolios.html">SegmentedControlIOS</a></h3>
<p>Renders a <code>UISegmentedControl</code> on iOS.</p>
</div>
<div class="component">
<h3><a href="docs/tabbarios.html">TabBarIOS</a></h3>
<p>Renders a <code>UITabViewController</code> on iOS. Use with <a href="docs/tabbarios-item.html">TabBarIOS.Item</a>.</p>
</div>
</div>
## Android Components and APIs
Many of the following components provide wrappers for commonly used Android classes.
<div class="component-grid component-grid-border">
<div class="component">
<h3><a href="docs/backhandler.html">BackHandler</a></h3>
<p>Detect hardware button presses for back navigation.</p>
</div>
<div class="component">
<h3><a href="docs/datepickerandroid.html">DatePickerAndroid</a></h3>
<p>Opens the standard Android date picker dialog.</p>
</div>
<div class="component">
<h3><a href="docs/drawerlayoutandroid.html">DrawerLayoutAndroid</a></h3>
<p>Renders a <code>DrawerLayout</code> on Android.</p>
</div>
<div class="component">
<h3><a href="docs/permissionsandroid.html">PermissionsAndroid</a></h3>
<p>Provides access to the permissions model introduced in Android M.</p>
</div>
<div class="component">
<h3><a href="docs/progressbarandroid.html">ProgressBarAndroid</a></h3>
<p>Renders a <code>ProgressBar</code> on Android.</p>
</div>
<div class="component">
<h3><a href="docs/timepickerandroid.html">TimePickerAndroid</a></h3>
<p>Opens the standard Android time picker dialog.</p>
</div>
<div class="component">
<h3><a href="docs/toastandroid.html">ToastAndroid</a></h3>
<p>Create an Android Toast alert.</p>
</div>
<div class="component">
<h3><a href="docs/toolbarandroid.html">ToolbarAndroid</a></h3>
<p>Renders a <code>Toolbar</code> on Android.</p>
</div>
<div class="component">
<h3><a href="docs/viewpagerandroid.html">ViewPagerAndroid</a></h3>
<p>Container that allows to flip left and right between child views.</p>
</div>
</div>
## Others
These components may come in handy for certain applications. For an exhaustive list of components and APIs, check out the sidebar to the left.
<div class="component-grid">
<div class="component">
<h3><a href="docs/activityindicator.html">ActivityIndicator</a></h3>
<p>Displays a circular loading indicator.</p>
</div>
<div class="component">
<h3><a href="docs/alert.html">Alert</a></h3>
<p>Launches an alert dialog with the specified title and message.</p>
</div>
<div class="component">
<h3><a href="docs/animated.html">Animated</a></h3>
<p>A library for creating fluid, powerful animations that are easy to build and maintain.</p>
</div>
<div class="component">
<h3><a href="docs/cameraroll.html">CameraRoll</a></h3>
<p>Provides access to the local camera roll / gallery.</p>
</div>
<div class="component">
<h3><a href="docs/clipboard.html">Clipboard</a></h3>
<p>Provides an interface for setting and getting content from the clipboard on both iOS and Android.</p>
</div>
<div class="component">
<h3><a href="docs/dimensions.html">Dimensions</a></h3>
<p>Provides an interface for getting device dimensions.</p>
</div>
<div class="component">
<h3><a href="docs/keyboardavoidingview.html">KeyboardAvoidingView</a></h3>
<p>Provides a view that moves out of the way of the virtual keyboard automatically.</p>
</div>
<div class="component">
<h3><a href="docs/linking.html">Linking</a></h3>
<p>Provides a general interface to interact with both incoming and outgoing app links.</p>
</div>
<div class="component">
<h3><a href="docs/modal.html">Modal</a></h3>
<p>Provides a simple way to present content above an enclosing view.</p>
</div>
<div class="component">
<h3><a href="docs/pixelratio.html">PixelRatio</a></h3>
<p>Provides access to the device pixel density.</p>
</div>
<div class="component">
<h3><a href="docs/refreshcontrol.html">RefreshControl</a></h3>
<p>This component is used inside a <code>ScrollView</code> to add pull to refresh functionality.</p>
</div>
<div class="component">
<h3><a href="docs/statusbar.html">StatusBar</a></h3>
<p>Component to control the app status bar.</p>
</div>
<div class="component">
<h3><a href="docs/webview.html">WebView</a></h3>
<p>A component that renders web content in a native view.</p>
</div>
</div>

View File

@ -1,267 +0,0 @@
---
id: custom-webview-android
title: Custom WebView
layout: docs
category: Guides (Android)
permalink: docs/custom-webview-android.html
banner: ejected
next: headless-js-android
previous: native-components-android
---
While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code.
Before you do this, you should be familiar with the concepts in [native UI components](native-components-android). You should also familiarise yourself with the [native code for web views](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java), as you will have to use this as a reference when implementing new features—although a deep understanding is not required.
## Native Code
To get started, you'll need to create a subclass of `ReactWebViewManager`, `ReactWebView`, and `ReactWebViewClient`. In your view manager, you'll then need to override:
* `createReactWebViewInstance`
* `getName`
* `addEventEmitters`
```java
@ReactModule(name = CustomWebViewManager.REACT_CLASS)
public class CustomWebViewManager extends ReactWebViewManager {
/* This name must match what we're referring to in JS */
protected static final String REACT_CLASS = "RCTCustomWebView";
protected static class CustomWebViewClient extends ReactWebViewClient { }
protected static class CustomWebView extends ReactWebView {
public CustomWebView(ThemedReactContext reactContext) {
super(reactContext);
}
}
@Override
protected ReactWebView createReactWebViewInstance(ThemedReactContext reactContext) {
return new CustomWebView(reactContext);
}
@Override
public String getName() {
return REACT_CLASS;
}
@Override
protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
view.setWebViewClient(new CustomWebViewClient());
}
}
```
You'll need to follow the usual steps to [register the module](docs/native-modules-android.html#register-the-module).
### Adding New Properties
To add a new property, you'll need to add it to `CustomWebView`, and then expose it in `CustomWebViewManager`.
```java
public class CustomWebViewManager extends ReactWebViewManager {
...
protected static class CustomWebView extends ReactWebView {
public CustomWebView(ThemedReactContext reactContext) {
super(reactContext);
}
protected @Nullable String mFinalUrl;
public void setFinalUrl(String url) {
mFinalUrl = url;
}
public String getFinalUrl() {
return mFinalUrl;
}
}
...
@ReactProp(name = "finalUrl")
public void setFinalUrl(WebView view, String url) {
((CustomWebView) view).setFinalUrl(url);
}
}
```
### Adding New Events
For events, you'll first need to make create event subclass.
```java
// NavigationCompletedEvent.java
public class NavigationCompletedEvent extends Event<NavigationCompletedEvent> {
private WritableMap mParams;
public NavigationCompletedEvent(int viewTag, WritableMap params) {
super(viewTag);
this.mParams = params;
}
@Override
public String getEventName() {
return "navigationCompleted";
}
@Override
public void dispatch(RCTEventEmitter rctEventEmitter) {
init(getViewTag());
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams);
}
}
```
You can trigger the event in your web view client. You can hook existing handlers if your events are based on them.
You should refer to [ReactWebViewManager.java](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java) in the React Native codebase to see what handlers are available and how they are implemented. You can extend any methods here to provide extra functionality.
```java
public class NavigationCompletedEvent extends Event<NavigationCompletedEvent> {
private WritableMap mParams;
public NavigationCompletedEvent(int viewTag, WritableMap params) {
super(viewTag);
this.mParams = params;
}
@Override
public String getEventName() {
return "navigationCompleted";
}
@Override
public void dispatch(RCTEventEmitter rctEventEmitter) {
init(getViewTag());
rctEventEmitter.receiveEvent(getViewTag(), getEventName(), mParams);
}
}
// CustomWebViewManager.java
protected static class CustomWebViewClient extends ReactWebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
boolean shouldOverride = super.shouldOverrideUrlLoading(view, url);
String finalUrl = ((CustomWebView) view).getFinalUrl();
if (!shouldOverride && url != null && finalUrl != null && new String(url).equals(finalUrl)) {
final WritableMap params = Arguments.createMap();
dispatchEvent(view, new NavigationCompletedEvent(view.getId(), params));
}
return shouldOverride;
}
}
```
Finally, you'll need to expose the events in `CustomWebViewManager` through `getExportedCustomDirectEventTypeConstants`. Note that currently, the default implementation returns `null`, but this may change in the future.
```java
public class CustomWebViewManager extends ReactWebViewManager {
...
@Override
public @Nullable
Map getExportedCustomDirectEventTypeConstants() {
Map<String, Object> export = super.getExportedCustomDirectEventTypeConstants();
if (export == null) {
export = MapBuilder.newHashMap();
}
export.put("navigationCompleted", MapBuilder.of("registrationName", "onNavigationCompleted"));
return export;
}
}
```
## JavaScript Interface
To use your custom web view, you'll need to create a class for it. Your class must:
* Export all the prop types from `WebView.propTypes`
* Return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below)
To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. However, you must pass in an extra third argument, `WebView.extraNativeComponentConfig`. This third argument contains prop types that are only required for native code.
```js
import React, { Component, PropTypes } from 'react';
import { WebView, requireNativeComponent } from 'react-native';
export default class CustomWebView extends Component {
static propTypes = WebView.propTypes
render() {
return (
<WebView
{...this.props}
nativeConfig={{ component: RCTCustomWebView }}
/>
);
}
}
const RCTCustomWebView = requireNativeComponent(
'RCTCustomWebView',
CustomWebView,
WebView.extraNativeComponentConfig
);
```
If you want to add custom props to your native component, you can use `nativeConfig.props` on the web view.
For events, the event handler must always be set to a function. This means it isn't safe to use the event handler directly from `this.props`, as the user might not have provided one. The standard approach is to create a event handler in your class, and then invoking the event handler given in `this.props` if it exists.
If you are unsure how something should be implemented from the JS side, look at [WebView.android.js](https://github.com/facebook/react-native/blob/master/Libraries/Components/WebView/WebView.android.js) in the React Native source.
```javascript
export default class CustomWebView extends Component {
static propTypes = {
...WebView.propTypes,
finalUrl: PropTypes.string,
onNavigationCompleted: PropTypes.func,
};
static defaultProps = {
finalUrl: 'about:blank',
};
_onNavigationCompleted = (event) => {
const { onNavigationCompleted } = this.props;
onNavigationCompleted && onNavigationCompleted(event);
}
render() {
return (
<WebView
{...this.props}
nativeConfig={{
component: RCTCustomWebView,
props: {
finalUrl: this.props.finalUrl,
onNavigationCompleted: this._onNavigationCompleted,
}
}}
/>
);
}
}
```
Just like for regular native components, you must provide all your prop types in the component to have them forwarded on to the native component. However, if you have some prop types that are only used internally in component, you can add them to the `nativeOnly` property of the third argument previously mentioned. For event handlers, you have to use the value `true` instead of a regular prop type.
For example, if you wanted to add an internal event handler called `onScrollToBottom`, you would use,
```js
const RCTCustomWebView = requireNativeComponent(
'RCTCustomWebView',
CustomWebView,
{
...WebView.extraNativeComponentConfig,
nativeOnly: {
...WebView.extraNativeComponentConfig.nativeOnly,
onScrollToBottom: true,
},
}
);
```

View File

@ -1,240 +0,0 @@
---
id: custom-webview-ios
title: Custom WebView
layout: docs
category: Guides (iOS)
permalink: docs/custom-webview-ios.html
banner: ejected
next: linking-libraries-ios
previous: native-components-ios
---
While the built-in web view has a lot of features, it is not possible to handle every use-case in React Native. You can, however, extend the web view with native code without forking React Native or duplicating all the existing web view code.
Before you do this, you should be familiar with the concepts in [native UI components](native-components-ios). You should also familiarise yourself with the [native code for web views](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebViewManager.m), as you will have to use this as a reference when implementing new features—although a deep understanding is not required.
## Native Code
Like for regular native components, you need a view manager and an web view.
For the view, you'll need to make a subclass of `RCTWebView`.
```objc
// RCTCustomWebView.h
#import <React/RCTWebView.h>
@interface RCTCustomWebView : RCTWebView
@end
// RCTCustomWebView.m
#import "RCTCustomWebView.h"
@interface RCTCustomWebView ()
@end
@implementation RCTCustomWebView { }
@end
```
For the view manager, you need to make a subclass `RCTWebViewManager`. You must still include:
* `(UIView *)view` that returns your custom view
* The `RCT_EXPORT_MODULE()` tag
```objc
// RCTCustomWebViewManager.h
#import <React/RCTWebViewManager.h>
@interface RCTCustomWebViewManager : RCTWebViewManager
@end
// RCTCustomWebViewManager.m
#import "RCTCustomWebViewManager.h"
#import "RCTCustomWebView.h"
@interface RCTCustomWebViewManager () <RCTWebViewDelegate>
@end
@implementation RCTCustomWebViewManager { }
RCT_EXPORT_MODULE()
- (UIView *)view
{
RCTCustomWebView *webView = [RCTCustomWebView new];
webView.delegate = self;
return webView;
}
@end
```
### Adding New Events and Properties
Adding new properties and events is the same as regular UI components. For properties, you define an `@property` in the header. For events, you define a `RCTDirectEventBlock` in the view's `@interface`.
```objc
// RCTCustomWebView.h
@property (nonatomic, copy) NSString *finalUrl;
// RCTCustomWebView.m
@interface RCTCustomWebView ()
@property (nonatomic, copy) RCTDirectEventBlock onNavigationCompleted;
@end
```
Then expose it in the view manager's `@implementation`.
```objc
// RCTCustomWebViewManager.m
RCT_EXPORT_VIEW_PROPERTY(onNavigationCompleted, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(finalUrl, NSString)
```
### Extending Existing Events
You should refer to [RCTWebView.m](https://github.com/facebook/react-native/blob/master/React/Views/RCTWebView.m) in the React Native codebase to see what handlers are available and how they are implemented. You can extend any methods here to provide extra functionality.
By default, most methods aren't exposed from RCTWebView. If you need to expose them, you need to create an [Objective C category](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html), and then expose all the methods you need to use.
```objc
// RCTWebView+Custom.h
#import <React/RCTWebView.h>
@interface RCTWebView (Custom)
- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
- (NSMutableDictionary<NSString *, id> *)baseEvent;
@end
```
Once these are exposed, you can reference them in your custom web view class.
```objc
// RCTCustomWebView.m
// Remember to import the category file.
#import "RCTWebView+Custom.h"
- (BOOL)webView:(__unused UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
BOOL allowed = [super webView:webView shouldStartLoadWithRequest:request navigationType:navigationType];
if (allowed) {
NSString* url = request.URL.absoluteString;
if (url && [url isEqualToString:_finalUrl]) {
if (_onNavigationCompleted) {
NSMutableDictionary<NSString *, id> *event = [self baseEvent];
_onNavigationCompleted(event);
}
}
}
return allowed;
}
```
## JavaScript Interface
To use your custom web view, you'll need to create a class for it. Your class must:
* Export all the prop types from `WebView.propTypes`
* Return a `WebView` component with the prop `nativeConfig.component` set to your native component (see below)
To get your native component, you must use `requireNativeComponent`: the same as for regular custom components. However, you must pass in an extra third argument, `WebView.extraNativeComponentConfig`. This third argument contains prop types that are only required for native code.
```js
import React, { Component, PropTypes } from 'react';
import { WebView, requireNativeComponent, NativeModules } from 'react-native';
const { CustomWebViewManager } = NativeModules;
export default class CustomWebView extends Component {
static propTypes = WebView.propTypes
render() {
return (
<WebView
{...this.props}
nativeConfig={{
component: RCTCustomWebView,
viewManager: CustomWebViewManager
}}
/>
);
}
}
const RCTCustomWebView = requireNativeComponent(
'RCTCustomWebView',
CustomWebView,
WebView.extraNativeComponentConfig
);
```
If you want to add custom props to your native component, you can use `nativeConfig.props` on the web view. For iOS, you should also set the `nativeConfig.viewManager` prop with your custom WebView ViewManager as in the example above.
For events, the event handler must always be set to a function. This means it isn't safe to use the event handler directly from `this.props`, as the user might not have provided one. The standard approach is to create a event handler in your class, and then invoking the event handler given in `this.props` if it exists.
If you are unsure how something should be implemented from the JS side, look at [WebView.ios.js](https://github.com/facebook/react-native/blob/master/Libraries/Components/WebView/WebView.ios.js) in the React Native source.
```js
export default class CustomWebView extends Component {
static propTypes = {
...WebView.propTypes,
finalUrl: PropTypes.string,
onNavigationCompleted: PropTypes.func,
};
static defaultProps = {
finalUrl: 'about:blank',
};
_onNavigationCompleted = (event) => {
const { onNavigationCompleted } = this.props;
onNavigationCompleted && onNavigationCompleted(event);
}
render() {
return (
<WebView
{...this.props}
nativeConfig={{
component: RCTCustomWebView,
props: {
finalUrl: this.props.finalUrl,
onNavigationCompleted: this._onNavigationCompleted,
},
viewManager: CustomWebViewManager
}}
/>
);
}
}
```
Just like for regular native components, you must provide all your prop types in the component to have them forwarded on to the native component. However, if you have some prop types that are only used internally in component, you can add them to the `nativeOnly` property of the third argument previously mentioned. For event handlers, you have to use the value `true` instead of a regular prop type.
For example, if you wanted to add an internal event handler called `onScrollToBottom`, you would use,
```js
const RCTCustomWebView = requireNativeComponent(
'RCTCustomWebView',
CustomWebView,
{
...WebView.extraNativeComponentConfig,
nativeOnly: {
...WebView.extraNativeComponentConfig.nativeOnly,
onScrollToBottom: true,
},
}
);
```

View File

@ -1,103 +0,0 @@
---
id: datepickerandroid
title: DatePickerAndroid
layout: docs
category: APIs
permalink: docs/datepickerandroid.html
next: dimensions
previous: clipboard
---
Opens the standard Android date picker dialog.
### Example
```
try {
const {action, year, month, day} = await DatePickerAndroid.open({
// Use `new Date()` for current date.
// May 25 2020. Month 0 is January.
date: new Date(2020, 4, 25)
});
if (action !== DatePickerAndroid.dismissedAction) {
// Selected year, month (0-11), day
}
} catch ({code, message}) {
console.warn('Cannot open date picker', message);
}
```
### Methods
- [`open`](docs/datepickerandroid.html#open)
- [`dateSetAction`](docs/datepickerandroid.html#datesetaction)
- [`dismissedAction`](docs/datepickerandroid.html#dismissedaction)
---
# Reference
## Methods
### `open()`
```javascript
DatePickerAndroid.open(options)
```
Opens the standard Android date picker dialog.
The available keys for the `options` object are:
- `date` (`Date` object or timestamp in milliseconds) - date to show by default
- `minDate` (`Date` or timestamp in milliseconds) - minimum date that can be selected
- `maxDate` (`Date` object or timestamp in milliseconds) - maximum date that can be selected
- `mode` (`enum('calendar', 'spinner', 'default')`) - To set the date-picker mode to calendar/spinner/default
- 'calendar': Show a date picker in calendar mode.
- 'spinner': Show a date picker in spinner mode.
- 'default': Show a default native date picker(spinner/calendar) based on android versions.
Returns a Promise which will be invoked an object containing `action`, `year`, `month` (0-11),
`day` if the user picked a date. If the user dismissed the dialog, the Promise will
still be resolved with action being `DatePickerAndroid.dismissedAction` and all the other keys
being undefined. **Always** check whether the `action` before reading the values.
Note the native date picker dialog has some UI glitches on Android 4 and lower
when using the `minDate` and `maxDate` options.
---
### `dateSetAction()`
```javascript
DatePickerAndroid.dateSetAction()
```
A date has been selected.
---
### `dismissedAction()`
```javascript
DatePickerAndroid.dismissedAction()
```
The dialog has been dismissed.

View File

@ -1,140 +0,0 @@
---
id: datepickerios
title: DatePickerIOS
layout: docs
category: components
permalink: docs/datepickerios.html
next: drawerlayoutandroid
previous: checkbox
---
Use `DatePickerIOS` to render a date/time picker (selector) on iOS. This is
a controlled component, so you must hook in to the `onDateChange` callback
and update the `date` prop in order for the component to update, otherwise
the user's change will be reverted immediately to reflect `props.date` as the
source of truth.
### Props
- [View props...](docs/view.html#props)
- [`date`](docs/datepickerios.html#date)
- [`onDateChange`](docs/datepickerios.html#ondatechange)
- [`maximumDate`](docs/datepickerios.html#maximumdate)
- [`minimumDate`](docs/datepickerios.html#minimumdate)
- [`minuteInterval`](docs/datepickerios.html#minuteinterval)
- [`mode`](docs/datepickerios.html#mode)
- [`timeZoneOffsetInMinutes`](docs/datepickerios.html#timezoneoffsetinminutes)
---
# Reference
## Props
### `date`
The currently selected date.
| Type | Required |
| - | - |
| Date | Yes |
---
### `onDateChange`
Date change handler.
This is called when the user changes the date or time in the UI.
The first and only argument is a Date object representing the new
date and time.
| Type | Required |
| - | - |
| function | Yes |
---
### `maximumDate`
Maximum date.
Restricts the range of possible date/time values.
| Type | Required |
| - | - |
| Date | No |
---
### `minimumDate`
Minimum date.
Restricts the range of possible date/time values.
| Type | Required |
| - | - |
| Date | No |
---
### `minuteInterval`
The interval at which minutes can be selected.
| Type | Required |
| - | - |
| enum(1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30) | No |
---
### `mode`
The date picker mode.
| Type | Required |
| - | - |
| enum('date', 'time', 'datetime') | No |
---
### `timeZoneOffsetInMinutes`
Timezone offset in minutes.
By default, the date picker will use the device's timezone. With this
parameter, it is possible to force a certain timezone offset. For
instance, to show times in Pacific Standard Time, pass -7 * 60.
| Type | Required |
| - | - |
| number | No |

View File

@ -1,107 +0,0 @@
---
id: dimensions
title: Dimensions
layout: docs
category: APIs
permalink: docs/dimensions.html
next: easing
previous: datepickerandroid
---
### Methods
- [`set`](docs/dimensions.html#set)
- [`get`](docs/dimensions.html#get)
- [`addEventListener`](docs/dimensions.html#addeventlistener)
- [`removeEventListener`](docs/dimensions.html#removeeventlistener)
---
# Reference
## Methods
### `set()`
```javascript
Dimensions.set(dims)
```
This should only be called from native code by sending the
didUpdateDimensions event.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| dims | object | Yes | Simple string-keyed object of dimensions to set |
---
### `get()`
```javascript
Dimensions.get(dim)
```
Initial dimensions are set before `runApplication` is called so they should
be available before any other require's are run, but may be updated later.
> Note:
> Although dimensions are available immediately, they may change (e.g due to device rotation) so any rendering logic or styles that depend on these constants should try to call this function on every render, rather than caching the value (for example, using inline styles rather than setting a value in a `StyleSheet`).
Example: `var {height, width} = Dimensions.get('window');`
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| dim | string | Yes | Name of dimension as defined when calling `set`. |
---
### `addEventListener()`
```javascript
Dimensions.addEventListener(type, handler)
```
Add an event handler. Supported events:
- `change`: Fires when a property within the `Dimensions` object changes. The argument
to the event handler is an object with `window` and `screen` properties whose values
are the same as the return values of `Dimensions.get('window')` and
`Dimensions.get('screen')`, respectively.
---
### `removeEventListener()`
```javascript
Dimensions.removeEventListener(type, handler)
```
Remove an event handler.

View File

@ -1,269 +0,0 @@
---
id: direct-manipulation
title: Direct Manipulation
layout: docs
category: Guides
permalink: docs/direct-manipulation.html
next: colors
previous: javascript-environment
---
It is sometimes necessary to make changes directly to a component
without using state/props to trigger a re-render of the entire subtree.
When using React in the browser for example, you sometimes need to
directly modify a DOM node, and the same is true for views in mobile
apps. `setNativeProps` is the React Native equivalent to setting
properties directly on a DOM node.
> Use setNativeProps when frequent re-rendering creates a performance bottleneck
>
> Direct manipulation will not be a tool that you reach for
> frequently; you will typically only be using it for creating
> continuous animations to avoid the overhead of rendering the component
> hierarchy and reconciling many views. `setNativeProps` is imperative
> and stores state in the native layer (DOM, UIView, etc.) and not
> within your React components, which makes your code more difficult to
> reason about. Before you use it, try to solve your problem with `setState`
> and [shouldComponentUpdate](http://facebook.github.io/react/docs/advanced-performance.html#shouldcomponentupdate-in-action).
## setNativeProps with TouchableOpacity
[TouchableOpacity](https://github.com/facebook/react-native/blob/master/Libraries/Components/Touchable/TouchableOpacity.js)
uses `setNativeProps` internally to update the opacity of its child
component:
```javascript
setOpacityTo(value) {
// Redacted: animation related code
this.refs[CHILD_REF].setNativeProps({
opacity: value
});
},
```
This allows us to write the following code and know that the child will
have its opacity updated in response to taps, without the child having
any knowledge of that fact or requiring any changes to its implementation:
```javascript
<TouchableOpacity onPress={this._handlePress}>
<View style={styles.button}>
<Text>Press me!</Text>
</View>
</TouchableOpacity>
```
Let's imagine that `setNativeProps` was not available. One way that we
might implement it with that constraint is to store the opacity value
in the state, then update that value whenever `onPress` is fired:
```javascript
constructor(props) {
super(props);
this.state = { myButtonOpacity: 1, };
}
render() {
return (
<TouchableOpacity onPress={() => this.setState({myButtonOpacity: 0.5})}
onPressOut={() => this.setState({myButtonOpacity: 1})}>
<View style={[styles.button, {opacity: this.state.myButtonOpacity}]}>
<Text>Press me!</Text>
</View>
</TouchableOpacity>
)
}
```
This is computationally intensive compared to the original example -
React needs to re-render the component hierarchy each time the opacity
changes, even though other properties of the view and its children
haven't changed. Usually this overhead isn't a concern but when
performing continuous animations and responding to gestures, judiciously
optimizing your components can improve your animations' fidelity.
If you look at the implementation of `setNativeProps` in
[NativeMethodsMixin.js](https://github.com/facebook/react/blob/master/src/renderers/native/NativeMethodsMixin.js)
you will notice that it is a wrapper around `RCTUIManager.updateView` -
this is the exact same function call that results from re-rendering -
see [receiveComponent in
ReactNativeBaseComponent.js](https://github.com/facebook/react/blob/master/src/renderers/native/ReactNativeBaseComponent.js).
## Composite components and setNativeProps
Composite components are not backed by a native view, so you cannot call
`setNativeProps` on them. Consider this example:
```SnackPlayer?name=setNativeProps%20with%20Composite%20Components
import React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
class MyButton extends React.Component {
render() {
return (
<View>
<Text>{this.props.label}</Text>
</View>
)
}
}
export default class App extends React.Component {
render() {
return (
<TouchableOpacity>
<MyButton label="Press me!" />
</TouchableOpacity>
)
}
}
```
If you run this you will immediately see this error: `Touchable child
must either be native or forward setNativeProps to a native component`.
This occurs because `MyButton` isn't directly backed by a native view
whose opacity should be set. You can think about it like this: if you
define a component with `createReactClass` you would not expect to be
able to set a style prop on it and have that work - you would need to
pass the style prop down to a child, unless you are wrapping a native
component. Similarly, we are going to forward `setNativeProps` to a
native-backed child component.
#### Forward setNativeProps to a child
All we need to do is provide a `setNativeProps` method on our component
that calls `setNativeProps` on the appropriate child with the given
arguments.
```SnackPlayer?name=Forwarding%20setNativeProps
import React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
class MyButton extends React.Component {
setNativeProps = (nativeProps) => {
this._root.setNativeProps(nativeProps);
}
render() {
return (
<View ref={component => this._root = component} {...this.props}>
<Text>{this.props.label}</Text>
</View>
)
}
}
export default class App extends React.Component {
render() {
return (
<TouchableOpacity>
<MyButton label="Press me!" />
</TouchableOpacity>
)
}
}
```
You can now use `MyButton` inside of `TouchableOpacity`! A sidenote for
clarity: we used the [ref callback](https://facebook.github.io/react/docs/more-about-refs.html#the-ref-callback-attribute) syntax here, rather than the traditional string-based ref.
You may have noticed that we passed all of the props down to the child
view using `{...this.props}`. The reason for this is that
`TouchableOpacity` is actually a composite component, and so in addition
to depending on `setNativeProps` on its child, it also requires that the
child perform touch handling. To do this, it passes on [various
props](docs/view.html#onmoveshouldsetresponder)
that call back to the `TouchableOpacity` component.
`TouchableHighlight`, in contrast, is backed by a native view and only
requires that we implement `setNativeProps`.
## setNativeProps to clear TextInput value
Another very common use case of `setNativeProps` is to clear the value
of a TextInput. The `controlled` prop of TextInput can sometimes drop
characters when the `bufferDelay` is low and the user types very
quickly. Some developers prefer to skip this prop entirely and instead
use `setNativeProps` to directly manipulate the TextInput value when
necessary. For example, the following code demonstrates clearing the
input when you tap a button:
```SnackPlayer?name=Clear%20text
import React from 'react';
import { TextInput, Text, TouchableOpacity, View } from 'react-native';
export default class App extends React.Component {
clearText = () => {
this._textInput.setNativeProps({text: ''});
}
render() {
return (
<View style={{flex: 1}}>
<TextInput
ref={component => this._textInput = component}
style={{height: 50, flex: 1, marginHorizontal: 20, borderWidth: 1, borderColor: '#ccc'}}
/>
<TouchableOpacity onPress={this.clearText}>
<Text>Clear text</Text>
</TouchableOpacity>
</View>
);
}
}
```
## Avoiding conflicts with the render function
If you update a property that is also managed by the render function,
you might end up with some unpredictable and confusing bugs because
anytime the component re-renders and that property changes, whatever
value was previously set from `setNativeProps` will be completely
ignored and overridden.
## setNativeProps & shouldComponentUpdate
By [intelligently applying
`shouldComponentUpdate`](https://facebook.github.io/react/docs/advanced-performance.html#avoiding-reconciling-the-dom)
you can avoid the unnecessary overhead involved in reconciling unchanged
component subtrees, to the point where it may be performant enough to
use `setState` instead of `setNativeProps`.
## Other native methods
The methods described here are available on most of the default components provided by React Native. Note, however, that they are *not* available on composite components that aren't directly backed by a native view. This will generally include most components that you define in your own app.
### measure(callback)
Determines the location on screen, width, and height of the given view and returns the values via an async callback. If successful, the callback will be called with the following arguments:
* x
* y
* width
* height
* pageX
* pageY
Note that these measurements are not available until after the rendering has been completed in native. If you need the measurements as soon as possible, consider using the [`onLayout` prop](docs/view.html#onlayout) instead.
### measureInWindow(callback)
Determines the location of the given view in the window and returns the values via an async callback. If the React root view is embedded in another native view, this will give you the absolute coordinates. If successful, the callback will be called with the following arguments:
* x
* y
* width
* height
### measureLayout(relativeToNativeNode, onSuccess, onFail)
Like `measure()`, but measures the view relative an ancestor, specified as `relativeToNativeNode`. This means that the returned x, y are relative to the origin x, y of the ancestor view.
As always, to obtain a native node handle for a component, you can use `ReactNative.findNodeHandle(component)`.
### focus()
Requests focus for the given input or view. The exact behavior triggered will depend on the platform and type of view.
### blur()
Removes focus from an input or view. This is the opposite of `focus()`.

View File

@ -1,259 +0,0 @@
---
id: drawerlayoutandroid
title: DrawerLayoutAndroid
layout: docs
category: components
permalink: docs/drawerlayoutandroid.html
next: flatlist
previous: datepickerios
---
React component that wraps the platform `DrawerLayout` (Android only). The
Drawer (typically used for navigation) is rendered with `renderNavigationView`
and direct children are the main view (where your content goes). The navigation
view is initially not visible on the screen, but can be pulled in from the
side of the window specified by the `drawerPosition` prop and its width can
be set by the `drawerWidth` prop.
Example:
```
render: function() {
var navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
</View>
);
return (
<DrawerLayoutAndroid
drawerWidth={300}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
</View>
</DrawerLayoutAndroid>
);
},
```
### Props
- [View props...](docs/view.html#props)
- [`renderNavigationView`](docs/drawerlayoutandroid.html#rendernavigationview)
- [`onDrawerClose`](docs/drawerlayoutandroid.html#ondrawerclose)
- [`drawerPosition`](docs/drawerlayoutandroid.html#drawerposition)
- [`drawerWidth`](docs/drawerlayoutandroid.html#drawerwidth)
- [`keyboardDismissMode`](docs/drawerlayoutandroid.html#keyboarddismissmode)
- [`drawerLockMode`](docs/drawerlayoutandroid.html#drawerlockmode)
- [`onDrawerOpen`](docs/drawerlayoutandroid.html#ondraweropen)
- [`onDrawerSlide`](docs/drawerlayoutandroid.html#ondrawerslide)
- [`onDrawerStateChanged`](docs/drawerlayoutandroid.html#ondrawerstatechanged)
- [`drawerBackgroundColor`](docs/drawerlayoutandroid.html#drawerbackgroundcolor)
- [`statusBarBackgroundColor`](docs/drawerlayoutandroid.html#statusbarbackgroundcolor)
### Methods
- [`openDrawer`](docs/drawerlayoutandroid.html#opendrawer)
- [`closeDrawer`](docs/drawerlayoutandroid.html#closedrawer)
---
# Reference
## Props
### `renderNavigationView`
The navigation view that will be rendered to the side of the screen and can be pulled in.
| Type | Required |
| - | - |
| function | Yes |
---
### `onDrawerClose`
Function called whenever the navigation view has been closed.
| Type | Required |
| - | - |
| function | No |
---
### `drawerPosition`
Specifies the side of the screen from which the drawer will slide in.
| Type | Required |
| - | - |
| enum(DrawerConsts.DrawerPosition.Left, DrawerConsts.DrawerPosition.Right) | No |
---
### `drawerWidth`
Specifies the width of the drawer, more precisely the width of the view that be pulled in
from the edge of the window.
| Type | Required |
| - | - |
| number | No |
---
### `keyboardDismissMode`
Determines whether the keyboard gets dismissed in response to a drag.
- 'none' (the default), drags do not dismiss the keyboard.
- 'on-drag', the keyboard is dismissed when a drag begins.
| Type | Required |
| - | - |
| enum('none', 'on-drag') | No |
---
### `drawerLockMode`
Specifies the lock mode of the drawer. The drawer can be locked in 3 states:
- unlocked (default), meaning that the drawer will respond (open/close) to touch gestures.
- locked-closed, meaning that the drawer will stay closed and not respond to gestures.
- locked-open, meaning that the drawer will stay opened and not respond to gestures.
The drawer may still be opened and closed programmatically (`openDrawer`/`closeDrawer`).
| Type | Required |
| - | - |
| enum('unlocked', 'locked-closed', 'locked-open') | No |
---
### `onDrawerOpen`
Function called whenever the navigation view has been opened.
| Type | Required |
| - | - |
| function | No |
---
### `onDrawerSlide`
Function called whenever there is an interaction with the navigation view.
| Type | Required |
| - | - |
| function | No |
---
### `onDrawerStateChanged`
Function called when the drawer state has changed. The drawer can be in 3 states:
- idle, meaning there is no interaction with the navigation view happening at the time
- dragging, meaning there is currently an interaction with the navigation view
- settling, meaning that there was an interaction with the navigation view, and the
navigation view is now finishing its closing or opening animation
| Type | Required |
| - | - |
| function | No |
---
### `drawerBackgroundColor`
Specifies the background color of the drawer. The default value is white.
If you want to set the opacity of the drawer, use rgba. Example:
```
return (
<DrawerLayoutAndroid drawerBackgroundColor="rgba(0,0,0,0.5)">
</DrawerLayoutAndroid>
);
```
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
---
### `statusBarBackgroundColor`
Make the drawer take the entire screen and draw the background of the
status bar to allow it to open over the status bar. It will only have an
effect on API 21+.
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
## Methods
### `openDrawer()`
```javascript
openDrawer()
```
Opens the drawer.
---
### `closeDrawer()`
```javascript
closeDrawer()
```
Closes the drawer.

View File

@ -1,361 +0,0 @@
---
id: easing
title: Easing
layout: docs
category: APIs
permalink: docs/easing.html
next: geolocation
previous: dimensions
---
The `Easing` module implements common easing functions. This module is used
by [Animate.timing()](docs/animate.html#timing) to convey physically
believable motion in animations.
You can find a visualization of some common easing functions at
http://easings.net/
### Predefined animations
The `Easing` module provides several predefined animations through the
following methods:
- [`back`](docs/easing.html#back) provides a simple animation where the
object goes slightly back before moving forward
- [`bounce`](docs/easing.html#bounce) provides a bouncing animation
- [`ease`](docs/easing.html#ease) provides a simple inertial animation
- [`elastic`](docs/easing.html#elastic) provides a simple spring interaction
### Standard functions
Three standard easing functions are provided:
- [`linear`](docs/easing.html#linear)
- [`quad`](docs/easing.html#quad)
- [`cubic`](docs/easing.html#cubic)
The [`poly`](docs/easing.html#poly) function can be used to implement
quartic, quintic, and other higher power functions.
### Additional functions
Additional mathematical functions are provided by the following methods:
- [`bezier`](docs/easing.html#bezier) provides a cubic bezier curve
- [`circle`](docs/easing.html#circle) provides a circular function
- [`sin`](docs/easing.html#sin) provides a sinusoidal function
- [`exp`](docs/easing.html#exp) provides an exponential function
The following helpers are used to modify other easing functions.
- [`in`](docs/easing.html#in) runs an easing function forwards
- [`inOut`](docs/easing.html#inout) makes any easing function symmetrical
- [`out`](docs/easing.html#out) runs an easing function backwards
### Methods
- [`step0`](docs/easing.html#step0)
- [`step1`](docs/easing.html#step1)
- [`linear`](docs/easing.html#linear)
- [`ease`](docs/easing.html#ease)
- [`quad`](docs/easing.html#quad)
- [`cubic`](docs/easing.html#cubic)
- [`poly`](docs/easing.html#poly)
- [`sin`](docs/easing.html#sin)
- [`circle`](docs/easing.html#circle)
- [`exp`](docs/easing.html#exp)
- [`elastic`](docs/easing.html#elastic)
- [`back`](docs/easing.html#back)
- [`bounce`](docs/easing.html#bounce)
- [`bezier`](docs/easing.html#bezier)
- [`in`](docs/easing.html#in)
- [`out`](docs/easing.html#out)
- [`inOut`](docs/easing.html#inout)
---
# Reference
## Methods
### `step0()`
```javascript
static step0(n)
```
A stepping function, returns 1 for any positive value of `n`.
---
### `step1()`
```javascript
static step1(n)
```
A stepping function, returns 1 if `n` is greater than or equal to 1.
---
### `linear()`
```javascript
static linear(t)
```
A linear function, `f(t) = t`. Position correlates to elapsed time one to
one.
http://cubic-bezier.com/#0,0,1,1
---
### `ease()`
```javascript
static ease(t)
```
A simple inertial interaction, similar to an object slowly accelerating to
speed.
http://cubic-bezier.com/#.42,0,1,1
---
### `quad()`
```javascript
static quad(t)
```
A quadratic function, `f(t) = t * t`. Position equals the square of elapsed
time.
http://easings.net/#easeInQuad
---
### `cubic()`
```javascript
static cubic(t)
```
A cubic function, `f(t) = t * t * t`. Position equals the cube of elapsed
time.
http://easings.net/#easeInCubic
---
### `poly()`
```javascript
static poly(n)
```
A power function. Position is equal to the Nth power of elapsed time.
n = 4: http://easings.net/#easeInQuart
n = 5: http://easings.net/#easeInQuint
---
### `sin()`
```javascript
static sin(t)
```
A sinusoidal function.
http://easings.net/#easeInSine
---
### `circle()`
```javascript
static circle(t)
```
A circular function.
http://easings.net/#easeInCirc
---
### `exp()`
```javascript
static exp(t)
```
An exponential function.
http://easings.net/#easeInExpo
---
### `elastic()`
```javascript
static elastic(bounciness)
```
A simple elastic interaction, similar to a spring oscillating back and
forth.
Default bounciness is 1, which overshoots a little bit once. 0 bounciness
doesn't overshoot at all, and bounciness of N > 1 will overshoot about N
times.
http://easings.net/#easeInElastic
---
### `back()`
```javascript
static back(s)
```
Use with `Animated.parallel()` to create a simple effect where the object
animates back slightly as the animation starts.
Wolfram Plot:
- http://tiny.cc/back_default (s = 1.70158, default)
---
### `bounce()`
```javascript
static bounce(t)
```
Provides a simple bouncing effect.
http://easings.net/#easeInBounce
---
### `bezier()`
```javascript
static bezier(x1, y1, x2, y2)
```
Provides a cubic bezier curve, equivalent to CSS Transitions'
`transition-timing-function`.
A useful tool to visualize cubic bezier curves can be found at
http://cubic-bezier.com/
---
### `in()`
```javascript
static in(easing)
```
Runs an easing function forwards.
---
### `out()`
```javascript
static out(easing)
```
Runs an easing function backwards.
---
### `inOut()`
```javascript
static inOut(easing)
```
Makes any easing function symmetrical. The easing function will run
forwards for half of the duration, then backwards for the rest of the
duration.

View File

@ -1,654 +0,0 @@
---
id: flatlist
title: FlatList
layout: docs
category: components
permalink: docs/flatlist.html
next: image
previous: drawerlayoutandroid
---
A performant interface for rendering simple, flat lists, supporting the most handy features:
- Fully cross-platform.
- Optional horizontal mode.
- Configurable viewability callbacks.
- Header support.
- Footer support.
- Separator support.
- Pull to Refresh.
- Scroll loading.
- ScrollToIndex support.
If you need section support, use [`<SectionList>`](docs/sectionlist.html).
Minimal Example:
```javascript
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
```
More complex, multi-select example demonstrating `PureComponent` usage for perf optimization and avoiding bugs.
- By binding the `onPressItem` handler, the props will remain `===` and `PureComponent` will
prevent wasteful re-renders unless the actual `id`, `selected`, or `title` props change, even
if the components rendered in `MyListItem` did not have such optimizations.
- By passing `extraData={this.state}` to `FlatList` we make sure `FlatList` itself will re-render
when the `state.selected` changes. Without setting this prop, `FlatList` would not know it
needs to re-render any items because it is also a `PureComponent` and the prop comparison will
not show any changes.
- `keyExtractor` tells the list to use the `id`s for the react keys instead of the default `key` property.
```javascript
class MyListItem extends React.PureComponent {
_onPress = () => {
this.props.onPressItem(this.props.id);
};
render() {
const textColor = this.props.selected ? "red" : "black";
return (
<TouchableOpacity onPress={this._onPress}>
<View>
<Text style={{ color: textColor }}>
{this.props.title}
</Text>
</View>
</TouchableOpacity>
);
}
}
class MultiSelectList extends React.PureComponent {
state = {selected: (new Map(): Map<string, boolean>)};
_keyExtractor = (item, index) => item.id;
_onPressItem = (id: string) => {
// updater functions are preferred for transactional updates
this.setState((state) => {
// copy the map rather than modifying state.
const selected = new Map(state.selected);
selected.set(id, !selected.get(id)); // toggle
return {selected};
});
};
_renderItem = ({item}) => (
<MyListItem
id={item.id}
onPressItem={this._onPressItem}
selected={!!this.state.selected.get(item.id)}
title={item.title}
/>
);
render() {
return (
<FlatList
data={this.props.data}
extraData={this.state}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
);
}
}
```
This is a convenience wrapper around [`VirtualizedList`](docs/virtualizedlist.html), and thus inherits its props (as well as those of `ScrollView`) that aren't explicitly listed here, along with the following caveats:
- Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.
- This is a `PureComponent` which means that it will not re-render if `props` remain shallow- equal. Make sure that everything your `renderItem` function depends on is passed as a prop (e.g. `extraData`) that is not `===` after updates, otherwise your UI may not update on changes. This includes the `data` prop and parent component state.
- In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.
- By default, the list looks for a `key` prop on each item and uses that for the React key. Alternatively, you can provide a custom `keyExtractor` prop.
Also inherits [ScrollView props](docs/scrollview.html#props), unless it is nested in another `FlatList` of same orientation.
### Props
- [`ScrollView` props...](docs/scrollview.html#props)
- [`VirtualizedList` props...](docs/virtualizedlist.html#props)
- [`renderItem`](docs/flatlist.html#renderitem)
- [`data`](docs/flatlist.html#data)
- [`ItemSeparatorComponent`](docs/flatlist.html#itemseparatorcomponent)
- [`ListEmptyComponent`](docs/flatlist.html#listemptycomponent)
- [`ListFooterComponent`](docs/flatlist.html#listgootercomponent)
- [`ListHeaderComponent`](docs/flatlist.html#listheadercomponent)
- [`columnwrapperstyle`](docs/flatlist.html#columnwrapperstyle)
- [`extraData`](docs/flatlist.html#extradata)
- [`getItemLayout`](docs/flatlist.html#getitemlayout)
- [`horizontal`](docs/flatlist.html#horizontal)
- [`initialNumToRender`](docs/flatlist.html#initialnumtorender)
- [`initialScrollIndex`](docs/flatlist.html#initialscrollindex)
- [`inverted`](docs/flatlist.html#inverted)
- [`keyExtractor`](docs/flatlist.html#keyextractor)
- [`numColumns`](docs/flatlist.html#numcolumns)
- [`onEndReached`](docs/flatlist.html#onendreached)
- [`onEndReachedThreshold`](docs/flatlist.html#onendreachedthreshold)
- [`onRefresh`](docs/flatlist.html#onrefresh)
- [`onViewableItemsChanged`](docs/flatlist.html#onviewableitemschanged)
- [`progressViewOffset`](docs/flatlist.html#progressviewoffset)
- [`legacyImplementation`](docs/flatlist.html#legacyimplementation)
- [`refreshing`](docs/flatlist.html#refreshing)
- [`removeClippedSubviews`](docs/flatlist.html#removeclippedsubviews)
- [`viewabilityConfig`](docs/flatlist.html#viewabilityconfig)
- [`viewabilityConfigCallbackPairs`](docs/flatlist.html#viewabilityconfigcallbackpairs)
### Methods
- [`scrollToEnd`](docs/flatlist.html#scrolltoend)
- [`scrollToIndex`](docs/flatlist.html#scrolltoindex)
- [`scrollToItem`](docs/flatlist.html#scrolltoitem)
- [`scrollToOffset`](docs/flatlist.html#scrolltooffset)
- [`recordInteraction`](docs/flatlist.html#recordinteraction)
- [`flashScrollIndicators`](docs/flatlist.html#flashscrollindicators)
### Type Definitions
- [`Props`](docs/flatlist.html#props)
- [`DefaultProps`](docs/flatlist.html#defaultprops)
---
# Reference
## Props
### `renderItem`
```javascript
renderItem({ item: object, index: number, separators: { highlight: function, unhighlight: function, updateProps: function(select: string, newProps: object) } }): [element]
```
Takes an item from `data` and renders it into the list.
Provides additional metadata like `index` if you need it, as well as a more generic `separators.updateProps` function which let's you set whatever props you want to change the rendering of either the leading separator or trailing separator in case the more common `highlight` and `unhighlight` (which set the `highlighted: boolean` prop) are insufficient for your use case.
| Type | Required |
| - | - |
| function | Yes |
Example usage:
```javascript
<FlatList
ItemSeparatorComponent={Platform.OS !== 'android' && ({highlighted}) => (
<View style={[style.separator, highlighted && {marginLeft: 0}]} />
)}
data={[{title: 'Title Text', key: 'item1'}]}
renderItem={({item, separators}) => (
<TouchableHighlight
onPress={() => this._onPress(item)}
onShowUnderlay={separators.highlight}
onHideUnderlay={separators.unhighlight}>
<View style={{backgroundColor: 'white'}}>
<Text>{item.title}</Text>
</View>
</TouchableHighlight>
)}
/>
```
---
### `data`
For simplicity, data is just a plain array. If you want to use something else, like an immutable list, use the underlying [`VirtualizedList`](docs/virtualizedlist.html) directly.
| Type | Required |
| - | - |
| array | Yes |
---
### `ItemSeparatorComponent`
Rendered in between each item, but not at the top or bottom. By default, `highlighted` and `leadingItem` props are provided. `renderItem` provides `separators.highlight`/`unhighlight` which will update the `highlighted` prop, but you can also add custom props with `separators.updateProps`.
| Type | Required |
| - | - |
| component | No |
---
### `ListEmptyComponent`
Rendered when the list is empty. Can be a React Component Class, a render function, or a rendered element.
| Type | Required |
| - | - |
| component, function, element | No |
---
### `ListFooterComponent`
Rendered at the bottom of all the items. Can be a React Component Class, a render function, or a rendered element.
| Type | Required |
| - | - |
| component, function, element | No |
---
### `ListHeaderComponent`
Rendered at the top of all the items. Can be a React Component Class, a render function, or a rendered element.
| Type | Required |
| - | - |
| component, function, element | No |
---
### `columnWrapperStyle`
Optional custom style for multi-item rows generated when `numColumns > 1`.
| Type | Required |
| - | - |
| style object | No |
---
### `extraData`
A marker property for telling the list to re-render (since it implements `PureComponent`). If any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the `data` prop, stick it here and treat it immutably.
| Type | Required |
| - | - |
| any | No |
---
### `getItemLayout`
```javascript
(data, index) => {length: number, offset: number, index: number}
```
`getItemLayout` is an optional optimization that let us skip measurement of dynamic content if you know the height of items a priori. `getItemLayout` is the most efficient, and is easy to use if you have fixed height items, for example:
```javascript
getItemLayout={(data, index) => (
{length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index}
)}
```
Adding `getItemLayout` can be a great performance boost for lists of several hundred items. Remember to include separator length (height or width) in your offset calculation if you specify `ItemSeparatorComponent`.
| Type | Required |
| - | - |
| function | No |
---
### `horizontal`
If true, renders items next to each other horizontally instead of stacked vertically.
| Type | Required |
| - | - |
| boolean | No |
---
### `initialNumToRender`
How many items to render in the initial batch. This should be enough to fill the screen but not much more. Note these items will never be unmounted as part of the windowed rendering in order to improve perceived performance of scroll-to-top actions.
| Type | Required |
| - | - |
| number | No |
---
### `initialScrollIndex`
Instead of starting at the top with the first item, start at `initialScrollIndex`. This disables the "scroll to top" optimization that keeps the first `initialNumToRender` items always rendered and immediately renders the items starting at this initial index. Requires `getItemLayout` to be implemented.
| Type | Required |
| - | - |
| number | No |
---
### `inverted`
Reverses the direction of scroll. Uses scale transforms of `-1`.
| Type | Required |
| - | - |
| boolean | No |
---
### `keyExtractor`
```javascript
(item: object, index: number) => string
```
Used to extract a unique key for a given item at the specified index. Key is used for caching and as the react key to track item re-ordering. The default extractor checks `item.key`, then falls back to using the index, like React does.
| Type | Required |
| - | - |
| function | No |
---
### `numColumns`
Multiple columns can only be rendered with `horizontal={false}` and will zig-zag like a `flexWrap` layout. Items should all be the same height - masonry layouts are not supported.
| Type | Required |
| - | - |
| number | No |
---
### `onEndReached`
```javascript
(info: {distanceFromEnd: number}) => void
```
Called once when the scroll position gets within `onEndReachedThreshold` of the rendered content.
| Type | Required |
| - | - |
| function | No |
---
### `onEndReachedThreshold`
How far from the end (in units of visible length of the list) the bottom edge of the list must be from the end of the content to trigger the `onEndReached` callback. Thus a value of 0.5 will trigger `onEndReached` when the end of the content is within half the visible length of the list.
| Type | Required |
| - | - |
| number | No |
---
### `onRefresh`
```javascript
() => void
```
If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the `refreshing` prop correctly.
| Type | Required |
| - | - |
| function | No |
---
### `onViewableItemsChanged`
```javascript
(info: {
viewableItems: array,
changed: array,
}) => void
```
Called when the viewability of rows changes, as defined by the `viewabilityConfig` prop.
| Type | Required |
| - | - |
| function | No |
---
### `progressViewOffset`
Set this when offset is needed for the loading indicator to show correctly.
| Type | Required | Platform |
| - | - | - |
| number | No | Android |
---
### `legacyImplementation`
May not have full feature parity and is meant for debugging and performance comparison.
| Type | Required |
| - | - |
| boolean | No |
---
### `refreshing`
Set this true while waiting for new data from a refresh.
| Type | Required |
| - | - |
| boolean | No |
---
### `removeClippedSubviews`
This may improve scroll performance for large lists.
> Note:
> May have bugs (missing content) in some circumstances - use at your own risk.
| Type | Required |
| - | - |
| boolean | No |
---
### `viewabilityConfig`
See `ViewabilityHelper.js` for flow type and further documentation.
| Type | Required |
| - | - |
| ViewabilityConfig | No |
---
### `viewabilityConfigCallbackPairs`
List of `ViewabilityConfig`/`onViewableItemsChanged` pairs. A specific `onViewableItemsChanged` will be called when its corresponding `ViewabilityConfig`'s conditions are met. See `ViewabilityHelper.js` for flow type and further documentation.
| Type | Required |
| - | - |
| array of ViewabilityConfigCallbackPair | No |
## Methods
### `scrollToEnd()`
```javascript
scrollToEnd([params]: object)
```
Scrolls to the end of the content. May be janky without `getItemLayout` prop.
---
### `scrollToIndex()`
```javascript
scrollToIndex(params: object)
```
Scrolls to the item at the specified index such that it is positioned in the viewable area
such that `viewPosition` 0 places it at the top, 1 at the bottom, and 0.5 centered in the
middle. `viewOffset` is a fixed number of pixels to offset the final target position.
Note: cannot scroll to locations outside the render window without specifying the
`getItemLayout` prop.
---
### `scrollToItem()`
```javascript
scrollToItem(params: object)
```
Requires linear scan through data - use `scrollToIndex` instead if possible.
Note: cannot scroll to locations outside the render window without specifying the
`getItemLayout` prop.
---
### `scrollToOffset()`
```javascript
scrollToOffset(params: object)
```
Scroll to a specific content pixel offset in the list.
Check out [scrollToOffset](docs/virtualizedlist.html#scrolltooffset) of VirtualizedList
---
### `recordInteraction()`
```javascript
recordInteraction()
```
Tells the list an interaction has occurred, which should trigger viewability calculations, e.g.
if `waitForInteractions` is true and the user has not scrolled. This is typically called by
taps on items or by navigation actions.
---
### `flashScrollIndicators()`
```javascript
flashScrollIndicators()
```
Displays the scroll indicators momentarily.
## Type Definitions
### Props
| Type |
| - |
| IntersectionTypeAnnotation |
---
### DefaultProps
| Type |
| - |
| TypeofTypeAnnotation |

View File

@ -1,110 +0,0 @@
---
id: flexbox
title: Layout with Flexbox
layout: docs
category: The Basics
permalink: docs/flexbox.html
next: handling-text-input
previous: height-and-width
---
A component can specify the layout of its children using the flexbox algorithm. Flexbox is designed to provide a consistent layout on different screen sizes.
You will normally use a combination of `flexDirection`, `alignItems`, and `justifyContent` to achieve the right layout.
> Flexbox works the same way in React Native as it does in CSS on the web, with a few exceptions. The defaults are different, with `flexDirection` defaulting to `column` instead of `row`, and the `flex` parameter only supporting a single number.
#### Flex Direction
Adding `flexDirection` to a component's `style` determines the **primary axis** of its layout. Should the children be organized horizontally (`row`) or vertically (`column`)? The default is `column`.
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class FlexDirectionBasics extends Component {
render() {
return (
// Try setting `flexDirection` to `column`.
<View style={{flex: 1, flexDirection: 'row'}}>
<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>
);
}
};
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => FlexDirectionBasics);
```
#### Justify Content
Adding `justifyContent` to a component's style determines the **distribution** of children along the **primary axis**. Should children be distributed at the start, the center, the end, or spaced evenly? Available options are `flex-start`, `center`, `flex-end`, `space-around`, and `space-between`.
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class JustifyContentBasics extends Component {
render() {
return (
// Try setting `justifyContent` to `center`.
// Try setting `flexDirection` to `row`.
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'space-between',
}}>
<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>
);
}
};
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics);
```
#### Align Items
Adding `alignItems` to a component's style determines the **alignment** of children along the **secondary axis** (if the primary axis is `row`, then the secondary is `column`, and vice versa). Should children be aligned at the start, the center, the end, or stretched to fill? Available options are `flex-start`, `center`, `flex-end`, and `stretch`.
> For `stretch` to have an effect, children must not have a fixed dimension along the secondary axis. In the following example, setting `alignItems: stretch` does nothing until the `height: 50` is removed from the children.
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class AlignItemsBasics extends Component {
render() {
return (
// Try setting `alignItems` to 'flex-start'
// Try setting `justifyContent` to `flex-end`.
// Try setting `flexDirection` to `row`.
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}>
<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>
);
}
};
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics);
```
#### Going Deeper
We've covered the basics, but there are many other styles you may need for layouts. The full list of props that control layout is documented [here](./docs/layout-props.html).
We're getting close to being able to build a real application. One thing we are still missing is a way to take user input, so let's move on to [learn how to handle text input with the TextInput component](docs/handling-text-input.html).

View File

@ -1,162 +0,0 @@
---
id: geolocation
title: Geolocation
layout: docs
category: APIs
permalink: docs/geolocation.html
next: imageeditor
previous: easing
---
The Geolocation API extends the web spec:
https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
As a browser polyfill, this API is available through the `navigator.geolocation`
global - you do not need to `import` it.
### Configuration and Permissions
<div class="banner-crna-ejected">
<h3>Projects with Native Code Only</h3>
<p>
This section only applies to projects made with <code>react-native init</code>
or to those made with Create React Native App which have since ejected. For
more information about ejecting, please see
the <a href="https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md" target="_blank">guide</a> on
the Create React Native App repository.
</p>
</div>
#### iOS
You need to include the `NSLocationWhenInUseUsageDescription` key
in Info.plist to enable geolocation when using the app. Geolocation is
enabled by default when you create a project with `react-native init`.
In order to enable geolocation in the background, you need to include the
'NSLocationAlwaysUsageDescription' key in Info.plist and add location as
a background mode in the 'Capabilities' tab in Xcode.
#### Android
To request access to location, you need to add the following line to your
app's `AndroidManifest.xml`:
`<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />`
Android API >= 18 Positions will also contain a `mocked` boolean to indicate if position
was created from a mock provider.
<p>
Android API >= 23 Requires an additional step to check for, and request
the ACCESS_FINE_LOCATION permission using
the <a href="https://facebook.github.io/react-native/docs/permissionsandroid.html" target="_blank">PermissionsAndroid API</a>.
Failure to do so may result in a hard crash.
</p>
### Methods
- [`setRNConfiguration`](docs/geolocation.html#setrnconfiguration)
- [`requestAuthorization`](docs/geolocation.html#requestauthorization)
- [`getCurrentPosition`](docs/geolocation.html#getcurrentposition)
- [`watchPosition`](docs/geolocation.html#watchposition)
- [`clearWatch`](docs/geolocation.html#clearwatch)
- [`stopObserving`](docs/geolocation.html#stopobserving)
---
# Reference
## Methods
### `setRNConfiguration()`
```javascript
Geolocation.setRNConfiguration(config)
```
Sets configuration options that will be used in all location requests.
### Options
#### iOS
- `skipPermissionRequests` - defaults to `false`, if `true` you must request permissions
before using Geolocation APIs.
---
### `requestAuthorization()`
```javascript
Geolocation.requestAuthorization()
```
Request suitable Location permission based on the key configured on pList.
If NSLocationAlwaysUsageDescription is set, it will request Always authorization,
although if NSLocationWhenInUseUsageDescription is set, it will request InUse
authorization.
---
### `getCurrentPosition()`
```javascript
Geolocation.getCurrentPosition(geo_success, geo_error?, geo_options?)
```
Invokes the success callback once with the latest location info. Supported
options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
On Android, if the location is cached this can return almost immediately,
or it will request an update which might take a while.
---
### `watchPosition()`
```javascript
Geolocation.watchPosition(success, error?, options?)
```
Invokes the success callback whenever the location changes. Supported
options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool), distanceFilter(m), useSignificantChanges (bool)
---
### `clearWatch()`
```javascript
Geolocation.clearWatch(watchID)
```
---
### `stopObserving()`
```javascript
Geolocation.stopObserving()
```

View File

@ -1,72 +0,0 @@
---
id: gesture-responder-system
title: Gesture Responder System
layout: docs
category: Guides
permalink: docs/gesture-responder-system.html
next: javascript-environment
previous: performance
---
The gesture responder system manages the lifecycle of gestures in your app. A touch can go through several phases as the app determines what the user's intention is. For example, the app needs to determine if the touch is scrolling, sliding on a widget, or tapping. This can even change during the duration of a touch. There can also be multiple simultaneous touches.
The touch responder system is needed to allow components to negotiate these touch interactions without any additional knowledge about their parent or child components. This system is implemented in `ResponderEventPlugin.js`, which contains further details and documentation.
### Best Practices
To make your app feel great, every action should have the following attributes:
- Feedback/highlighting- show the user what is handling their touch, and what will happen when they release the gesture
- Cancel-ability- when making an action, the user should be able to abort it mid-touch by dragging their finger away
These features make users more comfortable while using an app, because it allows people to experiment and interact without fear of making mistakes.
### TouchableHighlight and Touchable*
The responder system can be complicated to use. So we have provided an abstract `Touchable` implementation for things that should be "tappable". This uses the responder system and allows you to easily configure tap interactions declaratively. Use `TouchableHighlight` anywhere where you would use a button or link on web.
## Responder Lifecycle
A view can become the touch responder by implementing the correct negotiation methods. There are two methods to ask the view if it wants to become responder:
- `View.props.onStartShouldSetResponder: (evt) => true,` - Does this view want to become responder on the start of a touch?
- `View.props.onMoveShouldSetResponder: (evt) => true,` - Called for every touch move on the View when it is not the responder: does this view want to "claim" touch responsiveness?
If the View returns true and attempts to become the responder, one of the following will happen:
- `View.props.onResponderGrant: (evt) => {}` - The View is now responding for touch events. This is the time to highlight and show the user what is happening
- `View.props.onResponderReject: (evt) => {}` - Something else is the responder right now and will not release it
If the view is responding, the following handlers can be called:
- `View.props.onResponderMove: (evt) => {}` - The user is moving their finger
- `View.props.onResponderRelease: (evt) => {}` - Fired at the end of the touch, ie "touchUp"
- `View.props.onResponderTerminationRequest: (evt) => true` - Something else wants to become responder. Should this view release the responder? Returning true allows release
- `View.props.onResponderTerminate: (evt) => {}` - The responder has been taken from the View. Might be taken by other views after a call to `onResponderTerminationRequest`, or might be taken by the OS without asking (happens with control center/ notification center on iOS)
`evt` is a synthetic touch event with the following form:
- `nativeEvent`
+ `changedTouches` - Array of all touch events that have changed since the last event
+ `identifier` - The ID of the touch
+ `locationX` - The X position of the touch, relative to the element
+ `locationY` - The Y position of the touch, relative to the element
+ `pageX` - The X position of the touch, relative to the root element
+ `pageY` - The Y position of the touch, relative to the root element
+ `target` - The node id of the element receiving the touch event
+ `timestamp` - A time identifier for the touch, useful for velocity calculation
+ `touches` - Array of all current touches on the screen
### Capture ShouldSet Handlers
`onStartShouldSetResponder` and `onMoveShouldSetResponder` are called with a bubbling pattern, where the deepest node is called first. That means that the deepest component will become responder when multiple Views return true for `*ShouldSetResponder` handlers. This is desirable in most cases, because it makes sure all controls and buttons are usable.
However, sometimes a parent will want to make sure that it becomes responder. This can be handled by using the capture phase. Before the responder system bubbles up from the deepest component, it will do a capture phase, firing `on*ShouldSetResponderCapture`. So if a parent View wants to prevent the child from becoming responder on a touch start, it should have a `onStartShouldSetResponderCapture` handler which returns true.
- `View.props.onStartShouldSetResponderCapture: (evt) => true,`
- `View.props.onMoveShouldSetResponderCapture: (evt) => true,`
### PanResponder
For higher-level gesture interpretation, check out [PanResponder](docs/panresponder.html).

View File

@ -1,762 +0,0 @@
---
id: getting-started
title: Getting Started
layout: docs
category: The Basics
permalink: docs/getting-started.html
next: tutorial
previous: undefined
---
<style>
.toggler li {
display: inline-block;
position: relative;
top: 1px;
padding: 10px;
margin: 0px 2px 0px 2px;
border: 1px solid #05A5D1;
border-bottom-color: transparent;
border-radius: 3px 3px 0px 0px;
color: #05A5D1;
background-color: transparent;
font-size: 0.99em;
cursor: pointer;
}
.toggler li:first-child {
margin-left: 0;
}
.toggler li:last-child {
margin-right: 0;
}
.toggler ul {
width: 100%;
display: inline-block;
list-style-type: none;
margin: 0;
border-bottom: 1px solid #05A5D1;
cursor: default;
}
@media screen and (max-width: 960px) {
.toggler li,
.toggler li:first-child,
.toggler li:last-child {
display: block;
border-bottom-color: #05A5D1;
border-radius: 3px;
margin: 2px 0px 2px 0px;
}
.toggler ul {
border-bottom: 0;
}
}
.toggler a {
display: inline-block;
padding: 10px 5px;
margin: 2px;
border: 1px solid #05A5D1;
border-radius: 3px;
text-decoration: none !important;
}
.display-guide-quickstart .toggler .button-quickstart,
.display-guide-native .toggler .button-native,
.display-os-mac .toggler .button-mac,
.display-os-linux .toggler .button-linux,
.display-os-windows .toggler .button-windows,
.display-platform-ios .toggler .button-ios,
.display-platform-android .toggler .button-android {
background-color: #05A5D1;
color: white;
}
block { display: none; }
.display-guide-quickstart.display-platform-ios.display-os-mac .quickstart.ios.mac,
.display-guide-quickstart.display-platform-ios.display-os-linux .quickstart.ios.linux,
.display-guide-quickstart.display-platform-ios.display-os-windows .quickstart.ios.windows,
.display-guide-quickstart.display-platform-android.display-os-mac .quickstart.android.mac,
.display-guide-quickstart.display-platform-android.display-os-linux .quickstart.android.linux,
.display-guide-quickstart.display-platform-android.display-os-windows .quickstart.android.windows, .display-guide-native.display-platform-ios.display-os-mac .native.ios.mac,
.display-guide-native.display-platform-ios.display-os-linux .native.ios.linux,
.display-guide-native.display-platform-ios.display-os-windows .native.ios.windows,
.display-guide-native.display-platform-android.display-os-mac .native.android.mac,
.display-guide-native.display-platform-android.display-os-linux .native.android.linux,
.display-guide-native.display-platform-android.display-os-windows .native.android.windows {
display: block;
}
</style>
This page will help you install and build your first React Native app. If you already have React Native installed, you can skip ahead to the [Tutorial](docs/tutorial.html).
<div class="toggler">
<ul role="tablist" >
<li id="quickstart" class="button-quickstart" aria-selected="false" role="tab" tabindex="0" aria-controls="quickstarttab" onclick="displayTab('guide', 'quickstart')">
Quick Start
</li>
<li id="native" class="button-native" aria-selected="false" role="tab" tabindex="-1" aria-controls="nativetab" onclick="displayTab('guide', 'native')">
Building Projects with Native Code
</li>
</ul>
</div>
<block class="quickstart mac windows linux ios android" />
[Create React Native App](https://github.com/react-community/create-react-native-app) is the easiest way to start building a new React Native application. It allows you to start a project without installing or configuring any tools to build native code - no Xcode or Android Studio installation required (see [Caveats](docs/getting-started.html#caveats)).
Assuming that you have [Node](https://nodejs.org/en/download/) installed, you can use npm to install the `create-react-native-app` command line utility:
```
npm install -g create-react-native-app
```
Then run the following commands to create a new React Native project called "AwesomeProject":
```
create-react-native-app AwesomeProject
cd AwesomeProject
npm start
```
This will start a development server for you, and print a QR code in your terminal.
## Running your React Native application
Install the [Expo](https://expo.io) client app on your iOS or Android phone and connect to the same wireless network as your computer. Using the Expo app, scan the QR code from your terminal to open your project.
### Modifying your app
Now that you have successfully run the app, let's modify it. Open `App.js` in your text editor of choice and edit some lines. The application should reload automatically once you save your changes.
### That's it!
Congratulations! You've successfully run and modified your first React Native app.
<center><img src="img/react-native-congratulations.png" width="150"></img></center>
## Now what?
- Create React Native App also has a [user guide](https://github.com/react-community/create-react-native-app/blob/master/react-native-scripts/template/README.md) you can reference if you have questions specific to the tool.
- If you can't get this to work, see the [Troubleshooting](https://github.com/react-community/create-react-native-app/blob/master/react-native-scripts/template/README.md#troubleshooting) section in the README for Create React Native App.
If you're curious to learn more about React Native, continue on
to the [Tutorial](docs/tutorial.html).
### Running your app on a simulator or virtual device
Create React Native App makes it really easy to run your React Native app on a physical device without setting up a development environment. If you want to run your app on the iOS Simulator or an Android Virtual Device, please refer to the instructions for building projects with native code to learn how to install Xcode and set up your Android development environment.
Once you've set these up, you can launch your app on an Android Virtual Device by running `npm run android`, or on the iOS Simulator by running `npm run ios` (macOS only).
### Caveats
Because you don't build any native code when using Create React Native App to create a project, it's not possible to include custom native modules beyond the React Native APIs and components that are available in the Expo client app.
If you know that you'll eventually need to include your own native code, Create React Native App is still a good way to get started. In that case you'll just need to "[eject](https://github.com/react-community/create-react-native-app/blob/master/react-native-scripts/template/README.md#ejecting-from-create-react-native-app)" eventually to create your own native builds. If you do eject, the "Building Projects with Native Code" instructions will be required to continue working on your project.
Create React Native App configures your project to use the most recent React Native version that is supported by the Expo client app. The Expo client app usually gains support for a given React Native version about a week after the React Native version is released as stable. You can check [this document](https://github.com/react-community/create-react-native-app/blob/master/VERSIONS.md) to find out what versions are supported.
If you're integrating React Native into an existing project, you'll want to skip Create React Native App and go directly to setting up the native build environment. Select "Building Projects with Native Code" above for instructions on configuring a native build environment for React Native.
<block class="native mac windows linux ios android" />
<p>Follow these instructions if you need to build native code in your project. For example, if you are integrating React Native into an existing application, or if you "ejected" from <a href="docs/getting-started.html" onclick="displayTab('guide', 'quickstart')">Create React Native App</a>, you'll need this section.</p>
The instructions are a bit different depending on your development operating system, and whether you want to start developing for iOS or Android. If you want to develop for both iOS and Android, that's fine - you just have to pick
one to start with, since the setup is a bit different.
<div class="toggler">
<span>Development OS:</span>
<a href="javascript:void(0);" class="button-mac" onclick="displayTab('os', 'mac')">macOS</a>
<a href="javascript:void(0);" class="button-windows" onclick="displayTab('os', 'windows')">Windows</a>
<a href="javascript:void(0);" class="button-linux" onclick="displayTab('os', 'linux')">Linux</a>
<span>Target OS:</span>
<a href="javascript:void(0);" class="button-ios" onclick="displayTab('platform', 'ios')">iOS</a>
<a href="javascript:void(0);" class="button-android" onclick="displayTab('platform', 'android')">Android</a>
</div>
<block class="native linux windows ios" />
## Unsupported
<blockquote><p>A Mac is required to build projects with native code for iOS. You can follow the <a href="docs/getting-started.html" onclick="displayTab('guide', 'quickstart')">Quick Start</a> to learn how to build your app using Create React Native App instead.</p></blockquote>
<block class="native mac ios" />
## Installing dependencies
You will need Node, Watchman, the React Native command line interface, and Xcode.
While you can use any editor of your choice to develop your app, you will need to install Xcode in order to set up the necessary tooling to build your React Native app for iOS.
<block class="native mac android" />
## Installing dependencies
You will need Node, Watchman, the React Native command line interface, a JDK, and Android Studio.
<block class="native linux android" />
## Installing dependencies
You will need Node, the React Native command line interface, a JDK, and Android Studio.
<block class="native windows android" />
## Installing dependencies
You will need Node, the React Native command line interface, Python2, a JDK, and Android Studio.
<block class="native mac windows linux android" />
While you can use any editor of your choice to develop your app, you will need to install Android Studio in order to set up the necessary tooling to build your React Native app for Android.
<block class="native mac ios android" />
### Node, Watchman
We recommend installing Node and Watchman using [Homebrew](http://brew.sh/). Run the following commands in a Terminal after installing Homebrew:
```
brew install node
brew install watchman
```
If you have already installed Node on your system, make sure it is version 4 or newer.
[Watchman](https://facebook.github.io/watchman) is a tool by Facebook for watching changes in the filesystem. It is highly recommended you install it for better performance.
<block class="native linux android" />
### Node
Follow the [installation instructions for your Linux distribution](https://nodejs.org/en/download/package-manager/) to install Node 6 or newer.
<block class='native windows android' />
### Node, Python2, JDK
We recommend installing Node and Python2 via [Chocolatey](https://chocolatey.org), a popular package manager for Windows.
React Native also requires a recent version of the [Java SE Development Kit (JDK)](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html), as well as Python 2. Both can be installed using Chocolatey.
Open an Administrator Command Prompt (right click Command Prompt and select "Run as Administrator"), then run the following command:
```powershell
choco install -y nodejs.install python2 jdk8
```
If you have already installed Node on your system, make sure it is version 4 or newer. If you already have a JDK on your system, make sure it is version 8 or newer.
> You can find additional installation options on [Node's Downloads page](https://nodejs.org/en/download/).
<block class="native mac ios android" />
### The React Native CLI
Node comes with npm, which lets you install the React Native command line interface.
Run the following command in a Terminal:
```
npm install -g react-native-cli
```
> If you get an error like `Cannot find module 'npmlog'`, try installing npm directly: `curl -0 -L https://npmjs.org/install.sh | sudo sh`.
<block class="native windows linux android" />
### The React Native CLI
Node comes with npm, which lets you install the React Native command line interface.
Run the following command in a Command Prompt or shell:
```powershell
npm install -g react-native-cli
```
> If you get an error like `Cannot find module 'npmlog'`, try installing npm directly: `curl -0 -L https://npmjs.org/install.sh | sudo sh`.
<block class="native mac ios" />
### Xcode
The easiest way to install Xcode is via the [Mac App Store](https://itunes.apple.com/us/app/xcode/id497799835?mt=12). Installing Xcode will also install the iOS Simulator and all the necessary tools to build your iOS app.
If you have already installed Xcode on your system, make sure it is version 8 or higher.
#### Command Line Tools
You will also need to install the Xcode Command Line Tools. Open Xcode, then choose "Preferences..." from the Xcode menu. Go to the Locations panel and install the tools by selecting the most recent version in the Command Line Tools dropdown.
![Xcode Command Line Tools](img/XcodeCommandLineTools.png)
<block class="native mac linux android" />
### Java Development Kit
React Native requires a recent version of the Java SE Development Kit (JDK). [Download and install JDK 8 or newer](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) if needed.
<block class="native mac linux windows android" />
### Android development environment
Setting up your development environment can be somewhat tedious if you're new to Android development. If you're already familiar with Android development, there are a few things you may need to configure. In either case, please make sure to carefully follow the next few steps.
<block class="native mac windows linux android" />
#### 1. Install Android Studio
[Download and install Android Studio](https://developer.android.com/studio/index.html). Choose a "Custom" setup when prompted to select an installation type. Make sure the boxes next to all of the following are checked:
<block class="native mac windows android" />
- `Android SDK`
- `Android SDK Platform`
- `Performance (Intel ® HAXM)`
- `Android Virtual Device`
<block class="native linux android" />
- `Android SDK`
- `Android SDK Platform`
- `Android Virtual Device`
<block class="native mac windows linux android" />
Then, click "Next" to install all of these components.
> If the checkboxes are grayed out, you will have a chance to install these components later on.
Once setup has finalized and you're presented with the Welcome screen, proceed to the next step.
#### 2. Install the Android SDK
Android Studio installs the latest Android SDK by default. Building a React Native app with native code, however, requires the `Android 6.0 (Marshmallow)` SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio.
The SDK Manager can be accessed from the "Welcome to Android Studio" screen. Click on "Configure", then select "SDK Manager".
<block class="native mac android" />
![Android Studio Welcome](img/AndroidStudioWelcomeMacOS.png)
<block class="native windows android" />
![Android Studio Welcome](img/AndroidStudioWelcomeWindows.png)
<block class="native mac windows linux android" />
> The SDK Manager can also be found within the Android Studio "Preferences" dialog, under **Appearance & Behavior****System Settings****Android SDK**.
Select the "SDK Platforms" tab from within the SDK Manager, then check the box next to "Show Package Details" in the bottom right corner. Look for and expand the `Android 6.0 (Marshmallow)` entry, then make sure the following items are all checked:
- `Google APIs`
- `Android SDK Platform 23`
- `Intel x86 Atom_64 System Image`
- `Google APIs Intel x86 Atom_64 System Image`
<block class="native mac android" />
![Android SDK Manager](img/AndroidSDKManagerMacOS.png)
<block class="native windows android" />
![Android SDK Manager](img/AndroidSDKManagerWindows.png)
<block class="native windows mac linux android" />
Next, select the "SDK Tools" tab and check the box next to "Show Package Details" here as well. Look for and expand the "Android SDK Build-Tools" entry, then make sure that `23.0.1` is selected.
<block class="native mac android" />
![Android SDK Manager - 23.0.1 Build Tools](img/AndroidSDKManagerSDKToolsMacOS.png)
<block class="native windows android" />
![Android SDK Manager - 23.0.1 Build Tools](img/AndroidSDKManagerSDKToolsWindows.png)
<block class="native windows mac linux android" />
Finally, click "Apply" to download and install the Android SDK and related build tools.
<block class="native mac android" />
![Android SDK Manager - Installs](img/AndroidSDKManagerInstallsMacOS.png)
<block class="native windows android" />
![Android SDK Manager - Installs](img/AndroidSDKManagerInstallsWindows.png)
<block class="native mac windows linux android" />
#### 3. Configure the ANDROID_HOME environment variable
The React Native tools require some environment variables to be set up in order to build apps with native code.
<block class="native mac linux android" />
Add the following lines to your `$HOME/.bash_profile` config file:
<block class="native mac android" />
```
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
```
<block class="native linux android" />
```
export ANDROID_HOME=$HOME/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
```
<block class="native mac linux android" />
> `.bash_profile` is specific to `bash`. If you're using another shell, you will need to edit the appropriate shell-specific config file.
Type `source $HOME/.bash_profile` to load the config into your current shell. Verify that ANDROID_HOME has been added to your path by running `echo $PATH`.
> Please make sure you use the correct Android SDK path. You can find the actual location of the SDK in the Android Studio "Preferences" dialog, under **Appearance & Behavior****System Settings****Android SDK**.
<block class="native windows android" />
Open the System pane under **System and Security** in the Control Panel, then click on **Change settings...**. Open the **Advanced** tab and click on **Environment Variables...**. Click on **New...** to create a new `ANDROID_HOME` user variable that points to the path to your Android SDK:
![ANDROID_HOME Environment Variable](img/AndroidEnvironmentVariableANDROID_HOME.png)
The SDK is installed, by default, at the following location:
```powershell
c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk
```
You can find the actual location of the SDK in the Android Studio "Preferences" dialog, under **Appearance & Behavior****System Settings****Android SDK**.
Open a new Command Prompt window to ensure the new environment variable is loaded before proceeding to the next step.
<block class="native linux android" />
### Watchman (optional)
Follow the [Watchman installation guide](https://facebook.github.io/watchman/docs/install.html#build-install) to compile and install Watchman from source.
> [Watchman](https://facebook.github.io/watchman/docs/install.html) is a tool by Facebook for watching
changes in the filesystem. It is highly recommended you install it for better performance, but it's alright to skip this if you find the process to be tedious.
<block class="native mac ios" />
## Creating a new application
Use the React Native command line interface to generate a new React Native project called "AwesomeProject":
```
react-native init AwesomeProject
```
This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Create React Native App, or if you're adding iOS support to an existing React Native project (see [Platform Specific Code](docs/platform-specific-code.html)).
<block class="native mac windows linux android" />
## Creating a new application
Use the React Native command line interface to generate a new React Native project called "AwesomeProject":
```
react-native init AwesomeProject
```
This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Create React Native App, or if you're adding Android support to an existing React Native project (see [Platform Specific Code](docs/platform-specific-code.html)).
<block class="native mac windows linux android" />
## Preparing the Android device
You will need an Android device to run your React Native Android app. This can be either a physical Android device, or more commonly, you can use an Android Virtual Device which allows you to emulate an Android device on your computer.
Either way, you will need to prepare the device to run Android apps for development.
### Using a physical device
If you have a physical Android device, you can use it for development in place of an AVD by plugging it in to your computer using a USB cable and following the instructions [here](docs/running-on-device.html).
### Using a virtual device
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:
![Android Studio AVD Manager](img/react-native-tools-avd.png)
If you have just installed Android Studio, you will likely need to [create a new AVD](https://developer.android.com/studio/run/managing-avds.html). Select "Create Virtual Device...", then pick any Phone from the list and click "Next".
<block class="native windows android" />
![Android Studio AVD Manager](img/CreateAVDWindows.png)
<block class="native mac android" />
![Android Studio AVD Manager](img/CreateAVDMacOS.png)
<block class="native mac windows linux android" />
Select the "x86 Images" tab, then look for the **Marshmallow** API Level 23, x86_64 ABI image with a Android 6.0 (Google APIs) target.
<block class="native linux android" />
> We recommend configuring [VM acceleration](https://developer.android.com/studio/run/emulator-acceleration.html#vm-linux) on your system to improve performance. Once you've followed those instructions, go back to the AVD Manager.
<block class="native windows android" />
![Install HAXM](img/CreateAVDx86Windows.png)
> If you don't have HAXM installed, click on "Install HAXM" or follow [these instructions](https://software.intel.com/en-us/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-windows) to set it up, then go back to the AVD Manager.
![AVD List](img/AVDManagerWindows.png)
<block class="native mac android" />
![Install HAXM](img/CreateAVDx86MacOS.png)
> If you don't have HAXM installed, follow [these instructions](https://software.intel.com/en-us/android/articles/installation-instructions-for-intel-hardware-accelerated-execution-manager-mac-os-x) to set it up, then go back to the AVD Manager.
![AVD List](img/AVDManagerMacOS.png)
<block class="native mac windows linux android" />
Click "Next" then "Finish" to create your AVD. At this point you should be able to click on the green triangle button next to your AVD to launch it, then proceed to the next step.
<block class="native mac ios" />
## Running your React Native application
Run `react-native run-ios` inside your React Native project folder:
```
cd AwesomeProject
react-native run-ios
```
You should see your new app running in the iOS Simulator shortly.
![AwesomeProject on iOS](img/iOSSuccess.png)
`react-native run-ios` is just one way to run your app. You can also run it directly from within Xcode or [Nuclide](https://nuclide.io/).
> If you can't get this to work, see the [Troubleshooting](docs/troubleshooting.html#content) page.
### Running on a device
The above command will automatically run your app on the iOS Simulator by default. If you want to run the app on an actual physical iOS device, please follow the instructions [here](docs/running-on-device.html).
<block class="native mac windows linux android" />
## Running your React Native application
Run `react-native run-android` inside your React Native project folder:
```
cd AwesomeProject
react-native run-android
```
If everything is set up correctly, you should see your new app running in your Android emulator shortly.
<block class="native mac android" />
![AwesomeProject on Android](img/AndroidSuccessMacOS.png)
<block class="native windows android" />
![AwesomeProject on Android](img/AndroidSuccessWindows.png)
<block class="native mac windows linux android" />
`react-native run-android` is just one way to run your app - you can also run it directly from within Android Studio or [Nuclide](https://nuclide.io/).
> If you can't get this to work, see the [Troubleshooting](docs/troubleshooting.html#content) page.
<block class="native mac ios android" />
### Modifying your app
Now that you have successfully run the app, let's modify it.
<block class="native mac ios" />
- Open `App.js` in your text editor of choice and edit some lines.
- Hit `⌘R` in your iOS Simulator to reload the app and see your changes!
<block class="native mac android" />
- Open `App.js` in your text editor of choice and edit some lines.
- Press the `R` key twice or select `Reload` from the Developer Menu (`⌘M`) to see your changes!
<block class="native windows linux android" />
### Modifying your app
Now that you have successfully run the app, let's modify it.
- Open `App.js` in your text editor of choice and edit some lines.
- Press the `R` key twice or select `Reload` from the Developer Menu (`Ctrl + M`) to see your changes!
<block class="native mac ios android" />
### That's it!
Congratulations! You've successfully run and modified your first React Native app.
<center><img src="img/react-native-congratulations.png" width="150"></img></center>
<block class="native windows linux android" />
### That's it!
Congratulations! You've successfully run and modified your first React Native app.
<center><img src="img/react-native-congratulations.png" width="150"></img></center>
<block class="native mac ios" />
## Now what?
- Turn on [Live Reload](docs/debugging.html#reloading-javascript) in the Developer Menu. Your app will now reload automatically whenever you save any changes!
- If you want to add this new React Native code to an existing application, check out the [Integration guide](docs/integration-with-existing-apps.html).
If you're curious to learn more about React Native, continue on
to the [Tutorial](docs/tutorial.html).
<block class="native windows linux mac android" />
## Now what?
- Turn on [Live Reload](docs/debugging.html#reloading-javascript) in the Developer Menu. Your app will now reload automatically whenever you save any changes!
- If you want to add this new React Native code to an existing application, check out the [Integration guide](docs/integration-with-existing-apps.html).
If you're curious to learn more about React Native, continue on
to the [Tutorial](docs/tutorial.html).
<script>
function displayTab(type, value) {
var container = document.getElementsByTagName('block')[0].parentNode;
container.className = 'display-' + type + '-' + value + ' ' +
container.className.replace(RegExp('display-' + type + '-[a-z]+ ?'), '');
event && event.preventDefault();
}
function convertBlocks() {
// Convert <div>...<span><block /></span>...</div>
// Into <div>...<block />...</div>
var blocks = document.querySelectorAll('block');
for (var i = 0; i < blocks.length; ++i) {
var block = blocks[i];
var span = blocks[i].parentNode;
var container = span.parentNode;
container.insertBefore(block, span);
container.removeChild(span);
}
// Convert <div>...<block />content<block />...</div>
// Into <div>...<block>content</block><block />...</div>
blocks = document.querySelectorAll('block');
for (var i = 0; i < blocks.length; ++i) {
var block = blocks[i];
while (
block.nextSibling &&
block.nextSibling.tagName !== 'BLOCK'
) {
block.appendChild(block.nextSibling);
}
}
}
function guessPlatformAndOS() {
if (!document.querySelector('block')) {
return;
}
// If we are coming to the page with a hash in it (i.e. from a search, for example), try to get
// us as close as possible to the correct platform and dev os using the hashtag and block walk up.
var foundHash = false;
if (
window.location.hash !== '' &&
window.location.hash !== 'content'
) {
// content is default
var hashLinks = document.querySelectorAll(
'a.hash-link'
);
for (
var i = 0;
i < hashLinks.length && !foundHash;
++i
) {
if (hashLinks[i].hash === window.location.hash) {
var parent = hashLinks[i].parentElement;
while (parent) {
if (parent.tagName === 'BLOCK') {
// Could be more than one target os and dev platform, but just choose some sort of order
// of priority here.
// Dev OS
if (parent.className.indexOf('mac') > -1) {
displayTab('os', 'mac');
foundHash = true;
} else if (
parent.className.indexOf('linux') > -1
) {
displayTab('os', 'linux');
foundHash = true;
} else if (
parent.className.indexOf('windows') > -1
) {
displayTab('os', 'windows');
foundHash = true;
} else {
break;
}
// Target Platform
if (parent.className.indexOf('ios') > -1) {
displayTab('platform', 'ios');
foundHash = true;
} else if (
parent.className.indexOf('android') > -1
) {
displayTab('platform', 'android');
foundHash = true;
} else {
break;
}
// Guide
if (parent.className.indexOf('native') > -1) {
displayTab('guide', 'native');
foundHash = true;
} else if (
parent.className.indexOf('quickstart') > -1
) {
displayTab('guide', 'quickstart');
foundHash = true;
} else {
break;
}
break;
}
parent = parent.parentElement;
}
}
}
}
// Do the default if there is no matching hash
if (!foundHash) {
var isMac = navigator.platform === 'MacIntel';
var isWindows = navigator.platform === 'Win32';
displayTab('platform', isMac ? 'ios' : 'android');
displayTab(
'os',
isMac ? 'mac' : isWindows ? 'windows' : 'linux'
);
displayTab('guide', 'quickstart');
displayTab('language', 'objc');
}
}
convertBlocks();
guessPlatformAndOS();
</script>

View File

@ -1,51 +0,0 @@
---
id: handling-text-input
title: Handling Text Input
layout: docs
category: The Basics
permalink: docs/handling-text-input.html
next: handling-touches
previous: flexbox
---
[`TextInput`](docs/textinput.html#content) is a basic component that allows the user to enter text. It has an `onChangeText` prop that takes
a function to be called every time the text changed, and an `onSubmitEditing` prop that takes a function to be called when the text is submitted.
For example, let's say that as the user types, you're translating their words into a different language. In this new language, every single word is written the same way: 🍕. So the sentence "Hello there Bob" would be translated
as "🍕🍕🍕".
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';
export default class PizzaTranslator extends Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
return (
<View style={{padding: 10}}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(text) => this.setState({text})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text.split(' ').map((word) => word && '🍕').join(' ')}
</Text>
</View>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => PizzaTranslator);
```
In this example, we store `text` in the state, because it changes over time.
There are a lot more things you might want to do with a text input. For example, you could validate the text inside while the user types. For more detailed examples, see the [React docs on controlled components](https://facebook.github.io/react/docs/forms.html), or the [reference docs for TextInput](docs/textinput.html).
Text input is one of the ways the user interacts with the app. Next, let's look at another type of input and [learn how to handle touches](docs/handling-touches.html).

View File

@ -1,183 +0,0 @@
---
id: handling-touches
title: Handling Touches
layout: docs
category: The Basics
permalink: docs/handling-touches.html
next: using-a-scrollview
previous: handling-text-input
---
Users interact with mobile apps mainly through touch. They can use a combination of gestures, such as tapping on a button, scrolling a list, or zooming on a map. React Native provides components to handle all sorts of common gestures, as well as a comprehensive [gesture responder system](docs/gesture-responder-system.html) to allow for more advanced gesture recognition, but the one component you will most likely be interested in is the basic Button.
## Displaying a basic button
[Button](docs/button.html) provides a basic button component that is rendered nicely on all platforms. The minimal example to display a button looks like this:
```javascript
<Button
onPress={() => { Alert.alert('You tapped the button!')}}
title="Press Me"
/>
```
This will render a blue label on iOS, and a blue rounded rectangle with white text on Android. Pressing the button will call the "onPress" function, which in this case displays an alert popup. If you like, you can specify a "color" prop to change the color of your button.
![](img/Button.png)
Go ahead and play around with the `Button` component using the example below. You can select which platform your app is previewed in by clicking on the toggle in the bottom right, then click on "Tap to Play" to preview the app.
```SnackPlayer?name=Button%20Basics
import React, { Component } from 'react';
import { Alert, AppRegistry, Button, StyleSheet, View } from 'react-native';
export default class ButtonBasics extends Component {
_onPressButton() {
Alert.alert('You tapped the button!')
}
render() {
return (
<View style={styles.container}>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Press Me"
/>
</View>
<View style={styles.buttonContainer}>
<Button
onPress={this._onPressButton}
title="Press Me"
color="#841584"
/>
</View>
<View style={styles.alternativeLayoutButtonContainer}>
<Button
onPress={this._onPressButton}
title="This looks great!"
/>
<Button
onPress={this._onPressButton}
title="OK!"
color="#841584"
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
buttonContainer: {
margin: 20
},
alternativeLayoutButtonContainer: {
margin: 20,
flexDirection: 'row',
justifyContent: 'space-between'
}
})
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => ButtonBasics);
```
## Touchables
If the basic button doesn't look right for your app, you can build your own button using any of the "Touchable" components provided by React Native. The "Touchable" components provide the capability to capture tapping gestures, and can display feedback when a gesture is recognized. These components do not provide any default styling, however, so you will need to do a bit of work to get them looking nicely in your app.
Which "Touchable" component you use will depend on what kind of feedback you want to provide:
- Generally, you can use [**TouchableHighlight**](docs/touchablehighlight.html) anywhere you would use a button or link on web. The view's background will be darkened when the user presses down on the button.
- You may consider using [**TouchableNativeFeedback**](docs/touchablenativefeedback.html) on Android to display ink surface reaction ripples that respond to the user's touch.
- [**TouchableOpacity**](docs/touchableopacity.html) can be used to provide feedback by reducing the opacity of the button, allowing the background to be seen through while the user is pressing down.
- If you need to handle a tap gesture but you don't want any feedback to be displayed, use [**TouchableWithoutFeedback**](docs/touchablewithoutfeedback.html).
In some cases, you may want to detect when a user presses and holds a view for a set amount of time. These long presses can be handled by passing a function to the `onLongPress` props of any of the "Touchable" components.
Let's see all of these in action:
```SnackPlayer?platform=android&name=Touchables
import React, { Component } from 'react';
import { Alert, AppRegistry, Platform, StyleSheet, Text, TouchableHighlight, TouchableOpacity, TouchableNativeFeedback, TouchableWithoutFeedback, View } from 'react-native';
export default class Touchables extends Component {
_onPressButton() {
Alert.alert('You tapped the button!')
}
_onLongPressButton() {
Alert.alert('You long-pressed the button!')
}
render() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={this._onPressButton} underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableHighlight</Text>
</View>
</TouchableHighlight>
<TouchableOpacity onPress={this._onPressButton}>
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableOpacity</Text>
</View>
</TouchableOpacity>
<TouchableNativeFeedback
onPress={this._onPressButton}
background={Platform.OS === 'android' ? TouchableNativeFeedback.SelectableBackground() : ''}>
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableNativeFeedback</Text>
</View>
</TouchableNativeFeedback>
<TouchableWithoutFeedback
onPress={this._onPressButton}
>
<View style={styles.button}>
<Text style={styles.buttonText}>TouchableWithoutFeedback</Text>
</View>
</TouchableWithoutFeedback>
<TouchableHighlight onPress={this._onPressButton} onLongPress={this._onLongPressButton} underlayColor="white">
<View style={styles.button}>
<Text style={styles.buttonText}>Touchable with Long Press</Text>
</View>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
paddingTop: 60,
alignItems: 'center'
},
button: {
marginBottom: 30,
width: 260,
alignItems: 'center',
backgroundColor: '#2196F3'
},
buttonText: {
padding: 20,
color: 'white'
}
})
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => Touchables);
```
## Scrolling lists, swiping pages, and pinch-to-zoom
Another gesture commonly used in mobile apps is the swipe or pan. This gesture allows the user to scroll through a list of items, or swipe through pages of content. In order to handle these and other gestures, we'll learn [how to use a ScrollView](docs/using-a-scrollview.html) next.

View File

@ -1,149 +0,0 @@
---
id: headless-js-android
title: Headless JS
layout: docs
category: Guides (Android)
permalink: docs/headless-js-android.html
next: signed-apk-android
previous: custom-webview-android
---
Headless JS is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music.
## The JS API
A task is a simple async function that you register on `AppRegistry`, similar to registering React applications:
```js
AppRegistry.registerHeadlessTask('SomeTaskName', () => require('SomeTaskName'));
```
Then, in `SomeTaskName.js`:
```js
module.exports = async (taskData) => {
// do stuff
}
```
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).
## The Java API
Yes, this does still require some native code, but it's pretty thin. You need to extend `HeadlessJsTaskService` and override `getTaskConfig`, e.g.:
```java
public class MyTaskService extends HeadlessJsTaskService {
@Override
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
return new HeadlessJsTaskConfig(
"SomeTaskName",
Arguments.fromBundle(extras),
5000, // timeout for the task
false // optional: defines whether or not the task is allowed in foreground. Default is false
);
}
return null;
}
}
```
Then add the service to your `AndroidManifest.xml` file:
```
<service android:name="com.example.MyTaskService" />
```
Now, whenever you [start your service][0], e.g. as a periodic task or in response to some system event / broadcast, JS will spin up, run your task, then spin down.
Example:
```java
Intent service = new Intent(getApplicationContext(), MyTaskService.class);
Bundle bundle = new Bundle();
bundle.putString("foo", "bar");
service.putExtras(bundle);
getApplicationContext().startService(service);
```
## Caveats
* By default, your app will crash if you try to run a task while the app is in the foreground. This is to prevent developers from shooting themselves in the foot by doing a lot of work in a task and slowing the UI. You can pass a fourth `boolean` argument to control this behaviour.
* If you start your service from a `BroadcastReceiver`, make sure to call `HeadlessJsTaskService.acquireWakeLockNow()` before returning from `onReceive()`.
## Example Usage
Service can be started from Java API. First you need to decide when the service should be started and implement your solution accordingly. Here is a simple example that reacts to network connection change.
Following lines shows part of Android manifest file for registering broadcast receiver.
```xml
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
```
Broadcast receiver then handles intent that was broadcasted in onReceive function. This is a great place to check whether your app is on foreground or not. If app is not on foreground we can prepare our intent to be started, with no information or additional information bundled using `putExtra` (keep in mind bundle can handle only parcelable values). In the end service is started and wakelock is acquired.
```java
public class NetworkChangeReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
/**
This part will be called everytime network connection is changed
e.g. Connected -> Not Connected
**/
if (!isAppOnForeground((context))) {
/**
We will start our service and send extra info about
network connections
**/
boolean hasInternet = isNetworkAvailable(context);
Intent serviceIntent = new Intent(context, MyTaskService.class);
serviceIntent.putExtra("hasInternet", hasInternet);
context.startService(serviceIntent);
HeadlessJsTaskService.acquireWakeLockNow(context);
}
}
private boolean isAppOnForeground(Context context) {
/**
We need to check if app is in foreground otherwise the app will crash.
http://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not
**/
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses =
activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance ==
ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND &&
appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return (netInfo != null && netInfo.isConnected());
}
}
```
[0]: https://developer.android.com/reference/android/content/Context.html#startService(android.content.Intent)

View File

@ -1,68 +0,0 @@
---
id: height-and-width
title: Height and Width
layout: docs
category: The Basics
permalink: docs/height-and-width.html
next: flexbox
previous: style
---
A component's height and width determine its size on the screen.
#### Fixed Dimensions
The simplest way to set the dimensions of a component is by adding a fixed `width` and `height` to style. All dimensions in React Native are unitless, and represent density-independent pixels.
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class FixedDimensionsBasics extends Component {
render() {
return (
<View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
<View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => FixedDimensionsBasics);
```
Setting dimensions this way is common for components that should always render at exactly the same size, regardless of screen dimensions.
#### Flex Dimensions
Use `flex` in a component's style to have the component expand and shrink dynamically based on available space. Normally you will use `flex: 1`, which tells a component to fill all available space, shared evenly amongst each other component with the same parent. The larger the `flex` given, the higher the ratio of space a component will take compared to its siblings.
> A component can only expand to fill available space if its parent has dimensions greater than 0. If a parent does not have either a fixed `width` and `height` or `flex`, the parent will have dimensions of 0 and the `flex` children will not be visible.
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, View } from 'react-native';
export default class FlexDimensionsBasics extends Component {
render() {
return (
// Try removing the `flex: 1` on the parent View.
// The parent will not have dimensions, so the children can't expand.
// What if you add `height: 300` instead of `flex: 1`?
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}} />
<View style={{flex: 2, backgroundColor: 'skyblue'}} />
<View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('AwesomeProject', () => FlexDimensionsBasics);
```
After you can control a component's size, the next step is to [learn how to lay it out on the screen](docs/flexbox.html).

View File

@ -1,236 +0,0 @@
---
id: image-style-props
title: Image Style Props
layout: docs
category: APIs
permalink: docs/image-style-props.html
next: null
previous: text-style-props
---
[Image](docs/image.html) style props.
### Props
- [Layout Props...](docs/layout-props.html#props)
- [Shadow Props...](docs/shadow-props.html#props)
- [Transforms...](docs/transforms.html#props)
- [`borderTopRightRadius`](docs/image-style-props.html#bordertoprightradius)
- [`backfaceVisibility`](docs/image-style-props.html#backfacevisibility)
- [`borderBottomLeftRadius`](docs/image-style-props.html#borderbottomleftradius)
- [`borderBottomRightRadius`](docs/image-style-props.html#borderbottomrightradius)
- [`borderColor`](docs/image-style-props.html#bordercolor)
- [`borderRadius`](docs/image-style-props.html#borderradius)
- [`borderTopLeftRadius`](docs/image-style-props.html#bordertopleftradius)
- [`backgroundColor`](docs/image-style-props.html#backgroundcolor)
- [`borderWidth`](docs/image-style-props.html#borderwidth)
- [`opacity`](docs/image-style-props.html#opacity)
- [`overflow`](docs/image-style-props.html#overflow)
- [`resizeMode`](docs/image-style-props.html#resizemode)
- [`tintColor`](docs/image-style-props.html#tintcolor)
- [`overlayColor`](docs/image-style-props.html#overlaycolor)
---
# Reference
## Props
### `borderTopRightRadius`
| Type | Required |
| - | - |
| number | No |
---
### `backfaceVisibility`
| Type | Required |
| - | - |
| enum('visible', 'hidden') | No |
---
### `borderBottomLeftRadius`
| Type | Required |
| - | - |
| number | No |
---
### `borderBottomRightRadius`
| Type | Required |
| - | - |
| number | No |
---
### `borderColor`
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
---
### `borderRadius`
| Type | Required |
| - | - |
| number | No |
---
### `borderTopLeftRadius`
| Type | Required |
| - | - |
| number | No |
---
### `backgroundColor`
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
---
### `borderWidth`
| Type | Required |
| - | - |
| number | No |
---
### `opacity`
| Type | Required |
| - | - |
| number | No |
---
### `overflow`
| Type | Required |
| - | - |
| enum('visible', 'hidden') | No |
---
### `resizeMode`
| Type | Required |
| - | - |
| Object.keys(ImageResizeMode) | No |
---
### `tintColor`
Changes the color of all the non-transparent pixels to the tintColor.
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
---
### `overlayColor`
When the image has rounded corners, specifying an overlayColor will
cause the remaining space in the corners to be filled with a solid color.
This is useful in cases which are not supported by the Android
implementation of rounded corners:
- Certain resize modes, such as 'contain'
- Animated GIFs
A typical way to use this prop is with images displayed on a solid
background and setting the `overlayColor` to the same color
as the background.
For details of how this works under the hood, see
http://frescolib.org/docs/rounded-corners-and-circles.html
| Type | Required | Platform |
| - | - | - |
| string | No | Android |

View File

@ -1,471 +0,0 @@
---
id: image
title: Image
layout: docs
category: components
permalink: docs/image.html
next: keyboardavoidingview
previous: flatlist
---
A React component for displaying different types of images,
including network images, static resources, temporary local images, and
images from local disk, such as the camera roll.
This example shows fetching and displaying an image from local storage
as well as one from network and even from data provided in the `'data:'` uri scheme.
> Note that for network and data images, you will need to manually specify the dimensions of your image!
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, View, Image } from 'react-native';
export default class DisplayAnImage extends Component {
render() {
return (
<View>
<Image
source={require('./img/favicon.png')}
/>
<Image
style={{width: 50, height: 50}}
source={{uri: 'https://facebook.github.io/react-native/img/favicon.png'}}
/>
<Image
style={{width: 66, height: 58}}
source={{uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAEXRFWHRTb2Z0d2FyZQBwbmdjcnVzaEB1SfMAAABQSURBVGje7dSxCQBACARB+2/ab8BEeQNhFi6WSYzYLYudDQYGBgYGBgYGBgYGBgYGBgZmcvDqYGBgmhivGQYGBgYGBgYGBgYGBgYGBgbmQw+P/eMrC5UTVAAAAABJRU5ErkJggg=='}}
/>
</View>
);
}
}
// skip this line if using Create React Native App
AppRegistry.registerComponent('DisplayAnImage', () => DisplayAnImage);
```
You can also add `style` to an image:
```ReactNativeWebPlayer
import React, { Component } from 'react';
import { AppRegistry, View, Image, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
stretch: {
width: 50,
height: 200
}
});
export default class DisplayAnImageWithStyle extends Component {
render() {
return (
<View>
<Image
style={styles.stretch}
source={require('./img/favicon.png')}
/>
</View>
);
}
}
// skip these lines if using Create React Native App
AppRegistry.registerComponent(
'DisplayAnImageWithStyle',
() => DisplayAnImageWithStyle
);
```
### GIF and WebP support on Android
When building your own native code, GIF and WebP are not supported by default on Android.
You will need to add some optional modules in `android/app/build.gradle`, depending on the needs of your app.
```
dependencies {
// If your app supports Android versions before Ice Cream Sandwich (API level 14)
compile 'com.facebook.fresco:animated-base-support:1.3.0'
// For animated GIF support
compile 'com.facebook.fresco:animated-gif:1.3.0'
// For WebP support, including animated WebP
compile 'com.facebook.fresco:animated-webp:1.3.0'
compile 'com.facebook.fresco:webpsupport:1.3.0'
// For WebP support, without animations
compile 'com.facebook.fresco:webpsupport:1.3.0'
}
```
Also, if you use GIF with ProGuard, you will need to add this rule in `proguard-rules.pro` :
```
-keep class com.facebook.imagepipeline.animated.factory.AnimatedFactoryImpl {
public AnimatedFactoryImpl(com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory, com.facebook.imagepipeline.core.ExecutorSupplier);
}
```
### Props
- [`blurRadius`](docs/image.html#blurradius)
- [`onLayout`](docs/image.html#onlayout)
- [`onLoad`](docs/image.html#onload)
- [`onLoadEnd`](docs/image.html#onloadend)
- [`onLoadStart`](docs/image.html#onloadstart)
- [`resizeMode`](docs/image.html#resizemode)
- [`source`](docs/image.html#source)
- [`onError`](docs/image.html#onerror)
- [`testID`](docs/image.html#testid)
- [`resizeMethod`](docs/image.html#resizemethod)
- [`accessibilityLabel`](docs/image.html#accessibilitylabel)
- [`accessible`](docs/image.html#accessible)
- [`capInsets`](docs/image.html#capinsets)
- [`defaultSource`](docs/image.html#defaultsource)
- [`onPartialLoad`](docs/image.html#onpartialload)
- [`onProgress`](docs/image.html#onprogress)
- [`style`](docs/image.html#style)
### Methods
- [`getSize`](docs/image.html#getsize)
- [`prefetch`](docs/image.html#prefetch)
---
# Reference
## Props
### `blurRadius`
blurRadius: the blur radius of the blur filter added to the image
| Type | Required |
| - | - |
| number | No |
---
### `onLayout`
Invoked on mount and layout changes with
`{nativeEvent: {layout: {x, y, width, height}}}`.
| Type | Required |
| - | - |
| function | No |
---
### `onLoad`
Invoked when load completes successfully.
| Type | Required |
| - | - |
| function | No |
---
### `onLoadEnd`
Invoked when load either succeeds or fails.
| Type | Required |
| - | - |
| function | No |
---
### `onLoadStart`
Invoked on load start.
e.g., `onLoadStart={(e) => this.setState({loading: true})}`
| Type | Required |
| - | - |
| function | No |
---
### `resizeMode`
Determines how to resize the image when the frame doesn't match the raw
image dimensions.
- `cover`: Scale the image uniformly (maintain the image's aspect ratio)
so that both dimensions (width and height) of the image will be equal
to or larger than the corresponding dimension of the view (minus padding).
- `contain`: Scale the image uniformly (maintain the image's aspect ratio)
so that both dimensions (width and height) of the image will be equal to
or less than the corresponding dimension of the view (minus padding).
- `stretch`: Scale width and height independently, This may change the
aspect ratio of the src.
- `repeat`: Repeat the image to cover the frame of the view. The
image will keep it's size and aspect ratio. (iOS only)
| Type | Required |
| - | - |
| enum('cover', 'contain', 'stretch', 'repeat', 'center') | No |
---
### `source`
The image source (either a remote URL or a local file resource).
This prop can also contain several remote URLs, specified together with
their width and height and potentially with scale/other URI arguments.
The native side will then choose the best `uri` to display based on the
measured size of the image container. A `cache` property can be added to
control how networked request interacts with the local cache.
The currently supported formats are `png`, `jpg`, `jpeg`, `bmp`, `gif`,
`webp` (Android only), `psd` (iOS only).
| Type | Required |
| - | - |
| ImageSourcePropType | No |
---
### `onError`
Invoked on load error with `{nativeEvent: {error}}`.
| Type | Required |
| - | - |
| function | No |
---
### `testID`
A unique identifier for this element to be used in UI Automation
testing scripts.
| Type | Required |
| - | - |
| string | No |
---
### `resizeMethod`
The mechanism that should be used to resize the image when the image's dimensions
differ from the image view's dimensions. Defaults to `auto`.
- `auto`: Use heuristics to pick between `resize` and `scale`.
- `resize`: A software operation which changes the encoded image in memory before it
gets decoded. This should be used instead of `scale` when the image is much larger
than the view.
- `scale`: The image gets drawn downscaled or upscaled. Compared to `resize`, `scale` is
faster (usually hardware accelerated) and produces higher quality images. This
should be used if the image is smaller than the view. It should also be used if the
image is slightly bigger than the view.
More details about `resize` and `scale` can be found at http://frescolib.org/docs/resizing-rotating.html.
| Type | Required | Platform |
| - | - | - |
| enum('auto', 'resize', 'scale') | No | Android |
---
### `accessibilityLabel`
The text that's read by the screen reader when the user interacts with
the image.
| Type | Required | Platform |
| - | - | - |
| node | No | iOS |
---
### `accessible`
When true, indicates the image is an accessibility element.
| Type | Required | Platform |
| - | - | - |
| bool | No | iOS |
---
### `capInsets`
When the image is resized, the corners of the size specified
by `capInsets` will stay a fixed size, but the center content and borders
of the image will be stretched. This is useful for creating resizable
rounded buttons, shadows, and other resizable assets. More info in the
[official Apple documentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIImage_Class/index.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets).
| Type | Required | Platform |
| - | - | - |
| object: {top: number, left: number, bottom: number, right: number} | No | iOS |
---
### `defaultSource`
A static image to display while loading the image source.
- `uri` - a string representing the resource identifier for the image, which
should be either a local file path or the name of a static image resource
(which should be wrapped in the `require('./path/to/image.png')` function).
- `width`, `height` - can be specified if known at build time, in which case
these will be used to set the default `<Image/>` component dimensions.
- `scale` - used to indicate the scale factor of the image. Defaults to 1.0 if
unspecified, meaning that one image pixel equates to one display point / DIP.
- `number` - Opaque type returned by something like `require('./image.jpg')`.
| Type | Required | Platform |
| - | - | - |
| object: {uri: string,width: number,height: number,scale: number}, ,number | No | iOS |
---
### `onPartialLoad`
Invoked when a partial load of the image is complete. The definition of
what constitutes a "partial load" is loader specific though this is meant
for progressive JPEG loads.
| Type | Required | Platform |
| - | - | - |
| function | No | iOS |
---
### `onProgress`
Invoked on download progress with `{nativeEvent: {loaded, total}}`.
| Type | Required | Platform |
| - | - | - |
| function | No | iOS |
---
### `style`
| Type | Required |
| - | - |
| [style](docs/imagestyleproptypes.html) | No |
## Methods
### `getSize()`
```javascript
static getSize(uri: string, success: function, [failure]: function): void
```
Retrieve the width and height (in pixels) of an image prior to displaying it. This method can fail if the image cannot be found, or fails to download.
In order to retrieve the image dimensions, the image may first need to be loaded or downloaded, after which it will be cached. This means that in principle you could use this method to preload images, however it is not optimized for that purpose, and may in future be implemented in a way that does not fully load/download the image data. A proper, supported way to preload images will be provided as a separate API.
Does not work for static image resources.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| uri | string | Yes | The location of the image. |
| success | function | Yes | The function that will be called if the image was successfully found and widthand height retrieved. |
| failure | function | No | The function that will be called if there was an error, such as failing toto retrieve the image. |
---
### `prefetch()`
```javascript
Image.prefetch(url: string):
```
Prefetches a remote image for later use by downloading it to the disk
cache
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| url | string | Yes | The remote location of the image. |

View File

@ -1,45 +0,0 @@
---
id: imageeditor
title: ImageEditor
layout: docs
category: APIs
permalink: docs/imageeditor.html
next: imagepickerios
previous: geolocation
---
### Methods
- [`cropImage`](docs/imageeditor.html#cropimage)
---
# Reference
## Methods
### `cropImage()`
```javascript
ImageEditor.cropImage(uri, cropData, success, failure)
```
Crop the image specified by the URI param. If URI points to a remote image, it will be downloaded automatically. If the image cannot be loaded/downloaded, the failure callback will be called.
If the cropping process is successful, the resultant cropped image will be stored in the ImageStore, and the URI returned in the success callback will point to the image in the store. Remember to delete the cropped image from the ImageStore when you are done with it.
**Crop Data Options:**
The following options can be used with the `cropData` parameter:
| Name | Type | Required | Description |
| - | - | - | - |
| offset | `{ x: number, y: number}` | Yes | The top-left corner of the cropped image, specified in the original image's coordinate space. |
| size | `{ width: number, height: number }` | Yes | The size (dimensions) of the cropped image, specified in the original image's coordinate space. |
| displaySize | `{ width: number, height: number }` | No | Size to scale the cropped image to. |
| resizeMode | `enum( contain: string, cover: string, stretch: string }` | No | The resizing mode to use when scaling the image. If the `displaySize` param is not specified, this has no effect. |

View File

@ -1,66 +0,0 @@
---
id: imagepickerios
title: ImagePickerIOS
layout: docs
category: APIs
permalink: docs/imagepickerios.html
next: imagestore
previous: imageeditor
---
### Methods
- [`canRecordVideos`](docs/imagepickerios.html#canrecordvideos)
- [`canUseCamera`](docs/imagepickerios.html#canusecamera)
- [`openCameraDialog`](docs/imagepickerios.html#opencameradialog)
- [`openSelectDialog`](docs/imagepickerios.html#openselectdialog)
---
# Reference
## Methods
### `canRecordVideos()`
```javascript
ImagePickerIOS.canRecordVideos(callback)
```
---
### `canUseCamera()`
```javascript
ImagePickerIOS.canUseCamera(callback)
```
---
### `openCameraDialog()`
```javascript
ImagePickerIOS.openCameraDialog(config, successCallback, cancelCallback)
```
---
### `openSelectDialog()`
```javascript
ImagePickerIOS.openSelectDialog(config, successCallback, cancelCallback)
```

View File

@ -1,104 +0,0 @@
---
id: imagestore
title: ImageStore
layout: docs
category: APIs
permalink: docs/imagestore.html
next: interactionmanager
previous: imagepickerios
---
### Methods
- [`hasImageForTag`](docs/imagestore.html#hasimagefortag)
- [`removeImageForTag`](docs/imagestore.html#removeimagefortag)
- [`addImageFromBase64`](docs/imagestore.html#addimagefrombase64)
- [`getBase64ForTag`](docs/imagestore.html#getbase64fortag)
---
# Reference
## Methods
### `hasImageForTag()`
```javascript
ImageStore.hasImageForTag(uri, callback)
```
Check if the ImageStore contains image data for the specified URI.
@platform ios
---
### `removeImageForTag()`
```javascript
ImageStore.removeImageForTag(uri)
```
Delete an image from the ImageStore. Images are stored in memory and
must be manually removed when you are finished with them, otherwise they
will continue to use up RAM until the app is terminated. It is safe to
call `removeImageForTag()` without first calling `hasImageForTag()`, it
will simply fail silently.
@platform ios
---
### `addImageFromBase64()`
```javascript
ImageStore.addImageFromBase64(base64ImageData, success, failure)
```
Stores a base64-encoded image in the ImageStore, and returns a URI that
can be used to access or display the image later. Images are stored in
memory only, and must be manually deleted when you are finished with
them by calling `removeImageForTag()`.
Note that it is very inefficient to transfer large quantities of binary
data between JS and native code, so you should avoid calling this more
than necessary.
@platform ios
---
### `getBase64ForTag()`
```javascript
ImageStore.getBase64ForTag(uri, success, failure)
```
Retrieves the base64-encoded data for an image in the ImageStore. If the
specified URI does not match an image in the store, the failure callback
will be called.
Note that it is very inefficient to transfer large quantities of binary
data between JS and native code, so you should avoid calling this more
than necessary. To display an image in the ImageStore, you can just pass
the URI to an `<Image/>` component; there is no need to retrieve the
base64 data.

View File

@ -1,68 +0,0 @@
---
id: improvingux
title: Improving User Experience
layout: docs
category: Guides
permalink: docs/improvingux.html
next: timers
previous: accessibility
---
Building apps for mobile platforms is nuanced, there are many little details that developers coming from a web background often do not consider. This guide is intended to explain some of these nuances and demonstrate how you might factor them in to your application.
> We are improving and adding more details to this page. If you'd like to help out, chime in at [react-native/14979](https://github.com/facebook/react-native/issues/14979).
## Topics index
- [Configure text inputs](#configure-text-inputs)
- [Manage layout when keyboard is visible](#manage-layout-when-keyboard-is-visible)
- [Make tappable areas larger](#make-tappable-areas-larger)
- [Use Android Ripple](#use-android-ripple)
- [Learn More](#learn-more)
-------------------------------------------------------------------------------
## Configure text inputs
Entering text on touch phone is a challange - small screen, software keyboard. But based on what kind of data you need, you can make it easier by properly configuring the text inputs:
* Focus the first field automatically
* Use placeholder text as an example of expected data format
* Enable or disable autocapitalization and autocorrect
* Choose keyboard type (e.g. email, numeric)
* Make sure the return button focuses the next field or submits the form
Check out [`TextInput` docs](docs/textinput.html) for more configuration options.
<video src="img/textinput.mp4" autoplay loop width="320" height="430"></video>
[Try it on your phone](https://snack.expo.io/H1iGt2vSW)
## Manage layout when keyboard is visible
Software keyboard takes almost half of the screen. If you have interactive elements that can get covered by the keyboard, make sure they are still accessible by using the [`KeyboardAvoidingView` component](docs/keyboardavoidingview.html).
<video src="img/keyboardavoidingview.mp4" autoplay loop width="320" height="448"></video>
[Try it on your phone](https://snack.expo.io/ryxRkwnrW)
## Make tappable areas larger
On mobile phones it's hard to be very precise when pressing buttons. Make sure all interactive elements are 44x44 or larger. One way to do this is to leave enough space for the element, `padding`, `minWidth` and `minHeight` style values can be useful for that. Alternatively, you can use [`hitSlop` prop](docs/touchablewithoutfeedback.html#hitslop) to increase interactive area without affecting the layout. Here's a demo:
<video src="img/hitslop.mp4" autoplay loop width="320" height="120"></video>
[Try it on your phone](https://snack.expo.io/rJPwCt4HZ)
## Use Android Ripple
Android API 21+ uses the material design ripple to provide user with feedback when they touch an interactable area on the screen. React Native exposes this through the [`TouchableNativeFeedback` component](docs/touchablenativefeedback.html). Using this touchable effect instead of opacity or highlight will often make your app feel much more fitting on the platform. That said, you need to be careful when using it because it doesn't work on iOS or on Android API < 21, so you will need to fallback to using one of the other Touchable components on iOS. You can use a library like [react-native-platform-touchable](https://github.com/react-community/react-native-platform-touchable) to handle the platform differences for you.
<video src="img/ripple.mp4" autoplay loop width="320"></video>
[Try it on your phone](https://snack.expo.io/SJywqe3rZ)
# Learn more
[Material Design](https://material.io/) and [Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/overview/design-principles/) are great resources for learning more about designing for mobile platforms.

View File

@ -1,944 +0,0 @@
---
id: integration-with-existing-apps
title: Integration with Existing Apps
layout: docs
category: Guides
permalink: docs/integration-with-existing-apps.html
next: running-on-device
previous: colors
---
<style>
.toggler li {
display: inline-block;
position: relative;
top: 1px;
padding: 10px;
margin: 0px 2px 0px 2px;
border: 1px solid #05A5D1;
border-bottom-color: transparent;
border-radius: 3px 3px 0px 0px;
color: #05A5D1;
background-color: transparent;
font-size: 0.99em;
cursor: pointer;
}
.toggler li:first-child {
margin-left: 0;
}
.toggler li:last-child {
margin-right: 0;
}
.toggler ul {
width: 100%;
display: inline-block;
list-style-type: none;
margin: 0;
border-bottom: 1px solid #05A5D1;
cursor: default;
}
@media screen and (max-width: 960px) {
.toggler li,
.toggler li:first-child,
.toggler li:last-child {
display: block;
border-bottom-color: #05A5D1;
border-radius: 3px;
margin: 2px 0px 2px 0px;
}
.toggler ul {
border-bottom: 0;
}
}
.toggler a {
display: inline-block;
padding: 10px 5px;
margin: 2px;
border: 1px solid #05A5D1;
border-radius: 3px;
text-decoration: none !important;
}
.display-language-objc .toggler .button-objc,
.display-language-swift .toggler .button-swift,
.display-language-android .toggler .button-android {
background-color: #05A5D1;
color: white;
}
block { display: none; }
.display-language-objc .objc,
.display-language-swift .swift,
.display-language-android .android {
display: block;
}
</style>
React Native is great when you are starting a new mobile app from scratch. However, it also works well for adding a single view or user flow to existing native applications. With a few steps, you can add new React Native based features, screens, views, etc.
The specific steps are different depending on what platform you're targeting.
<div class="toggler">
<ul role="tablist" >
<li id="objc" class="button-objc" aria-selected="false" role="tab" tabindex="0" aria-controls="objctab" onclick="displayTab('language', 'objc')">
iOS (Objective-C)
</li>
<li id="swift" class="button-swift" aria-selected="false" role="tab" tabindex="0" aria-controls="swifttab" onclick="displayTab('language', 'swift')">
iOS (Swift)
</li>
<li id="android" class="button-android" aria-selected="false" role="tab" tabindex="0" aria-controls="androidtab" onclick="displayTab('language', 'android')">
Android (Java)
</li>
</ul>
</div>
<block class="objc swift android" />
## Key Concepts
<block class="objc swift" />
The keys to integrating React Native components into your iOS application are to:
1. Set up React Native dependencies and directory structure.
2. Understand what React Native components you will use in your app.
3. Add these components as dependencies using CocoaPods.
4. Develop your React Native components in JavaScript.
5. Add a `RCTRootView` to your iOS app. This view will serve as the container for your React Native component.
6. Start the React Native server and run your native application.
7. Verify that the React Native aspect of your application works as expected.
<block class="android" />
The keys to integrating React Native components into your Android application are to:
1. Set up React Native dependencies and directory structure.
2. Develop your React Native components in JavaScript.
3. Add a `ReactRootView` to your Android app. This view will serve as the container for your React Native component.
4. Start the React Native server and run your native application.
5. Verify that the React Native aspect of your application works as expected.
<block class="objc swift android" />
## Prerequisites
<block class="objc swift" />
Follow the instructions for building apps with native code from the [Getting Started guide](docs/getting-started.html) to configure your development environment for building React Native apps for iOS.
### 1. Set up directory structure
To ensure a smooth experience, create a new folder for your integrated React Native project, then copy your existing iOS project to a `/ios` subfolder.
<block class="android" />
Follow the instructions for building apps with native code from the [Getting Started guide](docs/getting-started.html) to configure your development environment for building React Native apps for Android.
### 1. Set up directory structure
To ensure a smooth experience, create a new folder for your integrated React Native project, then copy your existing Android project to a `/android` subfolder.
<block class="objc swift android" />
### 2. Install JavaScript dependencies
Go to the root directory for your project and create a new `package.json` file with the following contents:
```
{
"name": "MyReactNativeApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start"
}
}
```
Next, you will install the `react` and `react-native` packages. Open a terminal or command prompt, then navigate to the root directory for your project and type the following commands:
```
$ npm install --save react@16.0.0-beta.5 react-native
```
> Make sure you use the same React version as specified in the [React Native package.json](https://github.com/facebook/react-native/blob/master/package.json) for your release. This will only be necessary as long as React Native depends on a pre-release version of React.
This will create a new `/node_modules` folder in your project's root directory. This folder stores all the JavaScript dependencies required to build your project.
<block class="objc swift" />
### 3. Install CocoaPods
[CocoaPods](http://cocoapods.org) is a package management tool for iOS and macOS development. We use it to add the actual React Native framework code locally into your current project.
We recommend installing CocoaPods using [Homebrew](http://brew.sh/).
```
$ brew install cocoapods
```
> It is technically possible not to use CocoaPods, but that would require manual library and linker additions that would overly complicate this process.
<block class="objc swift" />
## Adding React Native to your app
<block class="objc" />
Assume the [app for integration](https://github.com/JoelMarcey/iOS-2048) is a [2048](https://en.wikipedia.org/wiki/2048_%28video_game%29) game. Here is what the main menu of the native application looks like without React Native.
<block class="swift" />
Assume the [app for integration](https://github.com/JoelMarcey/swift-2048) is a [2048](https://en.wikipedia.org/wiki/2048_%28video_game%29) game. Here is what the main menu of the native application looks like without React Native.
<block class="objc swift" />
![Before RN Integration](img/react-native-existing-app-integration-ios-before.png)
### Configuring CocoaPods dependencies
Before you integrate React Native into your application, you will want to decide what parts of the React Native framework you would like to integrate. We will use CocoaPods to specify which of these "subspecs" your app will depend on.
The list of supported `subspec`s is available in [`/node_modules/react-native/React.podspec`](https://github.com/facebook/react-native/blob/master/React.podspec). They are generally named by functionality. For example, you will generally always want the `Core` `subspec`. That will get you the `AppRegistry`, `StyleSheet`, `View` and other core React Native libraries. If you want to add the React Native `Text` library (e.g., for `<Text>` elements), then you will need the `RCTText` `subspec`. If you want the `Image` library (e.g., for `<Image>` elements), then you will need the `RCTImage` `subspec`.
You can specify which `subspec`s your app will depend on in a `Podfile` file. The easiest way to create a `Podfile` is by running the CocoaPods `init` command in the `/ios` subfolder of your project:
```
$ pod init
```
The `Podfile` will contain a boilerplate setup that you will tweak for your integration purposes. In the end, `Podfile` should look something similar to this:
<block class="objc" />
```
# The target name is most likely the name of your project.
target 'NumberTileGame' do
# Your 'node_modules' directory is probably in the root of your project,
# but if not, adjust the `:path` accordingly
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43
'RCTText',
'RCTNetwork',
'RCTWebSocket', # needed for debugging
# Add any other subspecs you want to use in your project
]
# Explicitly include Yoga if you are using RN >= 0.42.0
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
# Third party deps podspec link
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'GLog', :podspec => '../node_modules/react-native/third-party-podspecs/GLog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
end
```
<block class="swift" />
```
source 'https://github.com/CocoaPods/Specs.git'
# Required for Swift apps
platform :ios, '8.0'
use_frameworks!
# The target name is most likely the name of your project.
target 'swift-2048' do
# Your 'node_modules' directory is probably in the root of your project,
# but if not, adjust the `:path` accordingly
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge', # Include this for RN >= 0.47
'DevSupport', # Include this to enable In-App Devmenu if RN >= 0.43
'RCTText',
'RCTNetwork',
'RCTWebSocket', # needed for debugging
# Add any other subspecs you want to use in your project
]
# Explicitly include Yoga if you are using RN >= 0.42.0
pod "yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
# Third party deps podspec link
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'GLog', :podspec => '../node_modules/react-native/third-party-podspecs/GLog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
end
```
<block class="objc swift" />
After you have created your `Podfile`, you are ready to install the React Native pod.
```
$ pod install
```
You should see output such as:
```
Analyzing dependencies
Fetching podspec for `React` from `../node_modules/react-native`
Downloading dependencies
Installing React (0.26.0)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 3 dependencies from the Podfile and 1 total pod installed.
```
<block class="swift" />
> If you get a warning such as "*The `swift-2048 [Debug]` target overrides the `FRAMEWORK_SEARCH_PATHS` build setting defined in `Pods/Target Support Files/Pods-swift-2048/Pods-swift-2048.debug.xcconfig`. This can lead to problems with the CocoaPods installation*", then make sure the `Framework Search Paths` in `Build Settings` for both `Debug` and `Release` only contain `$(inherited)`.
<block class="objc swift" />
### Code integration
Now we will actually modify the native iOS application to integrate React Native. For our 2048 sample app, we will add a "High Score" screen in React Native.
#### The React Native component
The first bit of code we will write is the actual React Native code for the new "High Score" screen that will be integrated into our application.
##### 1. Create a `index.js` file
First, create an empty `index.js` file in the root of your React Native project.
`index.js` is the starting point for React Native applications, and it is always required. It can be a small file that `require`s other file that are part of your React Native component or application, or it can contain all the code that is needed for it. In our case, we will just put everything in `index.js`.
##### 2. Add your React Native code
In your `index.js`, create your component. In our sample here, we will add simple `<Text>` component within a styled `<View>`
```javascript
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
class RNHighScores extends React.Component {
render() {
var contents = this.props["scores"].map(
score => <Text key={score.name}>{score.name}:{score.value}{"\n"}</Text>
);
return (
<View style={styles.container}>
<Text style={styles.highScoresTitle}>
2048 High Scores!
</Text>
<Text style={styles.scores}>
{contents}
</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#FFFFFF',
},
highScoresTitle: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
scores: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
// Module name
AppRegistry.registerComponent('RNHighScores', () => RNHighScores);
```
> `RNHighScores` is the name of your module that will be used when you add a view to React Native from within your iOS application.
#### The Magic: `RCTRootView`
Now that your React Native component is created via `index.js`, you need to add that component to a new or existing `ViewController`. The easiest path to take is to optionally create an event path to your component and then add that component to an existing `ViewController`.
We will tie our React Native component with a new native view in the `ViewController` that will actually host it called `RCTRootView` .
##### 1. Create an Event Path
You can add a new link on the main game menu to go to the "High Score" React Native page.
![Event Path](img/react-native-add-react-native-integration-link.png)
##### 2. Event Handler
We will now add an event handler from the menu link. A method will be added to the main `ViewController` of your application. This is where `RCTRootView` comes into play.
When you build a React Native application, you use the React Native packager to create an `index.bundle` that will be served by the React Native server. Inside `index.bundle` will be our `RNHighScore` module. So, we need to point our `RCTRootView` to the location of the `index.bundle` resource (via `NSURL`) and tie it to the module.
We will, for debugging purposes, log that the event handler was invoked. Then, we will create a string with the location of our React Native code that exists inside the `index.bundle`. Finally, we will create the main `RCTRootView`. Notice how we provide `RNHighScores` as the `moduleName` that we created [above](#the-react-native-component) when writing the code for our React Native component.
<block class="objc" />
First `import` the `RCTRootView` header.
```objectivec
#import <React/RCTRootView.h>
```
> The `initialProperties` are here for illustration purposes so we have some data for our high score screen. In our React Native component, we will use `this.props` to get access to that data.
```objectivec
- (IBAction)highScoreButtonPressed:(id)sender {
NSLog(@"High Score Button Pressed");
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL: jsCodeLocation
moduleName: @"RNHighScores"
initialProperties:
@{
@"scores" : @[
@{
@"name" : @"Alex",
@"value": @"42"
},
@{
@"name" : @"Joel",
@"value": @"10"
}
]
}
launchOptions: nil];
UIViewController *vc = [[UIViewController alloc] init];
vc.view = rootView;
[self presentViewController:vc animated:YES completion:nil];
}
```
> Note that `RCTRootView initWithURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `[RCTRootView alloc] initWithURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L93) to create a bridge and then use `RCTRootView initWithBridge`.
<block class="swift" />
First `import` the `React` library.
```javascript
import React
```
> The `initialProperties` are here for illustration purposes so we have some data for our high score screen. In our React Native component, we will use `this.props` to get access to that data.
```swift
@IBAction func highScoreButtonTapped(sender : UIButton) {
NSLog("Hello")
let jsCodeLocation = URL(string: "http://localhost:8081/index.bundle?platform=ios")
let mockData:NSDictionary = ["scores":
[
["name":"Alex", "value":"42"],
["name":"Joel", "value":"10"]
]
]
let rootView = RCTRootView(
bundleURL: jsCodeLocation,
moduleName: "RNHighScores",
initialProperties: mockData as [NSObject : AnyObject],
launchOptions: nil
)
let vc = UIViewController()
vc.view = rootView
self.present(vc, animated: true, completion: nil)
}
```
> Note that `RCTRootView bundleURL` starts up a new JSC VM. To save resources and simplify the communication between RN views in different parts of your native app, you can have multiple views powered by React Native that are associated with a single JS runtime. To do that, instead of using `RCTRootView bundleURL`, use [`RCTBridge initWithBundleURL`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridge.h#L89) to create a bridge and then use `RCTRootView initWithBridge`.
<block class="objc" />
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `[[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
<block class="swift" />
> When moving your app to production, the `NSURL` can point to a pre-bundled file on disk via something like `let mainBundle = NSBundle(URLForResource: "main" withExtension:"jsbundle")`. You can use the `react-native-xcode.sh` script in `node_modules/react-native/scripts/` to generate that pre-bundled file.
<block class="objc swift" />
##### 3. Wire Up
Wire up the new link in the main menu to the newly added event handler method.
![Event Path](img/react-native-add-react-native-integration-wire-up.png)
> One of the easier ways to do this is to open the view in the storyboard and right click on the new link. Select something such as the `Touch Up Inside` event, drag that to the storyboard and then select the created method from the list provided.
### Test your integration
You have now done all the basic steps to integrate React Native with your current application. Now we will start the React Native packager to build the `index.bundle` package and the server running on `localhost` to serve it.
##### 1. Add App Transport Security exception
Apple has blocked implicit cleartext HTTP resource loading. So we need to add the following our project's `Info.plist` (or equivalent) file.
```xml
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
```
> App Transport Security is good for your users. Make sure to re-enable it prior to releasing your app for production.
##### 2. Run the packager
To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project:
```
$ npm start
```
##### 3. Run the app
If you are using Xcode or your favorite editor, build and run your native iOS application as normal. Alternatively, you can run the app from the command line using:
```
# From the root of your project
$ react-native run-ios
```
In our sample application, you should see the link to the "High Scores" and then when you click on that you will see the rendering of your React Native component.
Here is the *native* application home screen:
![Home Screen](img/react-native-add-react-native-integration-example-home-screen.png)
Here is the *React Native* high score screen:
![High Scores](img/react-native-add-react-native-integration-example-high-scores.png)
> If you are getting module resolution issues when running your application please see [this GitHub issue](https://github.com/facebook/react-native/issues/4968) for information and possible resolution. [This comment](https://github.com/facebook/react-native/issues/4968#issuecomment-220941717) seemed to be the latest possible resolution.
### See the Code
<block class="objc" />
You can examine the code that added the React Native screen to our sample app on [GitHub](https://github.com/JoelMarcey/iOS-2048/commit/9ae70c7cdd53eb59f5f7c7daab382b0300ed3585).
<block class="swift" />
You can examine the code that added the React Native screen to our sample app on [GitHub](https://github.com/JoelMarcey/swift-2048/commit/13272a31ee6dd46dc68b1dcf4eaf16c1a10f5229).
<block class="android" />
## Adding React Native to your app
### Configuring maven
Add the React Native dependency to your app's `build.gradle` file:
```
dependencies {
compile 'com.android.support:appcompat-v7:23.0.1'
...
compile "com.facebook.react:react-native:+" // From node_modules.
}
```
> If you want to ensure that you are always using a specific React Native version in your native build, replace `+` with an actual React Native version you've downloaded from `npm`.
Add an entry for the local React Native maven directory to `build.gradle`. Be sure to add it to the "allprojects" block:
```
allprojects {
repositories {
...
maven {
// All of React Native (JS, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
}
...
}
```
> Make sure that the path is correct! You shouldnt run into any “Failed to resolve: com.facebook.react:react-native:0.x.x" errors after running Gradle sync in Android Studio.
### Configuring permissions
Next, make sure you have the Internet permission in your `AndroidManifest.xml`:
<uses-permission android:name="android.permission.INTERNET" />
If you need to access to the `DevSettingsActivity` add to your `AndroidManifest.xml`:
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
This is only really used in dev mode when reloading JavaScript from the development server, so you can strip this in release builds if you need to.
### Code integration
Now we will actually modify the native Android application to integrate React Native.
#### The React Native component
The first bit of code we will write is the actual React Native code for the new "High Score" screen that will be integrated into our application.
##### 1. Create a `index.js` file
First, create an empty `index.js` file in the root of your React Native project.
`index.js` is the starting point for React Native applications, and it is always required. It can be a small file that `require`s other file that are part of your React Native component or application, or it can contain all the code that is needed for it. In our case, we will just put everything in `index.js`.
##### 2. Add your React Native code
In your `index.js`, create your component. In our sample here, we will add simple `<Text>` component within a styled `<View>`:
```javascript
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
class HelloWorld extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.hello}>Hello, World</Text>
</View>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
AppRegistry.registerComponent('MyReactNativeApp', () => HelloWorld);
```
##### 3. Configure permissions for development error overlay
If your app is targeting the Android `API level 23` or greater, make sure you have the `overlay` permission enabled for the development build. You can check it with `Settings.canDrawOverlays(this);`. This is required in dev builds because react native development errors must be displayed above all the other windows. Due to the new permissions system introduced in the API level 23, the user needs to approve it. This can be achieved by adding the following code to the Activity file in the onCreate() method. OVERLAY_PERMISSION_REQ_CODE is a field of the class which would be responsible for passing the result back to the Activity.
```java
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}
}
```
Finally, the `onActivityResult()` method (as shown in the code below) has to be overridden to handle the permission Accepted or Denied cases for consistent UX.
```java
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
// SYSTEM_ALERT_WINDOW permission not granted...
}
}
}
}
```
#### The Magic: `ReactRootView`
You need to add some native code in order to start the React Native runtime and get it to render something. To do this, we're going to create an `Activity` that creates a `ReactRootView`, starts a React application inside it and sets it as the main content view.
> If you are targetting Android version <5, use the `AppCompatActivity` class from the `com.android.support:appcompat` package instead of `Activity`.
```java
public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackage(new MainReactPackage())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);
setContentView(mReactRootView);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
}
```
> If you are using a starter kit for React Native, replace the "HelloWorld" string with the one in your index.js file (its the first argument to the `AppRegistry.registerComponent()` method).
If you are using Android Studio, use `Alt + Enter` to add all missing imports in your MyReactActivity class. Be careful to use your packages `BuildConfig` and not the one from the `...facebook...` package.
We need set the theme of `MyReactActivity` to `Theme.AppCompat.Light.NoActionBar` because some components rely on this theme.
```xml
<activity
android:name=".MyReactActivity"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
</activity>
```
> A `ReactInstanceManager` can be shared amongst multiple activities and/or fragments. You will want to make your own `ReactFragment` or `ReactActivity` and have a singleton *holder* that holds a `ReactInstanceManager`. When you need the `ReactInstanceManager` (e.g., to hook up the `ReactInstanceManager` to the lifecycle of those Activities or Fragments) use the one provided by the singleton.
Next, we need to pass some activity lifecycle callbacks down to the `ReactInstanceManager`:
```java
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy(this);
}
}
```
We also need to pass back button events to React Native:
```java
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
```
This allows JavaScript to control what happens when the user presses the hardware back button (e.g. to implement navigation). When JavaScript doesn't handle a back press, your `invokeDefaultOnBackPressed` method will be called. By default this simply finishes your `Activity`.
Finally, we need to hook up the dev menu. By default, this is activated by (rage) shaking the device, but this is not very useful in emulators. So we make it show when you press the hardware menu button (use `Ctrl + M` if you're using Android Studio emulator):
```java
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
```
Now your activity is ready to run some JavaScript code.
### Test your integration
You have now done all the basic steps to integrate React Native with your current application. Now we will start the React Native packager to build the `index.bundle` package and the server running on localhost to serve it.
##### 1. Run the packager
To run your app, you need to first start the development server. To do this, simply run the following command in the root directory of your React Native project:
```
$ npm start
```
##### 2. Run the app
Now build and run your Android app as normal.
Once you reach your React-powered activity inside the app, it should load the JavaScript code from the development server and display:
![Screenshot](img/EmbeddedAppAndroid.png)
### Creating a release build in Android Studio
You can use Android Studio to create your release builds too! Its as easy as creating release builds of your previously-existing native Android app. Theres just one additional step, which youll have to do before every release build. You need to execute the following to create a React Native bundle, which will be included with your native Android app:
```
$ react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/
```
> Dont forget to replace the paths with correct ones and create the assets folder if it doesnt exist.
Now just create a release build of your native app from within Android Studio as usual and you should be good to go!
<block class="objc swift android" />
### Now what?
At this point you can continue developing your app as usual. Refer to our [debugging](docs/debugging.html) and [deployment](docs/running-on-device.html) docs to learn more about working with React Native.
<script>
function displayTab(type, value) {
var container = document.getElementsByTagName('block')[0].parentNode;
container.className = 'display-' + type + '-' + value + ' ' +
container.className.replace(RegExp('display-' + type + '-[a-z]+ ?'), '');
event && event.preventDefault();
}
function convertBlocks() {
// Convert <div>...<span><block /></span>...</div>
// Into <div>...<block />...</div>
var blocks = document.querySelectorAll('block');
for (var i = 0; i < blocks.length; ++i) {
var block = blocks[i];
var span = blocks[i].parentNode;
var container = span.parentNode;
container.insertBefore(block, span);
container.removeChild(span);
}
// Convert <div>...<block />content<block />...</div>
// Into <div>...<block>content</block><block />...</div>
blocks = document.querySelectorAll('block');
for (var i = 0; i < blocks.length; ++i) {
var block = blocks[i];
while (
block.nextSibling &&
block.nextSibling.tagName !== 'BLOCK'
) {
block.appendChild(block.nextSibling);
}
}
}
function guessPlatformAndOS() {
if (!document.querySelector('block')) {
return;
}
// If we are coming to the page with a hash in it (i.e. from a search, for example), try to get
// us as close as possible to the correct platform and dev os using the hashtag and block walk up.
var foundHash = false;
if (
window.location.hash !== '' &&
window.location.hash !== 'content'
) {
// content is default
var hashLinks = document.querySelectorAll(
'a.hash-link'
);
for (
var i = 0;
i < hashLinks.length && !foundHash;
++i
) {
if (hashLinks[i].hash === window.location.hash) {
var parent = hashLinks[i].parentElement;
while (parent) {
if (parent.tagName === 'BLOCK') {
// Could be more than one target os and dev platform, but just choose some sort of order
// of priority here.
// Dev OS
if (parent.className.indexOf('mac') > -1) {
displayTab('os', 'mac');
foundHash = true;
} else if (
parent.className.indexOf('linux') > -1
) {
displayTab('os', 'linux');
foundHash = true;
} else if (
parent.className.indexOf('windows') > -1
) {
displayTab('os', 'windows');
foundHash = true;
} else {
break;
}
// Target Platform
if (parent.className.indexOf('ios') > -1) {
displayTab('platform', 'ios');
foundHash = true;
} else if (
parent.className.indexOf('android') > -1
) {
displayTab('platform', 'android');
foundHash = true;
} else {
break;
}
// Guide
if (parent.className.indexOf('native') > -1) {
displayTab('guide', 'native');
foundHash = true;
} else if (
parent.className.indexOf('quickstart') > -1
) {
displayTab('guide', 'quickstart');
foundHash = true;
} else {
break;
}
break;
}
parent = parent.parentElement;
}
}
}
}
// Do the default if there is no matching hash
if (!foundHash) {
var isMac = navigator.platform === 'MacIntel';
var isWindows = navigator.platform === 'Win32';
displayTab('platform', isMac ? 'ios' : 'android');
displayTab(
'os',
isMac ? 'mac' : isWindows ? 'windows' : 'linux'
);
displayTab('guide', 'quickstart');
displayTab('language', 'objc');
}
}
convertBlocks();
guessPlatformAndOS();
</script>

View File

@ -1,153 +0,0 @@
---
id: interactionmanager
title: InteractionManager
layout: docs
category: APIs
permalink: docs/interactionmanager.html
next: keyboard
previous: imagestore
---
InteractionManager allows long-running work to be scheduled after any
interactions/animations have completed. In particular, this allows JavaScript
animations to run smoothly.
Applications can schedule tasks to run after interactions with the following:
```
InteractionManager.runAfterInteractions(() => {
// ...long-running synchronous task...
});
```
Compare this to other scheduling alternatives:
- requestAnimationFrame(): for code that animates a view over time.
- setImmediate/setTimeout(): run code later, note this may delay animations.
- runAfterInteractions(): run code later, without delaying active animations.
The touch handling system considers one or more active touches to be an
'interaction' and will delay `runAfterInteractions()` callbacks until all
touches have ended or been cancelled.
InteractionManager also allows applications to register animations by
creating an interaction 'handle' on animation start, and clearing it upon
completion:
```
var handle = InteractionManager.createInteractionHandle();
// run animation... (`runAfterInteractions` tasks are queued)
// later, on animation completion:
InteractionManager.clearInteractionHandle(handle);
// queued tasks run if all handles were cleared
```
`runAfterInteractions` takes either a plain callback function, or a
`PromiseTask` object with a `gen` method that returns a `Promise`. If a
`PromiseTask` is supplied, then it is fully resolved (including asynchronous
dependencies that also schedule more tasks via `runAfterInteractions`) before
starting on the next task that might have been queued up synchronously
earlier.
By default, queued tasks are executed together in a loop in one
`setImmediate` batch. If `setDeadline` is called with a positive number, then
tasks will only be executed until the deadline (in terms of js event loop run
time) approaches, at which point execution will yield via setTimeout,
allowing events such as touches to start interactions and block queued tasks
from executing, making apps more responsive.
### Methods
- [`runAfterInteractions`](docs/interactionmanager.html#runafterinteractions)
- [`createInteractionHandle`](docs/interactionmanager.html#createinteractionhandle)
- [`clearInteractionHandle`](docs/interactionmanager.html#clearinteractionhandle)
- [`setDeadline`](docs/interactionmanager.html#setdeadline)
- [`addListener`](docs/interactionmanager.html#addlistener)
### Properties
- [`Events`](docs/interactionmanager.html#events)
---
# Reference
## Methods
### `runAfterInteractions()`
```javascript
InteractionManager.runAfterInteractions(task)
```
Schedule a function to run after all interactions have completed. Returns a cancellable
"promise".
---
### `createInteractionHandle()`
```javascript
InteractionManager.createInteractionHandle()
```
Notify manager that an interaction has started.
---
### `clearInteractionHandle()`
```javascript
InteractionManager.clearInteractionHandle(handle)
```
Notify manager that an interaction has completed.
---
### `setDeadline()`
```javascript
InteractionManager.setDeadline(deadline)
```
A positive number will use setTimeout to schedule any tasks after the
eventLoopRunningTime hits the deadline value, otherwise all tasks will be
executed in one setImmediate batch (default).
---
### `addListener()`
```javascript
InteractionManager.addListener(EventEmitter)
```
## Properties
### `Events`
- `interactionStart`
- `interactionComplete`

View File

@ -1,85 +0,0 @@
---
id: javascript-environment
title: JavaScript Environment
layout: docs
category: Guides
permalink: docs/javascript-environment.html
next: direct-manipulation
previous: gesture-responder-system
---
## JavaScript Runtime
When using React Native, you're going to be running your JavaScript code in two environments:
* On iOS simulators and devices, Android emulators and devices React Native uses [JavaScriptCore](http://trac.webkit.org/wiki/JavaScriptCore) which is the JavaScript engine that powers Safari. On iOS JSC doesn't use JIT due to the absence of writable executable memory in iOS apps.
* When using Chrome debugging, it runs all the JavaScript code within Chrome itself and communicates with native code via WebSocket. So you are using [V8](https://code.google.com/p/v8/).
While both environments are very similar, you may end up hitting some inconsistencies. We're likely going to experiment with other JS engines in the future, so it's best to avoid relying on specifics of any runtime.
## JavaScript Syntax Transformers
Syntax transformers make writing code more enjoyable by allowing you to use new JavaScript syntax without having to wait for support on all interpreters.
As of version 0.5.0, React Native ships with the [Babel JavaScript compiler](https://babeljs.io). Check [Babel documentation](https://babeljs.io/docs/plugins/#transform-plugins) on its supported transformations for more details.
Here's a full list of React Native's [enabled transformations](https://github.com/facebook/react-native/blob/master/babel-preset/configs/main.js#L16).
ES5
* Reserved Words: `promise.catch(function() { });`
ES6
* [Arrow functions](http://babeljs.io/docs/learn-es2015/#arrows): `<C onPress={() => this.setState({pressed: true})}`
* [Block scoping](https://babeljs.io/docs/learn-es2015/#let-const): `let greeting = 'hi';`
* [Call spread](http://babeljs.io/docs/learn-es2015/#default-rest-spread): `Math.max(...array);`
* [Classes](http://babeljs.io/docs/learn-es2015/#classes): `class C extends React.Component { render() { return <View />; } }`
* [Constants](https://babeljs.io/docs/learn-es2015/#let-const): `const answer = 42;`
* [Destructuring](http://babeljs.io/docs/learn-es2015/#destructuring): `var {isActive, style} = this.props;`
* [for...of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of): `for (var num of [1, 2, 3]) {}`
* [Modules](http://babeljs.io/docs/learn-es2015/#modules): `import React, { Component } from 'react';`
* [Computed Properties](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals): `var key = 'abc'; var obj = {[key]: 10};`
* [Object Concise Method](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals): `var obj = { method() { return 10; } };`
* [Object Short Notation](http://babeljs.io/docs/learn-es2015/#enhanced-object-literals): `var name = 'vjeux'; var obj = { name };`
* [Rest Params](https://github.com/sebmarkbage/ecmascript-rest-spread): `function(type, ...args) { }`
* [Template Literals](http://babeljs.io/docs/learn-es2015/#template-strings): ``var who = 'world'; var str = `Hello ${who}`;``
ES7
* [Object Spread](https://github.com/sebmarkbage/ecmascript-rest-spread): `var extended = { ...obj, a: 10 };`
* [Function Trailing Comma](https://github.com/jeffmo/es-trailing-function-commas): `function f(a, b, c,) { }`
* [Async Functions](https://github.com/tc39/ecmascript-asyncawait): `async function doStuffAsync() { const foo = await doOtherStuffAsync(); }`;
Specific
* [JSX](https://facebook.github.io/react/docs/jsx-in-depth.html): `<View style={{color: 'red'}} />`
* [Flow](http://flowtype.org/): `function foo(x: ?number): string {}`
## Polyfills
Many standards functions are also available on all the supported JavaScript runtimes.
Browser
* [console.{log, warn, error, info, trace, table}](https://developer.chrome.com/devtools/docs/console-api)
* [CommonJS require](https://nodejs.org/docs/latest/api/modules.html)
* [XMLHttpRequest, fetch](docs/network.html#content)
* [{set, clear}{Timeout, Interval, Immediate}, {request, cancel}AnimationFrame](docs/timers.html#content)
* [navigator.geolocation](docs/geolocation.html#content)
ES6
* [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
* String.prototype.{[startsWith](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith), [endsWith](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith), [repeat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeats), [includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes)}
* [Array.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from)
* Array.prototype.{[find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find), [findIndex](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex), [includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)}
ES7
* Object.{[entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries), [values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values)}
Specific
* `__DEV__`

View File

@ -1,146 +0,0 @@
---
id: keyboard
title: Keyboard
layout: docs
category: APIs
permalink: docs/keyboard.html
next: layoutanimation
previous: interactionmanager
---
`Keyboard` module to control keyboard events.
### Usage
The Keyboard module allows you to listen for native events and react to them, as
well as make changes to the keyboard, like dismissing it.
```
import React, { Component } from 'react';
import { Keyboard, TextInput } from 'react-native';
class Example extends Component {
componentWillMount () {
this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
}
componentWillUnmount () {
this.keyboardDidShowListener.remove();
this.keyboardDidHideListener.remove();
}
_keyboardDidShow () {
alert('Keyboard Shown');
}
_keyboardDidHide () {
alert('Keyboard Hidden');
}
render() {
return (
<TextInput
onSubmitEditing={Keyboard.dismiss}
/>
);
}
}
```
### Methods
- [`addListener`](docs/keyboard.html#addlistener)
- [`removeListener`](docs/keyboard.html#removelistener)
- [`removeAllListeners`](docs/keyboard.html#removealllisteners)
- [`dismiss`](docs/keyboard.html#dismiss)
---
# Reference
## Methods
### `addListener()`
```javascript
Keyboard.addListener(eventName, callback)
```
The `addListener` function connects a JavaScript function to an identified native
keyboard notification event.
This function then returns the reference to the listener.
@param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for. This
can be any of the following:
- `keyboardWillShow`
- `keyboardDidShow`
- `keyboardWillHide`
- `keyboardDidHide`
- `keyboardWillChangeFrame`
- `keyboardDidChangeFrame`
Note that if you set `android:windowSoftInputMode` to `adjustResize` or `adjustNothing`,
only `keyboardDidShow` and `keyboardDidHide` events will be available on Android.
`keyboardWillShow` as well as `keyboardWillHide` are generally not available on Android
since there is no native corresponding event.
@param {function} callback function to be called when the event fires.
---
### `removeListener()`
```javascript
Keyboard.removeListener(eventName, callback)
```
Removes a specific listener.
@param {string} eventName The `nativeEvent` is the string that identifies the event you're listening for.
@param {function} callback function to be called when the event fires.
---
### `removeAllListeners()`
```javascript
Keyboard.removeAllListeners(eventName)
```
Removes all listeners for a specific event type.
@param {string} eventType The native event string listeners are watching which will be removed.
---
### `dismiss()`
```javascript
Keyboard.dismiss()
```
Dismisses the active keyboard and removes focus.

View File

@ -1,107 +0,0 @@
---
id: keyboardavoidingview
title: KeyboardAvoidingView
layout: docs
category: components
permalink: docs/keyboardavoidingview.html
next: listview
previous: image
---
It is a component to solve the common problem of views that need to move out of the way of the virtual keyboard.
It can automatically adjust either its position or bottom padding based on the position of the keyboard.
### Props
- [ViewPropTypes props...](docs/viewproptypes.html#props)
- [`keyboardVerticalOffset`](docs/keyboardavoidingview.html#keyboardverticaloffset)
- [`behavior`](docs/keyboardavoidingview.html#behavior)
- [`contentContainerStyle`](docs/keyboardavoidingview.html#contentcontainerstyle)
### Methods
- [`relativeKeyboardHeight`](docs/keyboardavoidingview.html#relativekeyboardheight)
- [`onKeyboardChange`](docs/keyboardavoidingview.html#onkeyboardchange)
- [`onLayout`](docs/keyboardavoidingview.html#onlayout)
---
# Reference
## Props
### `keyboardVerticalOffset`
This is the distance between the top of the user screen and the react native view,
may be non-zero in some use cases.
| Type | Required |
| - | - |
| number | Yes |
---
### `behavior`
| Type | Required |
| - | - |
| enum('height', 'position', 'padding') | No |
---
### `contentContainerStyle`
The style of the content container(View) when behavior is 'position'.
| Type | Required |
| - | - |
| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
## Methods
### `relativeKeyboardHeight()`
```javascript
relativeKeyboardHeight(keyboardFrame: object):
```
---
### `onKeyboardChange()`
```javascript
onKeyboardChange(event: object)
```
---
### `onLayout()`
```javascript
onLayout(event: ViewLayoutEvent)
```

View File

@ -1,965 +0,0 @@
---
id: layout-props
title: Layout Props
layout: docs
category: APIs
permalink: docs/layout-props.html
next: picker-style-props
previous: vibrationios
---
### Props
- [`marginHorizontal`](docs/layout-props.html#marginhorizontal)
- [`alignContent`](docs/layout-props.html#aligncontent)
- [`alignSelf`](docs/layout-props.html#alignself)
- [`aspectRatio`](docs/layout-props.html#aspectratio)
- [`borderBottomWidth`](docs/layout-props.html#borderbottomwidth)
- [`borderEndWidth`](docs/layout-props.html#borderendwidth)
- [`borderLeftWidth`](docs/layout-props.html#borderleftwidth)
- [`borderRightWidth`](docs/layout-props.html#borderrightwidth)
- [`borderStartWidth`](docs/layout-props.html#borderstartwidth)
- [`borderTopWidth`](docs/layout-props.html#bordertopwidth)
- [`borderWidth`](docs/layout-props.html#borderwidth)
- [`bottom`](docs/layout-props.html#bottom)
- [`display`](docs/layout-props.html#display)
- [`end`](docs/layout-props.html#end)
- [`flex`](docs/layout-props.html#flex)
- [`flexBasis`](docs/layout-props.html#flexbasis)
- [`flexDirection`](docs/layout-props.html#flexdirection)
- [`flexGrow`](docs/layout-props.html#flexgrow)
- [`flexShrink`](docs/layout-props.html#flexshrink)
- [`flexWrap`](docs/layout-props.html#flexwrap)
- [`height`](docs/layout-props.html#height)
- [`justifyContent`](docs/layout-props.html#justifycontent)
- [`left`](docs/layout-props.html#left)
- [`margin`](docs/layout-props.html#margin)
- [`marginBottom`](docs/layout-props.html#marginbottom)
- [`marginEnd`](docs/layout-props.html#marginend)
- [`alignItems`](docs/layout-props.html#alignitems)
- [`marginLeft`](docs/layout-props.html#marginleft)
- [`marginRight`](docs/layout-props.html#marginright)
- [`marginStart`](docs/layout-props.html#marginstart)
- [`marginTop`](docs/layout-props.html#margintop)
- [`marginVertical`](docs/layout-props.html#marginvertical)
- [`maxHeight`](docs/layout-props.html#maxheight)
- [`maxWidth`](docs/layout-props.html#maxwidth)
- [`minHeight`](docs/layout-props.html#minheight)
- [`minWidth`](docs/layout-props.html#minwidth)
- [`overflow`](docs/layout-props.html#overflow)
- [`padding`](docs/layout-props.html#padding)
- [`paddingBottom`](docs/layout-props.html#paddingbottom)
- [`paddingEnd`](docs/layout-props.html#paddingend)
- [`paddingHorizontal`](docs/layout-props.html#paddinghorizontal)
- [`paddingLeft`](docs/layout-props.html#paddingleft)
- [`paddingRight`](docs/layout-props.html#paddingright)
- [`paddingStart`](docs/layout-props.html#paddingstart)
- [`paddingTop`](docs/layout-props.html#paddingtop)
- [`paddingVertical`](docs/layout-props.html#paddingvertical)
- [`position`](docs/layout-props.html#position)
- [`right`](docs/layout-props.html#right)
- [`start`](docs/layout-props.html#start)
- [`top`](docs/layout-props.html#top)
- [`width`](docs/layout-props.html#width)
- [`zIndex`](docs/layout-props.html#zindex)
- [`direction`](docs/layout-props.html#direction)
---
# Reference
## Props
### `marginHorizontal`
Setting `marginHorizontal` has the same effect as setting
both `marginLeft` and `marginRight`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `alignContent`
`alignContent` controls how rows align in the cross direction,
overriding the `alignContent` of the parent.
See https://developer.mozilla.org/en-US/docs/Web/CSS/align-content
for more details.
| Type | Required |
| - | - |
| enum('flex-start', 'flex-end', 'center', 'stretch', 'space-between', 'space-around') | No |
---
### `alignSelf`
`alignSelf` controls how a child aligns in the cross direction,
overriding the `alignItems` of the parent. It works like `align-self`
in CSS (default: auto).
See https://developer.mozilla.org/en-US/docs/Web/CSS/align-self
for more details.
| Type | Required |
| - | - |
| enum('auto', 'flex-start', 'flex-end', 'center', 'stretch', 'baseline') | No |
---
### `aspectRatio`
Aspect ratio control the size of the undefined dimension of a node. Aspect ratio is a
non-standard property only available in react native and not CSS.
- On a node with a set width/height aspect ratio control the size of the unset dimension
- On a node with a set flex basis aspect ratio controls the size of the node in the cross axis
if unset
- On a node with a measure function aspect ratio works as though the measure function measures
the flex basis
- On a node with flex grow/shrink aspect ratio controls the size of the node in the cross axis
if unset
- Aspect ratio takes min/max dimensions into account
| Type | Required |
| - | - |
| number | No |
---
### `borderBottomWidth`
`borderBottomWidth` works like `border-bottom-width` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/border-bottom-width
for more details.
| Type | Required |
| - | - |
| number | No |
---
### `borderEndWidth`
When direction is `ltr`, `borderEndWidth` is equivalent to `borderRightWidth`.
When direction is `rtl`, `borderEndWidth` is equivalent to `borderLeftWidth`.
| Type | Required |
| - | - |
| number | No |
---
### `borderLeftWidth`
`borderLeftWidth` works like `border-left-width` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/border-left-width
for more details.
| Type | Required |
| - | - |
| number | No |
---
### `borderRightWidth`
`borderRightWidth` works like `border-right-width` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/border-right-width
for more details.
| Type | Required |
| - | - |
| number | No |
---
### `borderStartWidth`
When direction is `ltr`, `borderStartWidth` is equivalent to `borderLeftWidth`.
When direction is `rtl`, `borderStartWidth` is equivalent to `borderRightWidth`.
| Type | Required |
| - | - |
| number | No |
---
### `borderTopWidth`
`borderTopWidth` works like `border-top-width` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/border-top-width
for more details.
| Type | Required |
| - | - |
| number | No |
---
### `borderWidth`
`borderWidth` works like `border-width` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/border-width
for more details.
| Type | Required |
| - | - |
| number | No |
---
### `bottom`
`bottom` is the number of logical pixels to offset the bottom edge of
this component.
It works similarly to `bottom` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/bottom
for more details of how `bottom` affects layout.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `display`
`display` sets the display type of this component.
It works similarly to `display` in CSS, but only support 'flex' and 'none'.
'flex' is the default.
| Type | Required |
| - | - |
| enum('none', 'flex') | No |
---
### `end`
When the direction is `ltr`, `end` is equivalent to `right`.
When the direction is `rtl`, `end` is equivalent to `left`.
This style takes precedence over the `left` and `right` styles.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `flex`
In React Native `flex` does not work the same way that it does in CSS.
`flex` is a number rather than a string, and it works
according to the `Yoga` library
at https://github.com/facebook/yoga
When `flex` is a positive number, it makes the component flexible
and it will be sized proportional to its flex value. So a
component with `flex` set to 2 will take twice the space as a
component with `flex` set to 1.
When `flex` is 0, the component is sized according to `width`
and `height` and it is inflexible.
When `flex` is -1, the component is normally sized according
`width` and `height`. However, if there's not enough space,
the component will shrink to its `minWidth` and `minHeight`.
flexGrow, flexShrink, and flexBasis work the same as in CSS.
| Type | Required |
| - | - |
| number | No |
---
### `flexBasis`
| Type | Required |
| - | - |
| number, ,string | No |
---
### `flexDirection`
`flexDirection` controls which directions children of a container go.
`row` goes left to right, `column` goes top to bottom, and you may
be able to guess what the other two do. It works like `flex-direction`
in CSS, except the default is `column`.
See https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction
for more details.
| Type | Required |
| - | - |
| enum('row', 'row-reverse', 'column', 'column-reverse') | No |
---
### `flexGrow`
| Type | Required |
| - | - |
| number | No |
---
### `flexShrink`
| Type | Required |
| - | - |
| number | No |
---
### `flexWrap`
`flexWrap` controls whether children can wrap around after they
hit the end of a flex container.
It works like `flex-wrap` in CSS (default: nowrap).
See https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap
for more details.
| Type | Required |
| - | - |
| enum('wrap', 'nowrap') | No |
---
### `height`
`height` sets the height of this component.
It works similarly to `height` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/height for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `justifyContent`
`justifyContent` aligns children in the main direction.
For example, if children are flowing vertically, `justifyContent`
controls how they align vertically.
It works like `justify-content` in CSS (default: flex-start).
See https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
for more details.
| Type | Required |
| - | - |
| enum('flex-start', 'flex-end', 'center', 'space-between', 'space-around') | No |
---
### `left`
`left` is the number of logical pixels to offset the left edge of
this component.
It works similarly to `left` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/left
for more details of how `left` affects layout.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `margin`
Setting `margin` has the same effect as setting each of
`marginTop`, `marginLeft`, `marginBottom`, and `marginRight`.
See https://developer.mozilla.org/en-US/docs/Web/CSS/margin
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `marginBottom`
`marginBottom` works like `margin-bottom` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-bottom
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `marginEnd`
When direction is `ltr`, `marginEnd` is equivalent to `marginRight`.
When direction is `rtl`, `marginEnd` is equivalent to `marginLeft`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `alignItems`
`alignItems` aligns children in the cross direction.
For example, if children are flowing vertically, `alignItems`
controls how they align horizontally.
It works like `align-items` in CSS (default: stretch).
See https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
for more details.
| Type | Required |
| - | - |
| enum('flex-start', 'flex-end', 'center', 'stretch', 'baseline') | No |
---
### `marginLeft`
`marginLeft` works like `margin-left` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-left
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `marginRight`
`marginRight` works like `margin-right` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-right
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `marginStart`
When direction is `ltr`, `marginStart` is equivalent to `marginLeft`.
When direction is `rtl`, `marginStart` is equivalent to `marginRight`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `marginTop`
`marginTop` works like `margin-top` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/margin-top
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `marginVertical`
Setting `marginVertical` has the same effect as setting both
`marginTop` and `marginBottom`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `maxHeight`
`maxHeight` is the maximum height for this component, in logical pixels.
It works similarly to `max-height` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/max-height
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `maxWidth`
`maxWidth` is the maximum width for this component, in logical pixels.
It works similarly to `max-width` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/max-width
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `minHeight`
`minHeight` is the minimum height for this component, in logical pixels.
It works similarly to `min-height` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/min-height
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `minWidth`
`minWidth` is the minimum width for this component, in logical pixels.
It works similarly to `min-width` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/min-width
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `overflow`
`overflow` controls how children are measured and displayed.
`overflow: hidden` causes views to be clipped while `overflow: scroll`
causes views to be measured independently of their parents main axis.
It works like `overflow` in CSS (default: visible).
See https://developer.mozilla.org/en/docs/Web/CSS/overflow
for more details.
`overflow: visible` only works on iOS. On Android, all views will clip
their children.
| Type | Required |
| - | - |
| enum('visible', 'hidden', 'scroll') | No |
---
### `padding`
Setting `padding` has the same effect as setting each of
`paddingTop`, `paddingBottom`, `paddingLeft`, and `paddingRight`.
See https://developer.mozilla.org/en-US/docs/Web/CSS/padding
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingBottom`
`paddingBottom` works like `padding-bottom` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-bottom
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingEnd`
When direction is `ltr`, `paddingEnd` is equivalent to `paddingRight`.
When direction is `rtl`, `paddingEnd` is equivalent to `paddingLeft`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingHorizontal`
Setting `paddingHorizontal` is like setting both of
`paddingLeft` and `paddingRight`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingLeft`
`paddingLeft` works like `padding-left` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-left
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingRight`
`paddingRight` works like `padding-right` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-right
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingStart`
When direction is `ltr`, `paddingStart` is equivalent to `paddingLeft`.
When direction is `rtl`, `paddingStart` is equivalent to `paddingRight`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingTop`
`paddingTop` works like `padding-top` in CSS.
See https://developer.mozilla.org/en-US/docs/Web/CSS/padding-top
for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `paddingVertical`
Setting `paddingVertical` is like setting both of
`paddingTop` and `paddingBottom`.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `position`
`position` in React Native is similar to regular CSS, but
everything is set to `relative` by default, so `absolute`
positioning is always just relative to the parent.
If you want to position a child using specific numbers of logical
pixels relative to its parent, set the child to have `absolute`
position.
If you want to position a child relative to something
that is not its parent, just don't use styles for that. Use the
component tree.
See https://github.com/facebook/yoga
for more details on how `position` differs between React Native
and CSS.
| Type | Required |
| - | - |
| enum('absolute', 'relative') | No |
---
### `right`
`right` is the number of logical pixels to offset the right edge of
this component.
It works similarly to `right` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/right
for more details of how `right` affects layout.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `start`
When the direction is `ltr`, `start` is equivalent to `left`.
When the direction is `rtl`, `start` is equivalent to `right`.
This style takes precedence over the `left`, `right`, and `end` styles.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `top`
`top` is the number of logical pixels to offset the top edge of
this component.
It works similarly to `top` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/top
for more details of how `top` affects layout.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `width`
`width` sets the width of this component.
It works similarly to `width` in CSS, but in React Native you
must use points or percentages. Ems and other units are not supported.
See https://developer.mozilla.org/en-US/docs/Web/CSS/width for more details.
| Type | Required |
| - | - |
| number, ,string | No |
---
### `zIndex`
`zIndex` controls which components display on top of others.
Normally, you don't use `zIndex`. Components render according to
their order in the document tree, so later components draw over
earlier ones. `zIndex` may be useful if you have animations or custom
modal interfaces where you don't want this behavior.
It works like the CSS `z-index` property - components with a larger
`zIndex` will render on top. Think of the z-direction like it's
pointing from the phone into your eyeball.
See https://developer.mozilla.org/en-US/docs/Web/CSS/z-index for
more details.
| Type | Required |
| - | - |
| number | No |
---
### `direction`
`direction` specifies the directional flow of the user interface.
The default is `inherit`, except for root node which will have
value based on the current locale.
See https://facebook.github.io/yoga/docs/rtl/
for more details.
| Type | Required | Platform |
| - | - | - |
| enum('inherit', 'ltr', 'rtl') | No | iOS |

View File

@ -1,116 +0,0 @@
---
id: layoutanimation
title: LayoutAnimation
layout: docs
category: APIs
permalink: docs/layoutanimation.html
next: linking
previous: keyboard
---
Automatically animates views to their new positions when the
next layout happens.
A common way to use this API is to call it before calling `setState`.
Note that in order to get this to work on **Android** you need to set the following flags via `UIManager`:
UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
### Methods
- [`configureNext`](docs/layoutanimation.html#configurenext)
- [`create`](docs/layoutanimation.html#create)
- [`checkConfig`](docs/layoutanimation.html#checkconfig)
### Properties
- [`Types`](docs/layoutanimation.html#types)
- [`Properties`](docs/layoutanimation.html#properties)
- [`Presets`](docs/layoutanimation.html#presets)
- [`easeInEaseOut`](docs/layoutanimation.html#easeineaseout)
- [`linear`](docs/layoutanimation.html#linear)
- [`spring`](docs/layoutanimation.html#spring)
---
# Reference
## Methods
### `configureNext()`
```javascript
LayoutAnimation.configureNext(config, onAnimationDidEnd?)
```
Schedules an animation to happen on the next layout.
@param config Specifies animation properties:
- `duration` in milliseconds
- `create`, config for animating in new views (see `Anim` type)
- `update`, config for animating views that have been updated
(see `Anim` type)
@param onAnimationDidEnd Called when the animation finished.
Only supported on iOS.
@param onError Called on error. Only supported on iOS.
---
### `create()`
```javascript
LayoutAnimation.create(duration, type, creationProp)
```
Helper for creating a config for `configureNext`.
---
### `checkConfig()`
```javascript
LayoutAnimation.checkConfig(config, location, name)
```
## Properties
---
---
---
---
---

View File

@ -1,95 +0,0 @@
---
id: linking-libraries-ios
title: Linking Libraries
layout: docs
category: Guides (iOS)
permalink: docs/linking-libraries-ios.html
banner: ejected
next: running-on-simulator-ios
previous: custom-webview-ios
---
Not every app uses all the native capabilities, and including the code to support
all those features would impact the binary size... But we still want to make it
easy to add these features whenever you need them.
With that in mind we exposed many of these features as independent static libraries.
For most of the libs it will be as simple as dragging two files, sometimes a third
step will be necessary, but no more than that.
_All the libraries we ship with React Native live on the `Libraries` folder in
the root of the repository. Some of them are pure JavaScript, and you only need
to `require` it. Other libraries also rely on some native code, in that case
you'll have to add these files to your app, otherwise the app will throw an
error as soon as you try to use the library._
## Here are the few steps to link your libraries that contain native code
### Automatic linking
#### Step 1
Install a library with native dependencies:
```bash
$ npm install <library-with-native-dependencies> --save
```
> ***Note:*** `--save` or `--save-dev` flag is very important for this step. React Native will link
your libs based on `dependencies` and `devDependencies` in your `package.json` file.
#### Step 2
Link your native dependencies:
```bash
$ react-native link
```
Done! All libraries with native dependencies should be successfully linked to your iOS/Android project.
> ***Note:*** If your iOS project is using CocoaPods (contains `Podfile`) and linked library has `podspec` file,
then `react-native link` will link library using Podfile. To support non-trivial Podfiles
add `# Add new pods below this line` comment to places where you expect pods to be added.
### Manual linking
#### Step 1
If the library has native code, there must be a `.xcodeproj` file inside it's
folder.
Drag this file to your project on Xcode (usually under the `Libraries` group
on Xcode);
![](img/AddToLibraries.png)
#### Step 2
Click on your main project file (the one that represents the `.xcodeproj`)
select `Build Phases` and drag the static library from the `Products` folder
inside the Library you are importing to `Link Binary With Libraries`
![](img/AddToBuildPhases.png)
#### Step 3
Not every library will need this step, what you need to consider is:
_Do I need to know the contents of the library at compile time?_
What that means is, are you using this library on the native side or only in
JavaScript? If you are only using it in JavaScript, you are good to go!
This step is not necessary for libraries that we ship with React Native with the
exception of `PushNotificationIOS` and `Linking`.
In the case of the `PushNotificationIOS` for example, you have to call a method
on the library from your `AppDelegate` every time a new push notification is
received.
For that we need to know the library's headers. To achieve that you have to go
to your project's file, select `Build Settings` and search for `Header Search
Paths`. There you should include the path to your library (if it has relevant
files on subdirectories remember to make it `recursive`, like `React` on the
example).
![](img/AddToSearchPaths.png)

View File

@ -1,256 +0,0 @@
---
id: linking
title: Linking
layout: docs
category: APIs
permalink: docs/linking.html
next: netinfo
previous: layoutanimation
---
<div class="banner-crna-ejected">
<h3>Projects with Native Code Only</h3>
<p>
This section only applies to projects made with <code>react-native init</code>
or to those made with Create React Native App which have since ejected. For
more information about ejecting, please see
the <a href="https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md" target="_blank">guide</a> on
the Create React Native App repository.
</p>
</div>
`Linking` gives you a general interface to interact with both incoming
and outgoing app links.
### Basic Usage
#### Handling deep links
If your app was launched from an external url registered to your app you can
access and handle it from any component you want with
```
componentDidMount() {
Linking.getInitialURL().then((url) => {
if (url) {
console.log('Initial url is: ' + url);
}
}).catch(err => console.error('An error occurred', err));
}
```
NOTE: For instructions on how to add support for deep linking on Android,
refer to [Enabling Deep Links for App Content - Add Intent Filters for Your Deep Links](http://developer.android.com/training/app-indexing/deep-linking.html#adding-filters).
If you wish to receive the intent in an existing instance of MainActivity,
you may set the `launchMode` of MainActivity to `singleTask` in
`AndroidManifest.xml`. See [`<activity>`](http://developer.android.com/guide/topics/manifest/activity-element.html)
documentation for more information.
```
<activity
android:name=".MainActivity"
android:launchMode="singleTask">
```
NOTE: On iOS, you'll need to link `RCTLinking` to your project by following
the steps described [here](docs/linking-libraries-ios.html#manual-linking).
If you also want to listen to incoming app links during your app's
execution, you'll need to add the following lines to your `*AppDelegate.m`:
```
// iOS 9.x or newer
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
```
If you're targeting iOS 8.x or older, you can use the following code instead:
```
// iOS 8.x or older
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
```
// If your app is using [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html),
you'll need to add the following code as well:
```
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
```
And then on your React component you'll be able to listen to the events on
`Linking` as follows
```
componentDidMount() {
Linking.addEventListener('url', this._handleOpenURL);
},
componentWillUnmount() {
Linking.removeEventListener('url', this._handleOpenURL);
},
_handleOpenURL(event) {
console.log(event.url);
}
```
#### Opening external links
To start the corresponding activity for a link (web URL, email, contact etc.), call
```
Linking.openURL(url).catch(err => console.error('An error occurred', err));
```
If you want to check if any installed app can handle a given URL beforehand you can call
```
Linking.canOpenURL(url).then(supported => {
if (!supported) {
console.log('Can\'t handle url: ' + url);
} else {
return Linking.openURL(url);
}
}).catch(err => console.error('An error occurred', err));
```
### Methods
- [`constructor`](docs/linking.html#constructor)
- [`addEventListener`](docs/linking.html#addeventlistener)
- [`removeEventListener`](docs/linking.html#removeeventlistener)
- [`openURL`](docs/linking.html#openurl)
- [`canOpenURL`](docs/linking.html#canopenurl)
- [`getInitialURL`](docs/linking.html#getinitialurl)
---
# Reference
## Methods
### `constructor()`
```javascript
constructor()
```
---
### `addEventListener()`
```javascript
addEventListener(type, handler)
```
Add a handler to Linking changes by listening to the `url` event type
and providing the handler
---
### `removeEventListener()`
```javascript
removeEventListener(type, handler)
```
Remove a handler by passing the `url` event type and the handler
---
### `openURL()`
```javascript
openURL(url)
```
Try to open the given `url` with any of the installed apps.
You can use other URLs, like a location (e.g. "geo:37.484847,-122.148386" on Android
or "http://maps.apple.com/?ll=37.484847,-122.148386" on iOS), a contact,
or any other URL that can be opened with the installed apps.
The method returns a `Promise` object. If the user confirms the open dialog or the
url automatically opens, the promise is resolved. If the user cancels the open dialog
or there are no registered applications for the url, the promise is rejected.
> This method will fail if the system doesn't know how to open the specified URL. If you're passing in a non-http(s) URL, it's best to check {@code canOpenURL} first.
> For web URLs, the protocol ("http://", "https://") must be set accordingly!
---
### `canOpenURL()`
```javascript
canOpenURL(url)
```
Determine whether or not an installed app can handle a given URL.
> For web URLs, the protocol ("http://", "https://") must be set accordingly!
> As of iOS 9, your app needs to provide the `LSApplicationQueriesSchemes` key
inside `Info.plist` or canOpenURL will always return false.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| url | string | Yes | The URL to open |
---
### `getInitialURL()`
```javascript
getInitialURL()
```
If the app launch was triggered by an app link,
it will give the link url, otherwise it will give `null`
> To support deep linking on Android, refer http://developer.android.com/training/app-indexing/deep-linking.html#handling-intents

View File

@ -1,436 +0,0 @@
---
id: listview
title: ListView
layout: docs
category: components
permalink: docs/listview.html
next: maskedviewios
previous: keyboardavoidingview
---
DEPRECATED - use one of the new list components, such as [`FlatList`](docs/flatlist.html)
or [`SectionList`](docs/sectionlist.html) for bounded memory use, fewer bugs,
better performance, an easier to use API, and more features. Check out this
[blog post](https://facebook.github.io/react-native/blog/2017/03/13/better-list-views.html)
for more details.
ListView - A core component designed for efficient display of vertically
scrolling lists of changing data. The minimal API is to create a
[`ListView.DataSource`](docs/listviewdatasource.html), populate it with a simple
array of data blobs, and instantiate a `ListView` component with that data
source and a `renderRow` callback which takes a blob from the data array and
returns a renderable component.
Minimal example:
```
class MyComponent extends Component {
constructor() {
super();
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(['row 1', 'row 2']),
};
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>}
/>
);
}
}
```
ListView also supports more advanced features, including sections with sticky
section headers, header and footer support, callbacks on reaching the end of
the available data (`onEndReached`) and on the set of rows that are visible
in the device viewport change (`onChangeVisibleRows`), and several
performance optimizations.
There are a few performance operations designed to make ListView scroll
smoothly while dynamically loading potentially very large (or conceptually
infinite) data sets:
* Only re-render changed rows - the rowHasChanged function provided to the
data source tells the ListView if it needs to re-render a row because the
source data has changed - see ListViewDataSource for more details.
* Rate-limited row rendering - By default, only one row is rendered per
event-loop (customizable with the `pageSize` prop). This breaks up the
work into smaller chunks to reduce the chance of dropping frames while
rendering rows.
### Props
* [ScrollView props...](docs/scrollview.html#props)
- [`dataSource`](docs/listview.html#datasource)
- [`initialListSize`](docs/listview.html#initiallistsize)
- [`onEndReachedThreshold`](docs/listview.html#onendreachedthreshold)
- [`pageSize`](docs/listview.html#pagesize)
- [`renderRow`](docs/listview.html#renderrow)
- [`renderScrollComponent`](docs/listview.html#renderscrollcomponent)
- [`scrollRenderAheadDistance`](docs/listview.html#scrollrenderaheaddistance)
- [`stickyHeaderIndices`](docs/listview.html#stickyheaderindices)
- [`enableEmptySections`](docs/listview.html#enableemptysections)
- [`renderHeader`](docs/listview.html#renderheader)
- [`onEndReached`](docs/listview.html#onendreached)
- [`stickySectionHeadersEnabled`](docs/listview.html#stickysectionheadersenabled)
- [`renderSectionHeader`](docs/listview.html#rendersectionheader)
- [`renderSeparator`](docs/listview.html#renderseparator)
- [`onChangeVisibleRows`](docs/listview.html#onchangevisiblerows)
- [`removeClippedSubviews`](docs/listview.html#removeclippedsubviews)
- [`renderFooter`](docs/listview.html#renderfooter)
### Methods
- [`getMetrics`](docs/listview.html#getmetrics)
- [`scrollTo`](docs/listview.html#scrollto)
- [`scrollToEnd`](docs/listview.html#scrolltoend)
- [`flashScrollIndicators`](docs/listview.html#flashscrollindicators)
---
# Reference
## Props
### `dataSource`
An instance of [ListView.DataSource](docs/listviewdatasource.html) to use
| Type | Required |
| - | - |
| ListViewDataSource | Yes |
---
### `initialListSize`
How many rows to render on initial component mount. Use this to make
it so that the first screen worth of data appears at one time instead of
over the course of multiple frames.
| Type | Required |
| - | - |
| number | Yes |
---
### `onEndReachedThreshold`
Threshold in pixels (virtual, not physical) for calling onEndReached.
| Type | Required |
| - | - |
| number | Yes |
---
### `pageSize`
Number of rows to render per event loop. Note: if your 'rows' are actually
cells, i.e. they don't span the full width of your view (as in the
ListViewGridLayoutExample), you should set the pageSize to be a multiple
of the number of cells per row, otherwise you're likely to see gaps at
the edge of the ListView as new pages are loaded.
| Type | Required |
| - | - |
| number | Yes |
---
### `renderRow`
(rowData, sectionID, rowID, highlightRow) => renderable
Takes a data entry from the data source and its ids and should return
a renderable component to be rendered as the row. By default the data
is exactly what was put into the data source, but it's also possible to
provide custom extractors. ListView can be notified when a row is
being highlighted by calling `highlightRow(sectionID, rowID)`. This
sets a boolean value of adjacentRowHighlighted in renderSeparator, allowing you
to control the separators above and below the highlighted row. The highlighted
state of a row can be reset by calling highlightRow(null).
| Type | Required |
| - | - |
| function | Yes |
---
### `renderScrollComponent`
(props) => renderable
A function that returns the scrollable component in which the list rows
are rendered. Defaults to returning a ScrollView with the given props.
| Type | Required |
| - | - |
| function | Yes |
---
### `scrollRenderAheadDistance`
How early to start rendering rows before they come on screen, in
pixels.
| Type | Required |
| - | - |
| number | Yes |
---
### `stickyHeaderIndices`
An array of child indices determining which children get docked to the
top of the screen when scrolling. For example, passing
`stickyHeaderIndices={[0]}` will cause the first child to be fixed to the
top of the scroll view. This property is not supported in conjunction
with `horizontal={true}`.
| Type | Required |
| - | - |
| array of number | Yes |
---
### `enableEmptySections`
Flag indicating whether empty section headers should be rendered. In the future release
empty section headers will be rendered by default, and the flag will be deprecated.
If empty sections are not desired to be rendered their indices should be excluded from sectionID object.
| Type | Required |
| - | - |
| bool | No |
---
### `renderHeader`
| Type | Required |
| - | - |
| function | No |
---
### `onEndReached`
Called when all rows have been rendered and the list has been scrolled
to within onEndReachedThreshold of the bottom. The native scroll
event is provided.
| Type | Required |
| - | - |
| function | No |
---
### `stickySectionHeadersEnabled`
Makes the sections headers sticky. The sticky behavior means that it
will scroll with the content at the top of the section until it reaches
the top of the screen, at which point it will stick to the top until it
is pushed off the screen by the next section header. This property is
not supported in conjunction with `horizontal={true}`. Only enabled by
default on iOS because of typical platform standards.
| Type | Required |
| - | - |
| bool | No |
---
### `renderSectionHeader`
(sectionData, sectionID) => renderable
If provided, a header is rendered for this section.
| Type | Required |
| - | - |
| function | No |
---
### `renderSeparator`
(sectionID, rowID, adjacentRowHighlighted) => renderable
If provided, a renderable component to be rendered as the separator
below each row but not the last row if there is a section header below.
Take a sectionID and rowID of the row above and whether its adjacent row
is highlighted.
| Type | Required |
| - | - |
| function | No |
---
### `onChangeVisibleRows`
(visibleRows, changedRows) => void
Called when the set of visible rows changes. `visibleRows` maps
{ sectionID: { rowID: true }} for all the visible rows, and
`changedRows` maps { sectionID: { rowID: true | false }} for the rows
that have changed their visibility, with true indicating visible, and
false indicating the view has moved out of view.
| Type | Required |
| - | - |
| function | No |
---
### `removeClippedSubviews`
A performance optimization for improving scroll perf of
large lists, used in conjunction with overflow: 'hidden' on the row
containers. This is enabled by default.
| Type | Required |
| - | - |
| bool | No |
---
### `renderFooter`
() => renderable
The header and footer are always rendered (if these props are provided)
on every render pass. If they are expensive to re-render, wrap them
in StaticContainer or other mechanism as appropriate. Footer is always
at the bottom of the list, and header at the top, on every render pass.
In a horizontal ListView, the header is rendered on the left and the
footer on the right.
| Type | Required |
| - | - |
| function | No |
## Methods
### `getMetrics()`
```javascript
getMetrics()
```
Exports some data, e.g. for perf investigations or analytics.
---
### `scrollTo()`
```javascript
scrollTo(...args: Array)
```
Scrolls to a given x, y offset, either immediately or with a smooth animation.
See `ScrollView#scrollTo`.
---
### `scrollToEnd()`
```javascript
scrollToEnd([options]: object)
```
If this is a vertical ListView scrolls to the bottom.
If this is a horizontal ListView scrolls to the right.
Use `scrollToEnd({animated: true})` for smooth animated scrolling,
`scrollToEnd({animated: false})` for immediate scrolling.
If no options are passed, `animated` defaults to true.
See `ScrollView#scrollToEnd`.
---
### `flashScrollIndicators()`
```javascript
flashScrollIndicators()
```
Displays the scroll indicators momentarily.

View File

@ -1,290 +0,0 @@
---
id: listviewdatasource
title: ListViewDataSource
layout: docs
category: APIs
permalink: docs/listviewdatasource.html
next: netinfo
previous: linking
---
Provides efficient data processing and access to the
`ListView` component. A `ListViewDataSource` is created with functions for
extracting data from the input blob, and comparing elements (with default
implementations for convenience). The input blob can be as simple as an
array of strings, or an object with rows nested inside section objects.
To update the data in the datasource, use `cloneWithRows` (or
`cloneWithRowsAndSections` if you care about sections). The data in the
data source is immutable, so you can't modify it directly. The clone methods
suck in the new data and compute a diff for each row so ListView knows
whether to re-render it or not.
In this example, a component receives data in chunks, handled by
`_onDataArrived`, which concats the new data onto the old data and updates the
data source. We use `concat` to create a new array - mutating `this._data`,
e.g. with `this._data.push(newRowData)`, would be an error. `_rowHasChanged`
understands the shape of the row data and knows how to efficiently compare
it.
```
getInitialState: function() {
var ds = new ListView.DataSource({rowHasChanged: this._rowHasChanged});
return {ds};
},
_onDataArrived(newData) {
this._data = this._data.concat(newData);
this.setState({
ds: this.state.ds.cloneWithRows(this._data)
});
}
```
### Methods
- [`constructor`](docs/listviewdatasource.html#constructor)
- [`cloneWithRows`](docs/listviewdatasource.html#clonewithrows)
- [`cloneWithRowsAndSections`](docs/listviewdatasource.html#clonewithrowsandsections)
- [`getRowCount`](docs/listviewdatasource.html#getrowcount)
- [`getRowAndSectionCount`](docs/listviewdatasource.html#getrowandsectioncount)
- [`rowShouldUpdate`](docs/listviewdatasource.html#rowshouldupdate)
- [`getRowData`](docs/listviewdatasource.html#getrowdata)
- [`getRowIDForFlatIndex`](docs/listviewdatasource.html#getrowidforflatindex)
- [`getSectionIDForFlatIndex`](docs/listviewdatasource.html#getsectionidforflatindex)
- [`getSectionLengths`](docs/listviewdatasource.html#getsectionlengths)
- [`sectionHeaderShouldUpdate`](docs/listviewdatasource.html#sectionheadershouldupdate)
- [`getSectionHeaderData`](docs/listviewdatasource.html#getsectionheaderdata)
---
# Reference
## Methods
### `constructor()`
```javascript
constructor(params)
```
You can provide custom extraction and `hasChanged` functions for section
headers and rows. If absent, data will be extracted with the
`defaultGetRowData` and `defaultGetSectionHeaderData` functions.
The default extractor expects data of one of the following forms:
{ sectionID_1: { rowID_1: <rowData1>, ... }, ... }
or
{ sectionID_1: [ <rowData1>, <rowData2>, ... ], ... }
or
[ [ <rowData1>, <rowData2>, ... ], ... ]
The constructor takes in a params argument that can contain any of the
following:
- getRowData(dataBlob, sectionID, rowID);
- getSectionHeaderData(dataBlob, sectionID);
- rowHasChanged(prevRowData, nextRowData);
- sectionHeaderHasChanged(prevSectionData, nextSectionData);
---
### `cloneWithRows()`
```javascript
cloneWithRows(dataBlob, rowIdentities)
```
Clones this `ListViewDataSource` with the specified `dataBlob` and
`rowIdentities`. The `dataBlob` is just an arbitrary blob of data. At
construction an extractor to get the interesting information was defined
(or the default was used).
The `rowIdentities` is a 2D array of identifiers for rows.
ie. [['a1', 'a2'], ['b1', 'b2', 'b3'], ...]. If not provided, it's
assumed that the keys of the section data are the row identities.
Note: This function does NOT clone the data in this data source. It simply
passes the functions defined at construction to a new data source with
the data specified. If you wish to maintain the existing data you must
handle merging of old and new data separately and then pass that into
this function as the `dataBlob`.
---
### `cloneWithRowsAndSections()`
```javascript
cloneWithRowsAndSections(dataBlob, sectionIdentities, rowIdentities)
```
This performs the same function as the `cloneWithRows` function but here
you also specify what your `sectionIdentities` are. If you don't care
about sections you should safely be able to use `cloneWithRows`.
`sectionIdentities` is an array of identifiers for sections.
ie. ['s1', 's2', ...]. The identifiers should correspond to the keys or array indexes
of the data you wish to include. If not provided, it's assumed that the
keys of dataBlob are the section identities.
Note: this returns a new object!
```
const dataSource = ds.cloneWithRowsAndSections({
addresses: ['row 1', 'row 2'],
phone_numbers: ['data 1', 'data 2'],
}, ['phone_numbers']);
```
---
### `getRowCount()`
```javascript
getRowCount()
```
Returns the total number of rows in the data source.
If you are specifying the rowIdentities or sectionIdentities, then `getRowCount` will return the number of rows in the filtered data source.
---
### `getRowAndSectionCount()`
```javascript
getRowAndSectionCount()
```
Returns the total number of rows in the data source (see `getRowCount` for how this is calculated) plus the number of sections in the data.
If you are specifying the rowIdentities or sectionIdentities, then `getRowAndSectionCount` will return the number of rows & sections in the filtered data source.
---
### `rowShouldUpdate()`
```javascript
rowShouldUpdate(sectionIndex, rowIndex)
```
Returns if the row is dirtied and needs to be rerendered
---
### `getRowData()`
```javascript
getRowData(sectionIndex, rowIndex)
```
Gets the data required to render the row.
---
### `getRowIDForFlatIndex()`
```javascript
getRowIDForFlatIndex(index)
```
Gets the rowID at index provided if the dataSource arrays were flattened,
or null of out of range indexes.
---
### `getSectionIDForFlatIndex()`
```javascript
getSectionIDForFlatIndex(index)
```
Gets the sectionID at index provided if the dataSource arrays were flattened,
or null for out of range indexes.
---
### `getSectionLengths()`
```javascript
getSectionLengths()
```
Returns an array containing the number of rows in each section
---
### `sectionHeaderShouldUpdate()`
```javascript
sectionHeaderShouldUpdate(sectionIndex)
```
Returns if the section header is dirtied and needs to be rerendered
---
### `getSectionHeaderData()`
```javascript
getSectionHeaderData(sectionIndex)
```
Gets the data required to render the section header

View File

@ -1,72 +0,0 @@
---
id: maskedviewios
title: MaskedViewIOS
layout: docs
category: components
permalink: docs/maskedviewios.html
next: modal
previous: listview
---
Renders the child view with a mask specified in the `maskElement` prop.
```
import React from 'react';
import { MaskedViewIOS, Text, View } from 'react-native';
class MyMaskedView extends React.Component {
render() {
return (
<MaskedViewIOS
style={{ flex: 1 }}
maskElement={
<View style={styles.maskContainerStyle}>
<Text style={styles.maskTextStyle}>
Basic Mask
</Text>
</View>
}
>
<View style={{ flex: 1, backgroundColor: 'blue' }} />
</MaskedViewIOS>
);
}
}
```
The above example will render a view with a blue background that fills its
parent, and then mask that view with text that says "Basic Mask".
The alpha channel of the view rendered by the `maskElement` prop determines how
much of the view's content and background shows through. Fully or partially
opaque pixels allow the underlying content to show through but fully
transparent pixels block that content.
### Props
- [View props...](docs/view.html#props)
- [`maskElement`](docs/maskedviewios.html#maskelement)
---
# Reference
## Props
### `maskElement`
Should be a React element to be rendered and applied as the mask for the child element.
| Type | Required |
| - | - |
| element | Yes |

View File

@ -1,201 +0,0 @@
---
id: modal
title: Modal
layout: docs
category: components
permalink: docs/modal.html
next: navigatorios
previous: maskedviewios
---
### Props
- [`visible`](docs/modal.html#visible)
- [`supportedOrientations`](docs/modal.html#supportedorientations)
- [`onRequestClose`](docs/modal.html#onrequestclose)
- [`onShow`](docs/modal.html#onshow)
- [`transparent`](docs/modal.html#transparent)
- [`animationType`](docs/modal.html#animationtype)
- [`hardwareAccelerated`](docs/modal.html#hardwareaccelerated)
- [`onDismiss`](docs/modal.html#ondismiss)
- [`onOrientationChange`](docs/modal.html#onorientationchange)
- [`presentationStyle`](docs/modal.html#presentationstyle)
- [`animated`](docs/modal.html#animated)
---
# Reference
## Props
### `visible`
The `visible` prop determines whether your modal is visible.
| Type | Required |
| - | - |
| bool | No |
---
### `supportedOrientations`
The `supportedOrientations` prop allows the modal to be rotated to any of the specified orientations.
On iOS, the modal is still restricted by what's specified in your app's Info.plist's UISupportedInterfaceOrientations field.
When using `presentationStyle` of `pageSheet` or `formSheet`, this property will be ignored by iOS.
| Type | Required | Platform |
| - | - | - |
| array of enum('portrait', 'portrait-upside-down', 'landscape', 'landscape-left', 'landscape-right') | No | iOS |
---
### `onRequestClose`
The `onRequestClose` callback is called when the user taps the hardware back button on Android or the menu button on Apple TV.
| Type | Required |
| - | - |
| function | Required on Android and Apple TV |
---
### `onShow`
The `onShow` prop allows passing a function that will be called once the modal has been shown.
| Type | Required |
| - | - |
| function | No |
---
### `transparent`
The `transparent` prop determines whether your modal will fill the entire view. Setting this to `true` will render the modal over a transparent background.
| Type | Required |
| - | - |
| bool | No |
---
### `animationType`
The `animationType` prop controls how the modal animates.
- `slide` slides in from the bottom
- `fade` fades into view
- `none` appears without an animation
Default is set to `none`.
| Type | Required |
| - | - |
| enum('none', 'slide', 'fade') | No |
---
### `hardwareAccelerated`
The `hardwareAccelerated` prop controls whether to force hardware acceleration for the underlying window.
| Type | Required | Platform |
| - | - | - |
| bool | No | Android |
---
### `onDismiss`
The `onDismiss` prop allows passing a function that will be called once the modal has been dismissed.
| Type | Required | Platform |
| - | - | - |
| function | No | iOS |
---
### `onOrientationChange`
The `onOrientationChange` callback is called when the orientation changes while the modal is being displayed.
The orientation provided is only 'portrait' or 'landscape'. This callback is also called on initial render, regardless of the current orientation.
| Type | Required | Platform |
| - | - | - |
| function | No | iOS |
---
### `presentationStyle`
The `presentationStyle` prop controls how the modal appears (generally on larger devices such as iPad or plus-sized iPhones).
See https://developer.apple.com/reference/uikit/uimodalpresentationstyle for details.
- `fullScreen` covers the screen completely
- `pageSheet` covers portrait-width view centered (only on larger devices)
- `formSheet` covers narrow-width view centered (only on larger devices)
- `overFullScreen` covers the screen completely, but allows transparency
Default is set to `overFullScreen` or `fullScreen` depending on `transparent` property.
| Type | Required | Platform |
| - | - | - |
| enum('fullScreen', 'pageSheet', 'formSheet', 'overFullScreen') | No | iOS |
---
### `animated`
**Deprecated.** Use the `animationType` prop instead.
| Type | Required |
| - | - |
| bool | No |

View File

@ -1,57 +0,0 @@
---
id: more-resources
title: More Resources
layout: docs
category: The Basics
permalink: docs/more-resources.html
next: components-and-apis
previous: network
---
If you just read through this website, you should be able to build a pretty cool React Native app. But React Native isn't just a product made by one company - it's a community of thousands of developers. So if you're interested in React Native, here's some related stuff you might want to check out.
## Popular Libraries
If you're using React Native, you probably already know about [React](https://facebook.github.io/react/). So I feel a bit silly mentioning this. But if you haven't, check out React - it's the best way to build a modern website.
One common question is how to handle the "state" of your React Native application. The most popular library for this is [Redux](http://redux.js.org/). Don't be afraid of how often Redux uses the word "reducer" - it's a pretty simple library, and there's also a nice [series of videos](https://egghead.io/courses/getting-started-with-redux) explaining it.
If you're looking for a library that does a specific thing, check out [Awesome React Native](http://www.awesome-react-native.com/), a curated list of components that also has demos, articles, and other stuff.
## Examples
Try out apps from the [Showcase](https://facebook.github.io/react-native/showcase.html) to see what React Native is capable of! There are also some [example apps on GitHub](https://github.com/ReactNativeNews/React-Native-Apps). You can run the apps on a simulator or device, and you can see the source code for these apps, which is neat.
The folks who built the app for Facebook's F8 conference in 2016 also [open-sourced the code](https://github.com/fbsamples/f8app) and wrote up a [detailed series of tutorials](http://makeitopen.com/docs/en/1-1-planning.html). This is useful if you want a more in-depth example that's more realistic than most sample apps out there.
## Extending React Native
- Looking for a component? [JS.coach](https://js.coach/react-native)
- Fellow developers write and publish React Native modules to npm and open source them on GitHub.
- Making modules helps grow the React Native ecosystem and community. We recommend writing modules for your use cases and sharing them on npm.
- Read the guides on Native Modules ([iOS](https://facebook.github.io/react-native/docs/native-modules-ios.html), [Android](https://facebook.github.io/react-native/docs/native-modules-android.html)) and Native UI Components ([iOS](https://facebook.github.io/react-native/docs/native-components-ios.html), [Android](https://facebook.github.io/react-native/docs/native-components-android.html)) if you are interested in extending native functionality.
## Development Tools
[Nuclide](https://nuclide.io/) is the IDE that Facebook uses internally for JavaScript development. The killer feature of Nuclide is its debugging ability. It also has great inline Flow support. [VS Code](https://code.visualstudio.com/) is another IDE that is popular with JavaScript developers.
[Ignite](https://github.com/infinitered/ignite) is a starter kit that uses Redux and a few different common UI libraries. It has a CLI to generate apps, components, and containers. If you like all of the individual tech choices, Ignite could be perfect for you.
[CodePush](https://microsoft.github.io/code-push/) is a service from Microsoft that makes it easy to deploy live updates to your React Native app. If you don't like going through the app store process to deploy little tweaks, and you also don't like setting up your own backend, give CodePush a try.
[Expo](https://docs.expo.io) is a development environment plus application that focuses on letting you build React Native apps in the Expo development environment, without ever touching Xcode or Android Studio. If you wish React Native was even more JavaScripty and webby, check out Expo.
The [React Developer Tools](docs/debugging.html#react-developer-tools) are great for debugging React and React Native apps.
## Where React Native People Hang Out
The [React Native Community](https://www.facebook.com/groups/react.native.community) Facebook group has thousands of developers, and it's pretty active. Come there to show off your project, or ask how other people solved similar problems.
[Reactiflux](https://discord.gg/0ZcbPKXt5bZjGY5n) is a Discord chat where a lot of React-related discussion happens, including React Native. Discord is just like Slack except it works better for open source projects with a zillion contributors. Check out the #react-native channel.
The [React Twitter account](https://twitter.com/reactjs) covers both React and React Native. Follow the React Native [Twitter account](https://twitter.com/reactnative) and [blog](/react-native/blog/) to find out what's happening in the world of React Native.
There are a lot of [React Native Meetups](http://www.meetup.com/topics/react-native/) that happen around the world. Often there is React Native content in React meetups as well.
Sometimes we have React conferences. We posted the [videos from React.js Conf 2017](https://www.youtube.com/playlist?list=PLb0IAmt7-GS3fZ46IGFirdqKTIxlws7e0) and [React.js Conf 2016](https://www.youtube.com/playlist?list=PLb0IAmt7-GS0M8Q95RIc2lOM6nc77q1IY), and we'll probably have more conferences in the future, too. Stay tuned. You can also find a list of dedicated React Native conferences [here](http://www.awesome-react-native.com/#conferences).

View File

@ -1,197 +0,0 @@
---
id: native-components-android
title: Native UI Components
layout: docs
category: Guides (Android)
permalink: docs/native-components-android.html
banner: ejected
next: custom-webview-android
previous: native-modules-android
---
There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like `ScrollView` and `TextInput`, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, it's quite easy to wrap up these existing components for seamless integration with your React Native application.
Like the native module guide, this too is a more advanced guide that assumes you are somewhat familiar with Android SDK programming. This guide will show you how to build a native UI component, walking you through the implementation of a subset of the existing `ImageView `component available in the core React Native library.
## ImageView example
For this example we are going to walk through the implementation requirements to allow the use of ImageViews in JavaScript.
Native views are created and manipulated by extending `ViewManager` or more commonly `SimpleViewManager` . A `SimpleViewManager` is convenient in this case because it applies common properties such as background color, opacity, and Flexbox layout.
These subclasses are essentially singletons - only one instance of each is created by the bridge. They vend native views to the `NativeViewHierarchyManager`, which delegates back to them to set and update the properties of the views as necessary. The `ViewManagers` are also typically the delegates for the views, sending events back to JavaScript via the bridge.
Vending a view is simple:
1. Create the ViewManager subclass.
2. Implement the `createViewInstance` method
3. Expose view property setters using `@ReactProp` (or `@ReactPropGroup`) annotation
4. Register the manager in `createViewManagers` of the applications package.
5. Implement the JavaScript module
## 1. Create the `ViewManager` subclass
In this example we create view manager class `ReactImageManager` that extends `SimpleViewManager` of type `ReactImageView`. `ReactImageView` is the type of object managed by the manager, this will be the custom native view. Name returned by `getName` is used to reference the native view type from JavaScript.
```java
...
public class ReactImageManager extends SimpleViewManager<ReactImageView> {
public static final String REACT_CLASS = "RCTImageView";
@Override
public String getName() {
return REACT_CLASS;
}
```
## 2. Implement method `createViewInstance`
Views are created in the `createViewInstance` method, the view should initialize itself in its default state, any properties will be set via a follow up call to `updateView.`
```java
@Override
public ReactImageView createViewInstance(ThemedReactContext context) {
return new ReactImageView(context, Fresco.newDraweeControllerBuilder(), mCallerContext);
}
```
## 3. Expose view property setters using `@ReactProp` (or `@ReactPropGroup`) annotation
Properties that are to be reflected in JavaScript needs to be exposed as setter method annotated with `@ReactProp` (or `@ReactPropGroup`). Setter method should take view to be updated (of the current view type) as a first argument and property value as a second argument. Setter should be declared as a `void` method and should be `public`. Property type sent to JS is determined automatically based on the type of value argument of the setter. The following type of values are currently supported: `boolean`, `int`, `float`, `double`, `String`, `Boolean`, `Integer`, `ReadableArray`, `ReadableMap`.
Annotation `@ReactProp` has one obligatory argument `name` of type `String`. Name assigned to the `@ReactProp` annotation linked to the setter method is used to reference the property on JS side.
Except from `name`, `@ReactProp` annotation may take following optional arguments: `defaultBoolean`, `defaultInt`, `defaultFloat`. Those arguments should be of the corresponding primitive type (accordingly `boolean`, `int`, `float`) and the value provided will be passed to the setter method in case when the property that the setter is referencing has been removed from the component. Note that "default" values are only provided for primitive types, in case when setter is of some complex type, `null` will be provided as a default value in case when corresponding property gets removed.
Setter declaration requirements for methods annotated with `@ReactPropGroup` are different than for `@ReactProp`, please refer to the `@ReactPropGroup` annotation class docs for more information about it.
**IMPORTANT!** in ReactJS updating the property value will result in setter method call. Note that one of the ways we can update component is by removing properties that have been set before. In that case setter method will be called as well to notify view manager that property has changed. In that case "default" value will be provided (for primitive types "default" can value can be specified using `defaultBoolean`, `defaultFloat`, etc. arguments of `@ReactProp` annotation, for complex types setter will be called with value set to `null`).
```java
@ReactProp(name = "src")
public void setSrc(ReactImageView view, @Nullable ReadableArray sources) {
view.setSource(sources);
}
@ReactProp(name = "borderRadius", defaultFloat = 0f)
public void setBorderRadius(ReactImageView view, float borderRadius) {
view.setBorderRadius(borderRadius);
}
@ReactProp(name = ViewProps.RESIZE_MODE)
public void setResizeMode(ReactImageView view, @Nullable String resizeMode) {
view.setScaleType(ImageResizeMode.toScaleType(resizeMode));
}
```
## 4. Register the `ViewManager`
The final Java step is to register the ViewManager to the application, this happens in a similar way to [Native Modules](docs/native-modules-android.html), via the applications package member function `createViewManagers.`
```java
@Override
public List<ViewManager> createViewManagers(
ReactApplicationContext reactContext) {
return Arrays.<ViewManager>asList(
new ReactImageManager()
);
}
```
## 5. Implement the JavaScript module
The very final step is to create the JavaScript module that defines the interface layer between Java and JavaScript for the users of your new view. Much of the effort is handled by internal React code in Java and JavaScript and all that is left for you is to describe the `propTypes`.
```js
// ImageView.js
import PropTypes from 'prop-types';
import { requireNativeComponent, View } from 'react-native';
var iface = {
name: 'ImageView',
propTypes: {
src: PropTypes.string,
borderRadius: PropTypes.number,
resizeMode: PropTypes.oneOf(['cover', 'contain', 'stretch']),
...View.propTypes // include the default view properties
},
};
module.exports = requireNativeComponent('RCTImageView', iface);
```
`requireNativeComponent` commonly takes two parameters, the first is the name of the native view and the second is an object that describes the component interface. The component interface should declare a friendly `name` for use in debug messages and must declare the `propTypes` reflected by the Native View. The `propTypes` are used for checking the validity of a user's use of the native view. Note that if you need your JavaScript component to do more than just specify a name and propTypes, like do custom event handling, you can wrap the native component in a normal react component. In that case, you want to pass in the wrapper component instead of `iface` to `requireNativeComponent`. This is illustrated in the `MyCustomView` example below.
# Events
So now we know how to expose native view components that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning? When a native event occurs the native code should issue an event to the JavaScript representation of the View, and the two views are linked with the value returned from the `getId()` method.
```java
class MyCustomView extends View {
...
public void onReceiveNativeEvent() {
WritableMap event = Arguments.createMap();
event.putString("message", "MyMessage");
ReactContext reactContext = (ReactContext)getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
getId(),
"topChange",
event);
}
}
```
To map the `topChange` event name to the `onChange` callback prop in JavaScript, register it by overriding the `getExportedCustomBubblingEventTypeConstants` method in your `ViewManager`:
```java
public class ReactImageManager extends SimpleViewManager<MyCustomView> {
...
public Map getExportedCustomBubblingEventTypeConstants() {
return MapBuilder.builder()
.put(
"topChange",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onChange")))
.build();
}
}
```
This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:
```js
// MyCustomView.js
class MyCustomView extends React.Component {
constructor(props) {
super(props);
this._onChange = this._onChange.bind(this);
}
_onChange(event: Event) {
if (!this.props.onChangeMessage) {
return;
}
this.props.onChangeMessage(event.nativeEvent.message);
}
render() {
return <RCTMyCustomView {...this.props} onChange={this._onChange} />;
}
}
MyCustomView.propTypes = {
/**
* Callback that is called continuously when the user is dragging the map.
*/
onChangeMessage: PropTypes.func,
...
};
var RCTMyCustomView = requireNativeComponent(`RCTMyCustomView`, MyCustomView, {
nativeOnly: {onChange: true}
});
```
Note the use of `nativeOnly` above. Sometimes you'll have some special properties that you need to expose for the native component, but don't actually want them as part of the API for the associated React component. For example, `Switch` has a custom `onChange` handler for the raw native event, and exposes an `onValueChange` handler property that is invoked with just the boolean value rather than the raw event (similar to `onChangeMessage` in the example above). Since you don't want these native only properties to be part of the API, you don't want to put them in `propTypes`, but if you don't you'll get an error. The solution is simply to call them out via the `nativeOnly` option.

View File

@ -1,446 +0,0 @@
---
id: native-components-ios
title: Native UI Components
layout: docs
category: Guides (iOS)
permalink: docs/native-components-ios.html
banner: ejected
next: custom-webview-ios
previous: native-modules-ios
---
There are tons of native UI widgets out there ready to be used in the latest apps - some of them are part of the platform, others are available as third-party libraries, and still more might be in use in your very own portfolio. React Native has several of the most critical platform components already wrapped, like `ScrollView` and `TextInput`, but not all of them, and certainly not ones you might have written yourself for a previous app. Fortunately, it's quite easy to wrap up these existing components for seamless integration with your React Native application.
Like the native module guide, this too is a more advanced guide that assumes you are somewhat familiar with iOS programming. This guide will show you how to build a native UI component, walking you through the implementation of a subset of the existing `MapView` component available in the core React Native library.
## iOS MapView example
Let's say we want to add an interactive Map to our app - might as well use [`MKMapView`](https://developer.apple.com/library/prerelease/mac/documentation/MapKit/Reference/MKMapView_Class/index.html), we just need to make it usable from JavaScript.
Native views are created and manipulated by subclasses of `RCTViewManager`. These subclasses are similar in function to view controllers, but are essentially singletons - only one instance of each is created by the bridge. They expose native views to the `RCTUIManager`, which delegates back to them to set and update the properties of the views as necessary. The `RCTViewManager`s are also typically the delegates for the views, sending events back to JavaScript via the bridge.
Exposing a view is simple:
- Subclass `RCTViewManager` to create a manager for your component.
- Add the `RCT_EXPORT_MODULE()` marker macro.
- Implement the `-(UIView *)view` method.
```objectivec
// RNTMapManager.m
#import <MapKit/MapKit.h>
#import <React/RCTViewManager.h>
@interface RNTMapManager : RCTViewManager
@end
@implementation RNTMapManager
RCT_EXPORT_MODULE()
- (UIView *)view
{
return [[MKMapView alloc] init];
}
@end
```
**Note:** Do not attempt to set the `frame` or `backgroundColor` properties on the `UIView` instance that you expose through the `-view` method. React Native will overwrite the values set by your custom class in order to match your JavaScript component's layout props. If you need this granularity of control it might be better to wrap the `UIView` instance you want to style in another `UIView` and return the wrapper `UIView` instead. See [Issue 2948](https://github.com/facebook/react-native/issues/2948) for more context.
> In the example above, we prefixed our class name with `RNT`. Prefixes are used to avoid name collisions with other frameworks. Apple frameworks use two-letter prefixes, and React Native uses `RCT` as a prefix. In order to avoid name collisions, we recommend using a three-letter prefix other than `RCT` in your own classes.
Then you just need a little bit of JavaScript to make this a usable React component:
```javascript
// MapView.js
import { requireNativeComponent } from 'react-native';
// requireNativeComponent automatically resolves 'RNTMap' to 'RNTMapManager'
module.exports = requireNativeComponent('RNTMap', null);
// MyApp.js
import MapView from './MapView.js';
...
render() {
return <MapView style={{ flex: 1 }} />;
}
```
Make sure to use `RNTMap` here. We want to require the manager here, which will expose the view of our manager for use in Javascript.
**Note:** When rendering, don't forget to stretch the view, otherwise you'll be staring at a blank screen.
```javascript
render() {
return <MapView style={{flex: 1}} />;
}
```
This is now a fully-functioning native map view component in JavaScript, complete with pinch-zoom and other native gesture support. We can't really control it from JavaScript yet, though :(
## Properties
The first thing we can do to make this component more usable is to bridge over some native properties. Let's say we want to be able to disable zooming and specify the visible region. Disabling zoom is a simple boolean, so we add this one line:
```objectivec
// RNTMapManager.m
RCT_EXPORT_VIEW_PROPERTY(zoomEnabled, BOOL)
```
Note that we explicitly specify the type as `BOOL` - React Native uses `RCTConvert` under the hood to convert all sorts of different data types when talking over the bridge, and bad values will show convenient "RedBox" errors to let you know there is an issue ASAP. When things are straightforward like this, the whole implementation is taken care of for you by this macro.
Now to actually disable zooming, we set the property in JS:
```javascript
// MyApp.js
<MapView
zoomEnabled={false}
style={{ flex: 1 }}
/>;
```
To document the properties (and which values they accept) of our MapView component we'll add a wrapper component and document the interface with React `PropTypes`:
```javascript
// MapView.js
import PropTypes from 'prop-types';
import React from 'react';
import { requireNativeComponent } from 'react-native';
class MapView extends React.Component {
render() {
return <RNTMap {...this.props} />;
}
}
MapView.propTypes = {
/**
* A Boolean value that determines whether the user may use pinch
* gestures to zoom in and out of the map.
*/
zoomEnabled: PropTypes.bool,
};
var RNTMap = requireNativeComponent('RNTMap', MapView);
module.exports = MapView;
```
Now we have a nicely documented wrapper component that is easy to work with. Note that we changed the second argument to `requireNativeComponent` from `null` to the new `MapView` wrapper component. This allows the infrastructure to verify that the propTypes match the native props to reduce the chances of mismatches between the ObjC and JS code.
Next, let's add the more complex `region` prop. We start by adding the native code:
```objectivec
// RNTMapManager.m
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, MKMapView)
{
[view setRegion:json ? [RCTConvert MKCoordinateRegion:json] : defaultView.region animated:YES];
}
```
Ok, this is more complicated than the simple `BOOL` case we had before. Now we have a `MKCoordinateRegion` type that needs a conversion function, and we have custom code so that the view will animate when we set the region from JS. Within the function body that we provide, `json` refers to the raw value that has been passed from JS. There is also a `view` variable which gives us access to the manager's view instance, and a `defaultView` that we use to reset the property back to the default value if JS sends us a null sentinel.
You could write any conversion function you want for your view - here is the implementation for `MKCoordinateRegion` via a category on `RCTConvert`. It uses an already existing category of ReactNative `RCTConvert+CoreLocation`:
```objectivec
// RNTMapManager.m
#import "RCTConvert+Mapkit.m"
// RCTConvert+Mapkit.h
#import <MapKit/MapKit.h>
#import <React/RCTConvert.h>
#import <CoreLocation/CoreLocation.h>
#import <React/RCTConvert+CoreLocation.h>
@interface RCTConvert (Mapkit)
+ (MKCoordinateSpan)MKCoordinateSpan:(id)json;
+ (MKCoordinateRegion)MKCoordinateRegion:(id)json;
@end
@implementation RCTConvert(MapKit)
+ (MKCoordinateSpan)MKCoordinateSpan:(id)json
{
json = [self NSDictionary:json];
return (MKCoordinateSpan){
[self CLLocationDegrees:json[@"latitudeDelta"]],
[self CLLocationDegrees:json[@"longitudeDelta"]]
};
}
+ (MKCoordinateRegion)MKCoordinateRegion:(id)json
{
return (MKCoordinateRegion){
[self CLLocationCoordinate2D:json],
[self MKCoordinateSpan:json]
};
}
@end
```
These conversion functions are designed to safely process any JSON that the JS might throw at them by displaying "RedBox" errors and returning standard initialization values when missing keys or other developer errors are encountered.
To finish up support for the `region` prop, we need to document it in `propTypes` (or we'll get an error that the native prop is undocumented), then we can set it just like any other prop:
```javascript
// MapView.js
MapView.propTypes = {
/**
* A Boolean value that determines whether the user may use pinch
* gestures to zoom in and out of the map.
*/
zoomEnabled: PropTypes.bool,
/**
* The region to be displayed by the map.
*
* The region is defined by the center coordinates and the span of
* coordinates to display.
*/
region: PropTypes.shape({
/**
* Coordinates for the center of the map.
*/
latitude: PropTypes.number.isRequired,
longitude: PropTypes.number.isRequired,
/**
* Distance between the minimum and the maximum latitude/longitude
* to be displayed.
*/
latitudeDelta: PropTypes.number.isRequired,
longitudeDelta: PropTypes.number.isRequired,
}),
};
// MyApp.js
render() {
var region = {
latitude: 37.48,
longitude: -122.16,
latitudeDelta: 0.1,
longitudeDelta: 0.1,
};
return (
<MapView
region={region}
zoomEnabled={false}
style={{ flex: 1 }}
/>
);
}
```
Here you can see that the shape of the region is explicit in the JS documentation - ideally we could codegen some of this stuff, but that's not happening yet.
Sometimes your native component will have some special properties that you don't want to be part of the API for the associated React component. For example, `Switch` has a custom `onChange` handler for the raw native event, and exposes an `onValueChange` handler property that is invoked with just the boolean value rather than the raw event. Since you don't want these native only properties to be part of the API, you don't want to put them in `propTypes`, but if you don't you'll get an error. The solution is simply to add them to the `nativeOnly` option, e.g.
```javascript
var RCTSwitch = requireNativeComponent('RCTSwitch', Switch, {
nativeOnly: { onChange: true }
});
```
## Events
So now we have a native map component that we can control easily from JS, but how do we deal with events from the user, like pinch-zooms or panning to change the visible region?
Until now we've just returned a `MKMapView` instance from our manager's `-(UIView *)view` method. We can't add new properties to `MKMapView` so we have to create a new subclass from `MKMapView` which we use for our View. We can then add a `onRegionChange` callback on this subclass:
```objectivec
// RNTMapView.h
#import <MapKit/MapKit.h>
#import <React/RCTComponent.h>
@interface RNTMapView: MKMapView
@property (nonatomic, copy) RCTBubblingEventBlock onRegionChange;
@end
// RNTMapView.m
#import "RNTMapView.h"
@implementation RNTMapView
@end
```
Next, declare an event handler property on `RNTMapManager`, make it a delegate for all the views it exposes, and forward events to JS by calling the event handler block from the native view.
```objectivec{9,17,31-48}
// RNTMapManager.m
#import <MapKit/MapKit.h>
#import <React/RCTViewManager.h>
#import "RNTMapView.h"
#import "RCTConvert+Mapkit.m"
@interface RNTMapManager : RCTViewManager <MKMapViewDelegate>
@end
@implementation RNTMapManager
RCT_EXPORT_MODULE()
RCT_EXPORT_VIEW_PROPERTY(zoomEnabled, BOOL)
RCT_EXPORT_VIEW_PROPERTY(onRegionChange, RCTBubblingEventBlock)
RCT_CUSTOM_VIEW_PROPERTY(region, MKCoordinateRegion, MKMapView)
{
[view setRegion:json ? [RCTConvert MKCoordinateRegion:json] : defaultView.region animated:YES];
}
- (UIView *)view
{
RNTMapView *map = [RNTMapView new];
map.delegate = self;
return map;
}
#pragma mark MKMapViewDelegate
- (void)mapView:(RNTMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
if (!mapView.onRegionChange) {
return;
}
MKCoordinateRegion region = mapView.region;
mapView.onRegionChange(@{
@"region": @{
@"latitude": @(region.center.latitude),
@"longitude": @(region.center.longitude),
@"latitudeDelta": @(region.span.latitudeDelta),
@"longitudeDelta": @(region.span.longitudeDelta),
}
});
}
@end
```
In the delegate method `-mapView:regionDidChangeAnimated:` the event handler block is called on the corresponding view with the region data. Calling the `onRegionChange` event handler block results in calling the same callback prop in JavaScript. This callback is invoked with the raw event, which we typically process in the wrapper component to make a simpler API:
```javascript
// MapView.js
class MapView extends React.Component {
_onRegionChange = (event) => {
if (!this.props.onRegionChange) {
return;
}
// process raw event...
this.props.onRegionChange(event.nativeEvent);
}
render() {
return (
<RNTMap
{...this.props}
onRegionChange={this._onRegionChange}
/>
);
}
}
MapView.propTypes = {
/**
* Callback that is called continuously when the user is dragging the map.
*/
onRegionChange: PropTypes.func,
...
};
// MyApp.js
class MyApp extends React.Component {
onRegionChange(event) {
// Do stuff with event.region.latitude, etc.
}
render() {
var region = {
latitude: 37.48,
longitude: -122.16,
latitudeDelta: 0.1,
longitudeDelta: 0.1,
};
return (
<MapView
region={region}
zoomEnabled={false}
onRegionChange={this.onRegionChange}
/>
);
}
}
```
## Styles
Since all our native react views are subclasses of `UIView`, most style attributes will work like you would expect out of the box. Some components will want a default style, however, for example `UIDatePicker` which is a fixed size. This default style is important for the layout algorithm to work as expected, but we also want to be able to override the default style when using the component. `DatePickerIOS` does this by wrapping the native component in an extra view, which has flexible styling, and using a fixed style (which is generated with constants passed in from native) on the inner native component:
```javascript
// DatePickerIOS.ios.js
import { UIManager } from 'react-native';
var RCTDatePickerIOSConsts = UIManager.RCTDatePicker.Constants;
...
render: function() {
return (
<View style={this.props.style}>
<RCTDatePickerIOS
ref={DATEPICKER}
style={styles.rkDatePickerIOS}
...
/>
</View>
);
}
});
var styles = StyleSheet.create({
rkDatePickerIOS: {
height: RCTDatePickerIOSConsts.ComponentHeight,
width: RCTDatePickerIOSConsts.ComponentWidth,
},
});
```
The `RCTDatePickerIOSConsts` constants are exported from native by grabbing the actual frame of the native component like so:
```objectivec
// RCTDatePickerManager.m
- (NSDictionary *)constantsToExport
{
UIDatePicker *dp = [[UIDatePicker alloc] init];
[dp layoutIfNeeded];
return @{
@"ComponentHeight": @(CGRectGetHeight(dp.frame)),
@"ComponentWidth": @(CGRectGetWidth(dp.frame)),
@"DatePickerModes": @{
@"time": @(UIDatePickerModeTime),
@"date": @(UIDatePickerModeDate),
@"datetime": @(UIDatePickerModeDateAndTime),
}
};
}
```
This guide covered many of the aspects of bridging over custom native components, but there is even more you might need to consider, such as custom hooks for inserting and laying out subviews. If you want to go even deeper, check out the [source code](https://github.com/facebook/react-native/blob/master/React/Views) of some of the implemented components.

View File

@ -1,459 +0,0 @@
---
id: native-modules-android
title: Native Modules
layout: docs
category: Guides (Android)
permalink: docs/native-modules-android.html
banner: ejected
next: native-components-android
previous: app-extensions
---
Sometimes an app needs access to a platform API that React Native doesn't have a corresponding module for yet. Maybe you want to reuse some existing Java code without having to reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image processing, a database, or any number of advanced extensions.
We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform. This is a more advanced feature and we don't expect it to be part of the usual development process, however it is essential that it exists. If React Native doesn't support a native feature that you need, you should be able to build it yourself.
### Enable Gradle
If you plan to make changes in Java code, we recommend enabling [Gradle Daemon](https://docs.gradle.org/2.9/userguide/gradle_daemon.html) to speed up builds.
## The Toast Module
This guide will use the [Toast](http://developer.android.com/reference/android/widget/Toast.html) example. Let's say we would like to be able to create a toast message from JavaScript.
We start by creating a native module. A native module is a Java class that usually extends the `ReactContextBaseJavaModule` class and implements the functionality required by the JavaScript. Our goal here is to be able to write `ToastExample.show('Awesome', ToastExample.SHORT);` from JavaScript to display a short toast on the screen.
```java
package com.facebook.react.modules.toast;
import android.widget.Toast;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.util.Map;
import java.util.HashMap;
public class ToastModule extends ReactContextBaseJavaModule {
private static final String DURATION_SHORT_KEY = "SHORT";
private static final String DURATION_LONG_KEY = "LONG";
public ToastModule(ReactApplicationContext reactContext) {
super(reactContext);
}
}
```
`ReactContextBaseJavaModule` requires that a method called `getName` is implemented. The purpose of this method is to return the string name of the `NativeModule` which represents this class in JavaScript. So here we will call this `ToastExample` so that we can access it through `React.NativeModules.ToastExample` in JavaScript.
```java
@Override
public String getName() {
return "ToastExample";
}
```
An optional method called `getConstants` returns the constant values exposed to JavaScript. Its implementation is not required but is very useful to key pre-defined values that need to be communicated from JavaScript to Java in sync.
```java
@Override
public Map<String, Object> getConstants() {
final Map<String, Object> constants = new HashMap<>();
constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
return constants;
}
```
To expose a method to JavaScript a Java method must be annotated using `@ReactMethod`. The return type of bridge methods is always `void`. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).
```java
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
```
### Argument Types
The following argument types are supported for methods annotated with `@ReactMethod` and they directly map to their JavaScript equivalents
```
Boolean -> Bool
Integer -> Number
Double -> Number
Float -> Number
String -> String
Callback -> function
ReadableMap -> Object
ReadableArray -> Array
```
Read more about [ReadableMap](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableMap.java) and [ReadableArray](https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableArray.java)
### Register the Module
The last step within Java is to register the Module; this happens in the `createNativeModules` of your apps package. If a module is not registered it will not be available from JavaScript.
```java
package com.facebook.react.modules.toast;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AnExampleReactPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ToastModule(reactContext));
return modules;
}
}
```
The package needs to be provided in the `getPackages` method of the `MainApplication.java` file. This file exists under the android folder in your react-native application directory. The path to this file is: `android/app/src/main/java/com/your-app-name/MainApplication.java`.
```java
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new AnExampleReactPackage()); // <-- Add this line with your package name.
}
```
To make it simpler to access your new functionality from JavaScript, it is common to wrap the native module in a JavaScript module. This is not necessary but saves the consumers of your library the need to pull it off of `NativeModules` each time. This JavaScript file also becomes a good location for you to add any JavaScript side functionality.
```js
/**
* This exposes the native ToastExample module as a JS module. This has a
* function 'show' which takes the following parameters:
*
* 1. String message: A string with the text to toast
* 2. int duration: The duration of the toast. May be ToastExample.SHORT or
* ToastExample.LONG
*/
import { NativeModules } from 'react-native';
module.exports = NativeModules.ToastExample;
```
Now, from your other JavaScript file you can call the method like this:
```js
import ToastExample from './ToastExample';
ToastExample.show('Awesome', ToastExample.SHORT);
```
## Beyond Toasts
### Callbacks
Native modules also support a special kind of argument - a callback. In most cases it is used to provide the function call result to JavaScript.
```java
import com.facebook.react.bridge.Callback;
public class UIManagerModule extends ReactContextBaseJavaModule {
...
@ReactMethod
public void measureLayout(
int tag,
int ancestorTag,
Callback errorCallback,
Callback successCallback) {
try {
measureLayout(tag, ancestorTag, mMeasureBuffer);
float relativeX = PixelUtil.toDIPFromPixel(mMeasureBuffer[0]);
float relativeY = PixelUtil.toDIPFromPixel(mMeasureBuffer[1]);
float width = PixelUtil.toDIPFromPixel(mMeasureBuffer[2]);
float height = PixelUtil.toDIPFromPixel(mMeasureBuffer[3]);
successCallback.invoke(relativeX, relativeY, width, height);
} catch (IllegalViewOperationException e) {
errorCallback.invoke(e.getMessage());
}
}
...
```
This method would be accessed in JavaScript using:
```js
UIManager.measureLayout(
100,
100,
(msg) => {
console.log(msg);
},
(x, y, width, height) => {
console.log(x + ':' + y + ':' + width + ':' + height);
}
);
```
A native module is supposed to invoke its callback only once. It can, however, store the callback and invoke it later.
It is very important to highlight that the callback is not invoked immediately after the native function completes - remember that bridge communication is asynchronous, and this too is tied to the run loop.
### Promises
Native modules can also fulfill a promise, which can simplify your code, especially when using ES2016's `async/await` syntax. When the last parameter of a bridged native method is a `Promise`, its corresponding JS method will return a JS Promise object.
Refactoring the above code to use a promise instead of callbacks looks like this:
```java
import com.facebook.react.bridge.Promise;
public class UIManagerModule extends ReactContextBaseJavaModule {
...
private static final String E_LAYOUT_ERROR = "E_LAYOUT_ERROR";
@ReactMethod
public void measureLayout(
int tag,
int ancestorTag,
Promise promise) {
try {
measureLayout(tag, ancestorTag, mMeasureBuffer);
WritableMap map = Arguments.createMap();
map.putDouble("relativeX", PixelUtil.toDIPFromPixel(mMeasureBuffer[0]));
map.putDouble("relativeY", PixelUtil.toDIPFromPixel(mMeasureBuffer[1]));
map.putDouble("width", PixelUtil.toDIPFromPixel(mMeasureBuffer[2]));
map.putDouble("height", PixelUtil.toDIPFromPixel(mMeasureBuffer[3]));
promise.resolve(map);
} catch (IllegalViewOperationException e) {
promise.reject(E_LAYOUT_ERROR, e);
}
}
...
```
The JavaScript counterpart of this method returns a Promise. This means you can use the `await` keyword within an async function to call it and wait for its result:
```js
async function measureLayout() {
try {
var {
relativeX,
relativeY,
width,
height,
} = await UIManager.measureLayout(100, 100);
console.log(relativeX + ':' + relativeY + ':' + width + ':' + height);
} catch (e) {
console.error(e);
}
}
measureLayout();
```
### Threading
Native modules should not have any assumptions about what thread they are being called on, as the current assignment is subject to change in the future. If a blocking call is required, the heavy work should be dispatched to an internally managed worker thread, and any callbacks distributed from there.
### Sending Events to JavaScript
Native modules can signal events to JavaScript without being invoked directly. The easiest way to do this is to use the `RCTDeviceEventEmitter` which can be obtained from the `ReactContext` as in the code snippet below.
```java
...
private void sendEvent(ReactContext reactContext,
String eventName,
@Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
...
WritableMap params = Arguments.createMap();
...
sendEvent(reactContext, "keyboardWillShow", params);
```
JavaScript modules can then register to receive events by `addListenerOn` using the `Subscribable` mixin.
```js
import { DeviceEventEmitter } from 'react-native';
...
var ScrollResponderMixin = {
mixins: [Subscribable.Mixin],
componentWillMount: function() {
...
this.addListenerOn(DeviceEventEmitter,
'keyboardWillShow',
this.scrollResponderKeyboardWillShow);
...
},
scrollResponderKeyboardWillShow:function(e: Event) {
this.keyboardWillOpenTo = e;
this.props.onKeyboardWillShow && this.props.onKeyboardWillShow(e);
},
```
You can also directly use the `DeviceEventEmitter` module to listen for events.
```js
...
componentWillMount: function() {
DeviceEventEmitter.addListener('keyboardWillShow', function(e: Event) {
// handle event.
});
}
...
```
### Getting activity result from `startActivityForResult`
You'll need to listen to `onActivityResult` if you want to get results from an activity you started with `startActivityForResult`. To do this, you must extend `BaseActivityEventListener` or implement `ActivityEventListener`. The former is preferred as it is more resilient to API changes. Then, you need to register the listener in the module's constructor,
```java
reactContext.addActivityEventListener(mActivityResultListener);
```
Now you can listen to `onActivityResult` by implementing the following method:
```java
@Override
public void onActivityResult(
final Activity activity,
final int requestCode,
final int resultCode,
final Intent intent) {
// Your logic here
}
```
We will implement a simple image picker to demonstrate this. The image picker will expose the method `pickImage` to JavaScript, which will return the path of the image when called.
```java
public class ImagePickerModule extends ReactContextBaseJavaModule {
private static final int IMAGE_PICKER_REQUEST = 467081;
private static final String E_ACTIVITY_DOES_NOT_EXIST = "E_ACTIVITY_DOES_NOT_EXIST";
private static final String E_PICKER_CANCELLED = "E_PICKER_CANCELLED";
private static final String E_FAILED_TO_SHOW_PICKER = "E_FAILED_TO_SHOW_PICKER";
private static final String E_NO_IMAGE_DATA_FOUND = "E_NO_IMAGE_DATA_FOUND";
private Promise mPickerPromise;
private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {
@Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent intent) {
if (requestCode == IMAGE_PICKER_REQUEST) {
if (mPickerPromise != null) {
if (resultCode == Activity.RESULT_CANCELED) {
mPickerPromise.reject(E_PICKER_CANCELLED, "Image picker was cancelled");
} else if (resultCode == Activity.RESULT_OK) {
Uri uri = intent.getData();
if (uri == null) {
mPickerPromise.reject(E_NO_IMAGE_DATA_FOUND, "No image data found");
} else {
mPickerPromise.resolve(uri.toString());
}
}
mPickerPromise = null;
}
}
}
};
public ImagePickerModule(ReactApplicationContext reactContext) {
super(reactContext);
// Add the listener for `onActivityResult`
reactContext.addActivityEventListener(mActivityEventListener);
}
@Override
public String getName() {
return "ImagePickerModule";
}
@ReactMethod
public void pickImage(final Promise promise) {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
promise.reject(E_ACTIVITY_DOES_NOT_EXIST, "Activity doesn't exist");
return;
}
// Store the promise to resolve/reject when picker returns data
mPickerPromise = promise;
try {
final Intent galleryIntent = new Intent(Intent.ACTION_PICK);
galleryIntent.setType("image/*");
final Intent chooserIntent = Intent.createChooser(galleryIntent, "Pick an image");
currentActivity.startActivityForResult(chooserIntent, IMAGE_PICKER_REQUEST);
} catch (Exception e) {
mPickerPromise.reject(E_FAILED_TO_SHOW_PICKER, e);
mPickerPromise = null;
}
}
}
```
### Listening to LifeCycle events
Listening to the activity's LifeCycle events such as `onResume`, `onPause` etc. is very similar to how we implemented `ActivityEventListener`. The module must implement `LifecycleEventListener`. Then, you need to register a listener in the module's constructor,
```java
reactContext.addLifecycleEventListener(this);
```
Now you can listen to the activity's LifeCycle events by implementing the following methods:
```java
@Override
public void onHostResume() {
// Activity `onResume`
}
@Override
public void onHostPause() {
// Activity `onPause`
}
@Override
public void onHostDestroy() {
// Activity `onDestroy`
}
```

View File

@ -1,473 +0,0 @@
---
id: native-modules-ios
title: Native Modules
layout: docs
category: Guides (iOS)
permalink: docs/native-modules-ios.html
banner: ejected
next: native-components-ios
previous: testing
---
Sometimes an app needs access to platform API, and React Native doesn't have a corresponding module yet. Maybe you want to reuse some existing Objective-C, Swift or C++ code without having to reimplement it in JavaScript, or write some high performance, multi-threaded code such as for image processing, a database, or any number of advanced extensions.
We designed React Native such that it is possible for you to write real native code and have access to the full power of the platform. This is a more advanced feature and we don't expect it to be part of the usual development process, however it is essential that it exists. If React Native doesn't support a native feature that you need, you should be able to build it yourself.
This is a more advanced guide that shows how to build a native module. It assumes the reader knows Objective-C or Swift and core libraries (Foundation, UIKit).
## iOS Calendar Module Example
This guide will use the [iOS Calendar API](https://developer.apple.com/library/mac/documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html) example. Let's say we would like to be able to access the iOS calendar from JavaScript.
A native module is just an Objective-C class that implements the `RCTBridgeModule` protocol. If you are wondering, RCT is an abbreviation of ReaCT.
```objectivec
// CalendarManager.h
#import <React/RCTBridgeModule.h>
@interface CalendarManager : NSObject <RCTBridgeModule>
@end
```
In addition to implementing the `RCTBridgeModule` protocol, your class must also include the `RCT_EXPORT_MODULE()` macro. This takes an optional argument that specifies the name that the module will be accessible as in your JavaScript code (more on this later). If you do not specify a name, the JavaScript module name will match the Objective-C class name. If the Objective-C class name begins with RCT, the JavaScript module name will exclude the RCT prefix.
```objectivec
// CalendarManager.m
@implementation CalendarManager
// To export a module named CalendarManager
RCT_EXPORT_MODULE();
// This would name the module AwesomeCalendarManager instead
// RCT_EXPORT_MODULE(AwesomeCalendarManager);
@end
```
React Native will not expose any methods of `CalendarManager` to JavaScript unless explicitly told to. This is done using the `RCT_EXPORT_METHOD()` macro:
```objectivec
#import "CalendarManager.h"
#import <React/RCTLog.h>
@implementation CalendarManager
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location)
{
RCTLogInfo(@"Pretending to create an event %@ at %@", name, location);
}
```
Now, from your JavaScript file you can call the method like this:
```javascript
import { NativeModules } from 'react-native';
var CalendarManager = NativeModules.CalendarManager;
CalendarManager.addEvent('Birthday Party', '4 Privet Drive, Surrey');
```
> **NOTE**: JavaScript method names
>
> The name of the method exported to JavaScript is the native method's name up to the first colon. React Native also defines a macro called `RCT_REMAP_METHOD()` to specify the JavaScript method's name. This is useful when multiple native methods are the same up to the first colon and would have conflicting JavaScript names.
The CalendarManager module is instantiated on the Objective-C side using a [CalendarManager new] call. The return type of bridge methods is always `void`. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).
## Argument Types
`RCT_EXPORT_METHOD` supports all standard JSON object types, such as:
- string (`NSString`)
- number (`NSInteger`, `float`, `double`, `CGFloat`, `NSNumber`)
- boolean (`BOOL`, `NSNumber`)
- array (`NSArray`) of any types from this list
- object (`NSDictionary`) with string keys and values of any type from this list
- function (`RCTResponseSenderBlock`)
But it also works with any type that is supported by the `RCTConvert` class (see [`RCTConvert`](https://github.com/facebook/react-native/blob/master/React/Base/RCTConvert.h) for details). The `RCTConvert` helper functions all accept a JSON value as input and map it to a native Objective-C type or class.
In our `CalendarManager` example, we need to pass the event date to the native method. We can't send JavaScript Date objects over the bridge, so we need to convert the date to a string or number. We could write our native function like this:
```objectivec
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(nonnull NSNumber *)secondsSinceUnixEpoch)
{
NSDate *date = [RCTConvert NSDate:secondsSinceUnixEpoch];
}
```
or like this:
```objectivec
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSString *)ISO8601DateString)
{
NSDate *date = [RCTConvert NSDate:ISO8601DateString];
}
```
But by using the automatic type conversion feature, we can skip the manual conversion step completely, and just write:
```objectivec
RCT_EXPORT_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(NSDate *)date)
{
// Date is ready to use!
}
```
You would then call this from JavaScript by using either:
```javascript
CalendarManager.addEvent('Birthday Party', '4 Privet Drive, Surrey', date.getTime()); // passing date as number of milliseconds since Unix epoch
```
or
```javascript
CalendarManager.addEvent('Birthday Party', '4 Privet Drive, Surrey', date.toISOString()); // passing date as ISO-8601 string
```
And both values would get converted correctly to the native `NSDate`. A bad value, like an `Array`, would generate a helpful "RedBox" error message.
As `CalendarManager.addEvent` method gets more and more complex, the number of arguments will grow. Some of them might be optional. In this case it's worth considering changing the API a little bit to accept a dictionary of event attributes, like this:
```objectivec
#import <React/RCTConvert.h>
RCT_EXPORT_METHOD(addEvent:(NSString *)name details:(NSDictionary *)details)
{
NSString *location = [RCTConvert NSString:details[@"location"]];
NSDate *time = [RCTConvert NSDate:details[@"time"]];
...
}
```
and call it from JavaScript:
```javascript
CalendarManager.addEvent('Birthday Party', {
location: '4 Privet Drive, Surrey',
time: date.getTime(),
description: '...'
})
```
> **NOTE**: About array and map
>
> Objective-C doesn't provide any guarantees about the types of values in these structures. Your native module might expect an array of strings, but if JavaScript calls your method with an array containing numbers and strings, you'll get an `NSArray` containing a mix of `NSNumber` and `NSString`. For arrays, `RCTConvert` provides some typed collections you can use in your method declaration, such as `NSStringArray`, or `UIColorArray`. For maps, it is the developer's responsibility to check the value types individually by manually calling `RCTConvert` helper methods.
## Callbacks
> **WARNING**
>
> This section is more experimental than others because we don't have a solid set of best practices around callbacks yet.
Native modules also supports a special kind of argument- a callback. In most cases it is used to provide the function call result to JavaScript.
```objectivec
RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback)
{
NSArray *events = ...
callback(@[[NSNull null], events]);
}
```
`RCTResponseSenderBlock` accepts only one argument - an array of parameters to pass to the JavaScript callback. In this case we use Node's convention to make the first parameter an error object (usually `null` when there is no error) and the rest are the results of the function.
```javascript
CalendarManager.findEvents((error, events) => {
if (error) {
console.error(error);
} else {
this.setState({events: events});
}
})
```
A native module should invoke its callback exactly once. It's okay to store the callback and invoke it later. This pattern is often used to wrap iOS APIs that require delegates - see [`RCTAlertManager`](https://github.com/facebook/react-native/blob/master/React/Modules/RCTAlertManager.m) for an example. If the callback is never invoked, some memory is leaked. If both `onSuccess` and `onFail` callbacks are passed, you should only invoke one of them.
If you want to pass error-like objects to JavaScript, use `RCTMakeError` from [`RCTUtils.h`](https://github.com/facebook/react-native/blob/master/React/Base/RCTUtils.h). Right now this just passes an Error-shaped dictionary to JavaScript, but we would like to automatically generate real JavaScript `Error` objects in the future.
## Promises
Native modules can also fulfill a promise, which can simplify your code, especially when using ES2016's `async/await` syntax. When the last parameters of a bridged native method are an `RCTPromiseResolveBlock` and `RCTPromiseRejectBlock`, its corresponding JS method will return a JS Promise object.
Refactoring the above code to use a promise instead of callbacks looks like this:
```objectivec
RCT_REMAP_METHOD(findEvents,
findEventsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSArray *events = ...
if (events) {
resolve(events);
} else {
NSError *error = ...
reject(@"no_events", @"There were no events", error);
}
}
```
The JavaScript counterpart of this method returns a Promise. This means you can use the `await` keyword within an async function to call it and wait for its result:
```js
async function updateEvents() {
try {
var events = await CalendarManager.findEvents();
this.setState({ events });
} catch (e) {
console.error(e);
}
}
updateEvents();
```
## Threading
The native module should not have any assumptions about what thread it is being called on. React Native invokes native modules methods on a separate serial GCD queue, but this is an implementation detail and might change. The `- (dispatch_queue_t)methodQueue` method allows the native module to specify which queue its methods should be run on. For example, if it needs to use a main-thread-only iOS API, it should specify this via:
```objectivec
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
```
Similarly, if an operation may take a long time to complete, the native module should not block and can specify it's own queue to run operations on. For example, the `RCTAsyncLocalStorage` module creates its own queue so the React queue isn't blocked waiting on potentially slow disk access:
```objectivec
- (dispatch_queue_t)methodQueue
{
return dispatch_queue_create("com.facebook.React.AsyncLocalStorageQueue", DISPATCH_QUEUE_SERIAL);
}
```
The specified `methodQueue` will be shared by all of the methods in your module. If *just one* of your methods is long-running (or needs to be run on a different queue than the others for some reason), you can use `dispatch_async` inside the method to perform that particular method's code on another queue, without affecting the others:
```objectivec
RCT_EXPORT_METHOD(doSomethingExpensive:(NSString *)param callback:(RCTResponseSenderBlock)callback)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Call long-running code on background thread
...
// You can invoke callback from any thread/queue
callback(@[...]);
});
}
```
> **NOTE**: Sharing dispatch queues between modules
>
> The `methodQueue` method will be called once when the module is initialized, and then retained by the bridge, so there is no need to retain the queue yourself, unless you wish to make use of it within your module. However, if you wish to share the same queue between multiple modules then you will need to ensure that you retain and return the same queue instance for each of them; merely returning a queue of the same name for each won't work.
## Dependency Injection
The bridge initializes any registered RCTBridgeModules automatically, however you may wish to instantiate your own module instances (so you may inject dependencies, for example).
You can do this by creating a class that implements the RCTBridgeDelegate Protocol, initializing an RCTBridge with the delegate as an argument and initialising a RCTRootView with the initialized bridge.
```objectivec
id<RCTBridgeDelegate> moduleInitialiser = [[classThatImplementsRCTBridgeDelegate alloc] init];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:moduleInitialiser launchOptions:nil];
RCTRootView *rootView = [[RCTRootView alloc]
initWithBridge:bridge
moduleName:kModuleName
initialProperties:nil];
```
## Exporting Constants
A native module can export constants that are immediately available to JavaScript at runtime. This is useful for communicating static data that would otherwise require a round-trip through the bridge.
```objectivec
- (NSDictionary *)constantsToExport
{
return @{ @"firstDayOfTheWeek": @"Monday" };
}
```
JavaScript can use this value right away, synchronously:
```javascript
console.log(CalendarManager.firstDayOfTheWeek);
```
Note that the constants are exported only at initialization time, so if you change `constantsToExport` values at runtime it won't affect the JavaScript environment.
### Enum Constants
Enums that are defined via `NS_ENUM` cannot be used as method arguments without first extending RCTConvert.
In order to export the following `NS_ENUM` definition:
```objectivec
typedef NS_ENUM(NSInteger, UIStatusBarAnimation) {
UIStatusBarAnimationNone,
UIStatusBarAnimationFade,
UIStatusBarAnimationSlide,
};
```
You must create a class extension of RCTConvert like so:
```objectivec
@implementation RCTConvert (StatusBarAnimation)
RCT_ENUM_CONVERTER(UIStatusBarAnimation, (@{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone),
@"statusBarAnimationFade" : @(UIStatusBarAnimationFade),
@"statusBarAnimationSlide" : @(UIStatusBarAnimationSlide)}),
UIStatusBarAnimationNone, integerValue)
@end
```
You can then define methods and export your enum constants like this:
```objectivec
- (NSDictionary *)constantsToExport
{
return @{ @"statusBarAnimationNone" : @(UIStatusBarAnimationNone),
@"statusBarAnimationFade" : @(UIStatusBarAnimationFade),
@"statusBarAnimationSlide" : @(UIStatusBarAnimationSlide) };
};
RCT_EXPORT_METHOD(updateStatusBarAnimation:(UIStatusBarAnimation)animation
completion:(RCTResponseSenderBlock)callback)
```
Your enum will then be automatically unwrapped using the selector provided (`integerValue` in the above example) before being passed to your exported method.
## Sending Events to JavaScript
The native module can signal events to JavaScript without being invoked directly. The preferred way to do this is to subclass `RCTEventEmitter`, implement `supportedEvents` and call `self sendEventWithName`:
```objectivec
// CalendarManager.h
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
@interface CalendarManager : RCTEventEmitter <RCTBridgeModule>
@end
```
```objectivec
// CalendarManager.m
#import "CalendarManager.h"
@implementation CalendarManager
RCT_EXPORT_MODULE();
- (NSArray<NSString *> *)supportedEvents
{
return @[@"EventReminder"];
}
- (void)calendarEventReminderReceived:(NSNotification *)notification
{
NSString *eventName = notification.userInfo[@"name"];
[self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
}
@end
```
JavaScript code can subscribe to these events by creating a new `NativeEventEmitter` instance around your module.
```javascript
import { NativeEventEmitter, NativeModules } from 'react-native';
const { CalendarManager } = NativeModules;
const calendarManagerEmitter = new NativeEventEmitter(CalendarManager);
const subscription = calendarManagerEmitter.addListener(
'EventReminder',
(reminder) => console.log(reminder.name)
);
...
// Don't forget to unsubscribe, typically in componentWillUnmount
subscription.remove();
```
For more examples of sending events to JavaScript, see [`RCTLocationObserver`](https://github.com/facebook/react-native/blob/master/Libraries/Geolocation/RCTLocationObserver.m).
### Optimizing for zero listeners
You will receive a warning if you expend resources unnecessarily by emitting an event while there are no listeners. To avoid this, and to optimize your module's workload (e.g. by unsubscribing from upstream notifications or pausing background tasks), you can override `startObserving` and `stopObserving` in your `RCTEventEmitter` subclass.
```objectivec
@implementation CalendarManager
{
bool hasListeners;
}
// Will be called when this module's first listener is added.
-(void)startObserving {
hasListeners = YES;
// Set up any upstream listeners or background tasks as necessary
}
// Will be called when this module's last listener is removed, or on dealloc.
-(void)stopObserving {
hasListeners = NO;
// Remove upstream listeners, stop unnecessary background tasks
}
- (void)calendarEventReminderReceived:(NSNotification *)notification
{
NSString *eventName = notification.userInfo[@"name"];
if (hasListeners) { // Only send events if anyone is listening
[self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
}
}
```
## Exporting Swift
Swift doesn't have support for macros so exposing it to React Native requires a bit more setup but works relatively the same.
Let's say we have the same `CalendarManager` but as a Swift class:
```swift
// CalendarManager.swift
@objc(CalendarManager)
class CalendarManager: NSObject {
@objc(addEvent:location:date:)
func addEvent(name: String, location: String, date: NSNumber) -> Void {
// Date is ready to use!
}
func constantsToExport() -> [String: Any]! {
return ["someKey": "someValue"]
}
}
```
> **NOTE**: It is important to use the @objc modifiers to ensure the class and functions are exported properly to the Objective-C runtime.
Then create a private implementation file that will register the required information with the React Native bridge:
```objectivec
// CalendarManagerBridge.m
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(CalendarManager, NSObject)
RCT_EXTERN_METHOD(addEvent:(NSString *)name location:(NSString *)location date:(nonnull NSNumber *)date)
@end
```
For those of you new to Swift and Objective-C, whenever you [mix the two languages in an iOS project](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html), you will also need an additional bridging file, known as a bridging header, to expose the Objective-C files to Swift. Xcode will offer to create this header file for you if you add your Swift file to your app through the Xcode `File>New File` menu option. You will need to import `RCTBridgeModule.h` in this header file.
```objectivec
// CalendarManager-Bridging-Header.h
#import <React/RCTBridgeModule.h>
```
You can also use `RCT_EXTERN_REMAP_MODULE` and `_RCT_EXTERN_REMAP_METHOD` to alter the JavaScript name of the module or methods you are exporting. For more information see [`RCTBridgeModule`](https://github.com/facebook/react-native/blob/master/React/Base/RCTBridgeModule.h).
> **Important when making third party modules**: Static libraries with Swift are only supported in Xcode 9 and later. In order for the Xcode project to build when you use Swift in the iOS static library you include in the module, your main app project must contain Swift code and a bridging header itself. If your app project does not contain any Swift code, a workaround can be a single empty .swift file and an empty bridging header.

View File

@ -1,8 +0,0 @@
---
id: NativeMethodsMixin
title: NativeMethodsMixin
layout: redirect
permalink: docs/nativemethodsmixin.html
destinationUrl: direct-manipulation.html#other-native-methods
---
Redirecting...

View File

@ -1,574 +0,0 @@
---
id: navigatorios
title: NavigatorIOS
layout: docs
category: components
permalink: docs/navigatorios.html
next: picker
previous: modal
---
`NavigatorIOS` is a wrapper around [`UINavigationController`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UINavigationController_Class/), enabling you to implement a navigation stack. It works exactly the same as it would on a native app using `UINavigationController`, providing the same animations and behavior from UIKit.
As the name implies, it is only available on iOS. Take a look at [`React Navigation`](https://reactnavigation.org/) for a cross-platform solution in JavaScript, or check out either of these components for native solutions: [native-navigation](http://airbnb.io/native-navigation/), [react-native-navigation](https://github.com/wix/react-native-navigation).
To set up the navigator, provide the `initialRoute` prop with a route object. A route object is used to describe each scene that your app navigates to. `initialRoute` represents the first route in your navigator.
```
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { NavigatorIOS, Text } from 'react-native';
export default class NavigatorIOSApp extends Component {
render() {
return (
<NavigatorIOS
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
}}
style={{flex: 1}}
/>
);
}
}
class MyScene extends Component {
static propTypes = {
title: PropTypes.string.isRequired,
navigator: PropTypes.object.isRequired,
}
_onForward = () => {
this.props.navigator.push({
title: 'Scene ' + nextIndex,
});
}
render() {
return (
<View>
<Text>Current Scene: { this.props.title }</Text>
<TouchableHighlight onPress={this._onForward}>
<Text>Tap me to load the next scene</Text>
</TouchableHighlight>
</View>
)
}
}
```
In this code, the navigator renders the component specified in initialRoute, which in this case is `MyScene`. This component will receive a `route` prop and a `navigator` prop representing the navigator. The navigator's navigation bar will render the title for the current scene, "My Initial Scene".
You can optionally pass in a `passProps` property to your `initialRoute`. `NavigatorIOS` passes this in as props to the rendered component:
```
initialRoute={{
component: MyScene,
title: 'My Initial Scene',
passProps: { myProp: 'foo' }
}}
```
You can then access the props passed in via `{this.props.myProp}`.
#### Handling Navigation
To trigger navigation functionality such as pushing or popping a view, you have access to a `navigator` object. The object is passed in as a prop to any component that is rendered by `NavigatorIOS`. You can then call the relevant methods to perform the navigation action you need:
```
class MyView extends Component {
_handleBackPress() {
this.props.navigator.pop();
}
_handleNextPress(nextRoute) {
this.props.navigator.push(nextRoute);
}
render() {
const nextRoute = {
component: MyView,
title: 'Bar That',
passProps: { myProp: 'bar' }
};
return(
<TouchableHighlight onPress={() => this._handleNextPress(nextRoute)}>
<Text style={{marginTop: 200, alignSelf: 'center'}}>
See you on the other nav {this.props.myProp}!
</Text>
</TouchableHighlight>
);
}
}
```
You can also trigger navigator functionality from the `NavigatorIOS` component:
```
class NavvyIOS extends Component {
_handleNavigationRequest() {
this.refs.nav.push({
component: MyView,
title: 'Genius',
passProps: { myProp: 'genius' },
});
}
render() {
return (
<NavigatorIOS
ref='nav'
initialRoute={{
component: MyView,
title: 'Foo This',
passProps: { myProp: 'foo' },
rightButtonTitle: 'Add',
onRightButtonPress: () => this._handleNavigationRequest(),
}}
style={{flex: 1}}
/>
);
}
}
```
The code above adds a `_handleNavigationRequest` private method that is invoked from the `NavigatorIOS` component when the right navigation bar item is pressed. To get access to the navigator functionality, a reference to it is saved in the `ref` prop and later referenced to push a new scene into the navigation stack.
#### Navigation Bar Configuration
Props passed to `NavigatorIOS` will set the default configuration for the navigation bar. Props passed as properties to a route object will set the configuration for that route's navigation bar, overriding any props passed to the `NavigatorIOS` component.
```
_handleNavigationRequest() {
this.refs.nav.push({
//...
passProps: { myProp: 'genius' },
barTintColor: '#996699',
});
}
render() {
return (
<NavigatorIOS
//...
style={{flex: 1}}
barTintColor='#ffffcc'
/>
);
}
```
In the example above the navigation bar color is changed when the new route is pushed.
### Props
- [`initialRoute`](docs/navigatorios.html#initialroute)
- [`barStyle`](docs/navigatorios.html#barstyle)
- [`barTintColor`](docs/navigatorios.html#bartintcolor)
- [`interactivePopGestureEnabled`](docs/navigatorios.html#interactivepopgestureenabled)
- [`itemWrapperStyle`](docs/navigatorios.html#itemwrapperstyle)
- [`navigationBarHidden`](docs/navigatorios.html#navigationbarhidden)
- [`shadowHidden`](docs/navigatorios.html#shadowhidden)
- [`tintColor`](docs/navigatorios.html#tintcolor)
- [`titleTextColor`](docs/navigatorios.html#titletextcolor)
- [`translucent`](docs/navigatorios.html#translucent)
### Methods
- [`push`](docs/navigatorios.html#push)
- [`popN`](docs/navigatorios.html#popn)
- [`pop`](docs/navigatorios.html#pop)
- [`replaceAtIndex`](docs/navigatorios.html#replaceatindex)
- [`replace`](docs/navigatorios.html#replace)
- [`replacePrevious`](docs/navigatorios.html#replaceprevious)
- [`popToTop`](docs/navigatorios.html#poptotop)
- [`popToRoute`](docs/navigatorios.html#poptoroute)
- [`replacePreviousAndPop`](docs/navigatorios.html#replacepreviousandpop)
- [`resetTo`](docs/navigatorios.html#resetto)
---
# Reference
## Props
### `initialRoute`
NavigatorIOS uses `route` objects to identify child views, their props,
and navigation bar configuration. Navigation operations such as push
operations expect routes to look like this.
| Type | Required |
| - | - |
| object | Yes |
**Routes:**
The following parameters can be used to define a route:
* `**component**`: function
The React Class to render for this route.
* `**title**`: string
The title displayed in the navigation bar and the back button for this route.
* `**titleImage**`: [Image](docs/image.html)
If set, a title image will appear instead of the text title.
* `**passProps**`: object
Use this to specify additional props to pass to the rendered component. `NavigatorIOS` will automatically pass in `route` and `navigator` props to the comoponent.
* `**backButtonIcon**`: [Image](docs/image.html)
If set, the left navigation button image will be displayed using this source. Note that this doesn't apply to the header of the current view, but to those views that are subsequently pushed.
* `**backButtonTitle**`: string
If set, the left navigation button text will be set to this. Note that this doesn't apply to the left button of the current view, but to those views that are subsequently pushed.
* `**leftButtonIcon**`: [Image](docs/image.html)
If set, the left navigation button image will be displayed using this source.
* `**leftButtonTitle**`: string
If set, the left navigation button will display this text.
* `**leftButtonSystemIcon**`: [SystemIcon](docs/navigatorios.html#system-icons)
If set, the left header button will appear with this system icon. See below for supported icons.
* `**onLeftButtonPress**`: function
This function will be invoked when the left navigation bar item is pressed.
* `**rightButtonIcon**`: [Image](docs/image.html)
If set, the right navigation button image will be displayed using this source.
* `**rightButtonTitle**`: string
If set, the right navigation button will display this text.
* `**rightButtonSystemIcon**`: [SystemIcon](docs/navigatorios.html#system-icons)
If set, the right header button will appear with this system icon. See below for supported icons.
* `**onRightButtonPress**`: function
This function will be invoked when the right navigation bar item is pressed.
* `**wrapperStyle**`: [ViewPropTypes.style](docs/viewproptypes.html#style)
Styles for the navigation item containing the component.
* `**navigationBarHidden**`: boolean
Boolean value that indicates whether the navigation bar is hidden.
* `**shadowHidden**`: boolean
Boolean value that indicates whether to hide the 1px hairline shadow.
* `**tintColor**`: string
The color used for the buttons in the navigation bar.
* `**barTintColor**`: string
The background color of the navigation bar.
* `**barStyle**`: enum('default', 'black')
The style of the navigation bar. Supported values are 'default', 'black'. Use 'black' instead of setting `barTintColor` to black. This produces a navigation bar with the native iOS style with higher translucency.
* `**titleTextColor**`: string
The text color of the navigation bar title.
* `**translucent**`: boolean
Boolean value that indicates whether the navigation bar is translucent.
#### System Icons
Used in `leftButtonSystemIcon` and `rightButtonSystemIcon`. Supported icons are `done`, `cancel`, `edit`, `save`, `add`, `compose`, `reply`, `action`, `organize`, `bookmarks`, `search`, `refresh`, `stop`, `camera`, `trash`, `play`, `pause`, `rewind`, `fast-forward`, `undo`, `redo`, and `page-curl`.
---
### `barStyle`
The style of the navigation bar. Supported values are 'default', 'black'.
Use 'black' instead of setting `barTintColor` to black. This produces
a navigation bar with the native iOS style with higher translucency.
| Type | Required |
| - | - |
| enum('default', 'black') | No |
---
### `barTintColor`
The default background color of the navigation bar.
| Type | Required |
| - | - |
| string | No |
---
### `interactivePopGestureEnabled`
Boolean value that indicates whether the interactive pop gesture is
enabled. This is useful for enabling/disabling the back swipe navigation
gesture.
If this prop is not provided, the default behavior is for the back swipe
gesture to be enabled when the navigation bar is shown and disabled when
the navigation bar is hidden. Once you've provided the
`interactivePopGestureEnabled` prop, you can never restore the default
behavior.
| Type | Required |
| - | - |
| bool | No |
---
### `itemWrapperStyle`
The default wrapper style for components in the navigator.
A common use case is to set the `backgroundColor` for every scene.
| Type | Required |
| - | - |
| [ViewPropTypes.style](docs/viewproptypes.html#style) | No |
---
### `navigationBarHidden`
Boolean value that indicates whether the navigation bar is hidden
by default.
| Type | Required |
| - | - |
| bool | No |
---
### `shadowHidden`
Boolean value that indicates whether to hide the 1px hairline shadow
by default.
| Type | Required |
| - | - |
| bool | No |
---
### `tintColor`
The default color used for the buttons in the navigation bar.
| Type | Required |
| - | - |
| string | No |
---
### `titleTextColor`
The default text color of the navigation bar title.
| Type | Required |
| - | - |
| string | No |
---
### `translucent`
Boolean value that indicates whether the navigation bar is
translucent by default
| Type | Required |
| - | - |
| bool | No |
## Methods
### `push()`
```javascript
push(route: object)
```
Navigate forward to a new route.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| route | object | Yes | The new route to navigate to. |
---
### `popN()`
```javascript
popN(n: number)
```
Go back N scenes at once. When N=1, behavior matches `pop()`.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| n | number | Yes | The number of scenes to pop. |
---
### `pop()`
```javascript
pop()
```
Pop back to the previous scene.
---
### `replaceAtIndex()`
```javascript
replaceAtIndex(route: object, index: number)
```
Replace a route in the navigation stack.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| route | object | Yes | The new route that will replace the specified one. |
| index | number | Yes | The route into the stack that should be replaced. If it is negative, it counts from the back of the stack. |
---
### `replace()`
```javascript
replace(route: object)
```
Replace the route for the current scene and immediately
load the view for the new route.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| route | object | Yes | The new route to navigate to. |
---
### `replacePrevious()`
```javascript
replacePrevious(route: object)
```
Replace the route/view for the previous scene.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| route | object | Yes | The new route to will replace the previous scene. |
---
### `popToTop()`
```javascript
popToTop()
```
Go back to the topmost item in the navigation stack.
---
### `popToRoute()`
```javascript
popToRoute(route: object)
```
Go back to the item for a particular route object.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| route | object | Yes | The new route to navigate to. |
---
### `replacePreviousAndPop()`
```javascript
replacePreviousAndPop(route: object)
```
Replaces the previous route/view and transitions back to it.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| route | object | Yes | The new route that replaces the previous scene. |
---
### `resetTo()`
```javascript
resetTo(route: object)
```
Replaces the top item and pop to it.
**Parameters:**
| Name | Type | Required | Description |
| - | - | - | - |
| route | object | Yes | The new route that will replace the topmost item. |

View File

@ -1,220 +0,0 @@
---
id: netinfo
title: NetInfo
layout: docs
category: APIs
permalink: docs/netinfo.html
next: panresponder
previous: linking
---
NetInfo exposes info about online/offline status.
```
NetInfo.getConnectionInfo().then((connectionInfo) => {
console.log('Initial, type: ' + connectionInfo.type + ', effectiveType: ' + connectionInfo.effectiveType);
});
function handleFirstConnectivityChange(connectionInfo) {
console.log('First change, type: ' + connectionInfo.type + ', effectiveType: ' + connectionInfo.effectiveType);
NetInfo.removeEventListener(
'connectionChange',
handleFirstConnectivityChange
);
}
NetInfo.addEventListener(
'connectionChange',
handleFirstConnectivityChange
);
```
### ConnectionType enum
`ConnectionType` describes the type of connection the device is using to communicate with the network.
Cross platform values for `ConnectionType`:
- `none` - device is offline
- `wifi` - device is online and connected via wifi, or is the iOS simulator
- `cellular` - device is connected via Edge, 3G, WiMax, or LTE
- `unknown` - error case and the network status is unknown
Android-only values for `ConnectionType`:
- `bluetooth` - device is connected via Bluetooth
- `ethernet` - device is connected via Ethernet
- `wimax` - device is connected via WiMAX
### EffectiveConnectionType enum
Cross platform values for `EffectiveConnectionType`:
- `2g`
- `3g`
- `4g`
- `unknown`
### Android
To request network info, you need to add the following line to your
app's `AndroidManifest.xml`:
`<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />`
### Connectivity Types (deprecated)
The following connectivity types are deprecated. They're used by the deprecated APIs `fetch` and the `change` event.
iOS connectivity types (deprecated):
- `none` - device is offline
- `wifi` - device is online and connected via wifi, or is the iOS simulator
- `cell` - device is connected via Edge, 3G, WiMax, or LTE
- `unknown` - error case and the network status is unknown
Android connectivity types (deprecated).
- `NONE` - device is offline
- `BLUETOOTH` - The Bluetooth data connection.
- `DUMMY` - Dummy data connection.
- `ETHERNET` - The Ethernet data connection.
- `MOBILE` - The Mobile data connection.
- `MOBILE_DUN` - A DUN-specific Mobile data connection.
- `MOBILE_HIPRI` - A High Priority Mobile data connection.
- `MOBILE_MMS` - An MMS-specific Mobile data connection.
- `MOBILE_SUPL` - A SUPL-specific Mobile data connection.
- `VPN` - A virtual network using one or more native bearers. Requires API Level 21
- `WIFI` - The WIFI data connection.
- `WIMAX` - The WiMAX data connection.
- `UNKNOWN` - Unknown data connection.
The rest of the connectivity types are hidden by the Android API, but can be used if necessary.
### Methods
- [`addEventListener`](docs/netinfo.html#addeventlistener)
- [`removeEventListener`](docs/netinfo.html#removeeventlistener)
- [`fetch`](docs/netinfo.html#fetch)
- [`getConnectionInfo`](docs/netinfo.html#getconnectioninfo)
- [`isConnectionExpensive`](docs/netinfo.html#isconnectionexpensive)
### Properties
- [`isConnected`](docs/netinfo.html#isconnected)
---
# Reference
## Methods
### `addEventListener()`
```javascript
NetInfo.addEventListener(eventName, handler)
```
Adds an event handler. Supported events:
- `connectionChange`: Fires when the network status changes. The argument to the event
handler is an object with keys:
- `type`: A `ConnectionType` (listed above)
- `effectiveType`: An `EffectiveConnectionType` (listed above)
- `change`: This event is deprecated. Listen to `connectionChange` instead. Fires when
the network status changes. The argument to the event handler is one of the deprecated
connectivity types listed above.
---
### `removeEventListener()`
```javascript
NetInfo.removeEventListener(eventName, handler)
```
Removes the listener for network status changes.
---
### `fetch()`
```javascript
NetInfo.fetch()
```
This function is deprecated. Use `getConnectionInfo` instead. Returns a promise that
resolves with one of the deprecated connectivity types listed above.
---
### `getConnectionInfo()`
```javascript
NetInfo.getConnectionInfo()
```
Returns a promise that resolves to an object with `type` and `effectiveType` keys
whose values are a `ConnectionType` and an `EffectiveConnectionType`, (described above),
respectively.
---
### `isConnectionExpensive()`
```javascript
NetInfo.isConnectionExpensive()
```
Available on Android. Detect if the current active connection is metered or not. A network is
classified as metered when the user is sensitive to heavy data usage on that connection due to
monetary costs, data limitations or battery/performance issues.
```
NetInfo.isConnectionExpensive()
.then(isConnectionExpensive => {
console.log('Connection is ' + (isConnectionExpensive ? 'Expensive' : 'Not Expensive'));
})
.catch(error => {
console.error(error);
});
```
## Properties
### `isConnected`
Available on all platforms. Asynchronously fetch a boolean to determine internet connectivity.
```
NetInfo.isConnected.fetch().then(isConnected => {
console.log('First, is ' + (isConnected ? 'online' : 'offline'));
});
function handleFirstConnectivityChange(isConnected) {
console.log('Then, is ' + (isConnected ? 'online' : 'offline'));
NetInfo.isConnected.removeEventListener(
'connectionChange',
handleFirstConnectivityChange
);
}
NetInfo.isConnected.addEventListener(
'connectionChange',
handleFirstConnectivityChange
);
```

View File

@ -1,184 +0,0 @@
---
id: network
title: Networking
layout: docs
category: The Basics
permalink: docs/network.html
next: more-resources
previous: using-a-listview
---
Many mobile apps need to load resources from a remote URL. You may want to make a POST request to a REST API, or you may simply need to fetch a chunk of static content from another server.
## Using Fetch
React Native provides the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for your networking needs. Fetch will seem familiar if you have used `XMLHttpRequest` or other networking APIs before. You may refer to MDN's guide on [Using Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) for additional information.
#### Making requests
In order to fetch content from an arbitrary URL, just pass the URL to fetch:
```js
fetch('https://mywebsite.com/mydata.json')
```
Fetch also takes an optional second argument that allows you to customize the HTTP request. You may want to specify additional headers, or make a POST request:
```js
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
```
Take a look at the [Fetch Request docs](https://developer.mozilla.org/en-US/docs/Web/API/Request) for a full list of properties.
#### Handling the response
The above examples show how you can make a request. In many cases, you will want to do something with the response.
Networking is an inherently asynchronous operation. Fetch methods will return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that makes it straightforward to write code that works in an asynchronous manner:
```js
function getMoviesFromApiAsync() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
return responseJson.movies;
})
.catch((error) => {
console.error(error);
});
}
```
You can also use the proposed ES2017 `async`/`await` syntax in a React Native app:
```js
async function getMoviesFromApi() {
try {
let response = await fetch('https://facebook.github.io/react-native/movies.json');
let responseJson = await response.json();
return responseJson.movies;
} catch(error) {
console.error(error);
}
}
```
Don't forget to catch any errors that may be thrown by `fetch`, otherwise they will be dropped silently.
```SnackPlayer?name=Fetch%20Example
import React, { Component } from 'react';
import { ActivityIndicator, ListView, Text, View } from 'react-native';
export default class Movies extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true
}
}
componentDidMount() {
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.setState({
isLoading: false,
dataSource: ds.cloneWithRows(responseJson.movies),
}, function() {
// do something with new state
});
})
.catch((error) => {
console.error(error);
});
}
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, paddingTop: 20}}>
<ActivityIndicator />
</View>
);
}
return (
<View style={{flex: 1, paddingTop: 20}}>
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData.title}, {rowData.releaseYear}</Text>}
/>
</View>
);
}
}
```
> By default, iOS will block any request that's not encrypted using SSL. If you need to fetch from a cleartext URL (one that begins with `http`) you will first need to add an App Transport Security exception. If you know ahead of time what domains you will need access to, it is more secure to add exceptions just for those domains; if the domains are not known until runtime you can [disable ATS completely](docs/integration-with-existing-apps.html#app-transport-security). Note however that from January 2017, [Apple's App Store review will require reasonable justification for disabling ATS](https://forums.developer.apple.com/thread/48979). See [Apple's documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33) for more information.
### Using Other Networking Libraries
The [XMLHttpRequest API](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) is built in to React Native. This means that you can use third party libraries such as [frisbee](https://github.com/niftylettuce/frisbee) or [axios](https://github.com/mzabriskie/axios) that depend on it, or you can use the XMLHttpRequest API directly if you prefer.
```js
var request = new XMLHttpRequest();
request.onreadystatechange = (e) => {
if (request.readyState !== 4) {
return;
}
if (request.status === 200) {
console.log('success', request.responseText);
} else {
console.warn('error');
}
};
request.open('GET', 'https://mywebsite.com/endpoint/');
request.send();
```
> The security model for XMLHttpRequest is different than on web as there is no concept of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) in native apps.
## WebSocket Support
React Native also supports [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket), a protocol which provides full-duplex communication channels over a single TCP connection.
```js
var ws = new WebSocket('ws://host.com/path');
ws.onopen = () => {
// connection opened
ws.send('something'); // send a message
};
ws.onmessage = (e) => {
// a message was received
console.log(e.data);
};
ws.onerror = (e) => {
// an error occurred
console.log(e.message);
};
ws.onclose = (e) => {
// connection closed
console.log(e.code, e.reason);
};
```
## High Five!
If you've gotten here by reading linearly through the tutorial, then you are a pretty impressive human being. Congratulations. Next, you might want to check out [all the cool stuff the community does with React Native](docs/more-resources.html).

View File

@ -1,151 +0,0 @@
---
id: panresponder
title: PanResponder
layout: docs
category: APIs
permalink: docs/panresponder.html
next: permissionsandroid
previous: netinfo
---
`PanResponder` reconciles several touches into a single gesture. It makes
single-touch gestures resilient to extra touches, and can be used to
recognize simple multi-touch gestures.
By default, `PanResponder` holds an `InteractionManager` handle to block
long-running JS events from interrupting active gestures.
It provides a predictable wrapper of the responder handlers provided by the
[gesture responder system](docs/gesture-responder-system.html).
For each handler, it provides a new `gestureState` object alongside the
native event object:
```
onPanResponderMove: (event, gestureState) => {}
```
A native event is a synthetic touch event with the following form:
- `nativeEvent`
+ `changedTouches` - Array of all touch events that have changed since the last event
+ `identifier` - The ID of the touch
+ `locationX` - The X position of the touch, relative to the element
+ `locationY` - The Y position of the touch, relative to the element
+ `pageX` - The X position of the touch, relative to the root element
+ `pageY` - The Y position of the touch, relative to the root element
+ `target` - The node id of the element receiving the touch event
+ `timestamp` - A time identifier for the touch, useful for velocity calculation
+ `touches` - Array of all current touches on the screen
A `gestureState` object has the following:
- `stateID` - ID of the gestureState- persisted as long as there at least
one touch on screen
- `moveX` - the latest screen coordinates of the recently-moved touch
- `moveY` - the latest screen coordinates of the recently-moved touch
- `x0` - the screen coordinates of the responder grant
- `y0` - the screen coordinates of the responder grant
- `dx` - accumulated distance of the gesture since the touch started
- `dy` - accumulated distance of the gesture since the touch started
- `vx` - current velocity of the gesture
- `vy` - current velocity of the gesture
- `numberActiveTouches` - Number of touches currently on screen
### Basic Usage
```
componentWillMount: function() {
this._panResponder = PanResponder.create({
// Ask to be the responder:
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
// The gesture has started. Show visual feedback so the user knows
// what is happening!
// gestureState.d{x,y} will be set to zero now
},
onPanResponderMove: (evt, gestureState) => {
// The most recent move distance is gestureState.move{X,Y}
// The accumulated gesture distance since becoming responder is
// gestureState.d{x,y}
},
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => {
// The user has released all touches while this view is the
// responder. This typically means a gesture has succeeded
},
onPanResponderTerminate: (evt, gestureState) => {
// Another component has become the responder, so this gesture
// should be cancelled
},
onShouldBlockNativeResponder: (evt, gestureState) => {
// Returns whether this component should block native components from becoming the JS
// responder. Returns true by default. Is currently only supported on android.
return true;
},
});
},
render: function() {
return (
<View {...this._panResponder.panHandlers} />
);
},
```
### Working Example
To see it in action, try the
[PanResponder example in RNTester](https://github.com/facebook/react-native/blob/master/RNTester/js/PanResponderExample.js)
### Methods
- [`create`](docs/panresponder.html#create)
---
# Reference
## Methods
### `create()`
```javascript
PanResponder.create(config)
```
Enhanced versions of all of the responder callbacks
that provide not only the typical `ResponderSyntheticEvent`, but also the `PanResponder` gesture state. Simply replace the word `Responder` with
`PanResponder` in each of the typical `onResponder*` callbacks.
For example, the `config` object would look like:
- `onMoveShouldSetPanResponder: (e, gestureState) => {...}`
- `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}`
- `onStartShouldSetPanResponder: (e, gestureState) => {...}`
- `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}`
- `onPanResponderReject: (e, gestureState) => {...}`
- `onPanResponderGrant: (e, gestureState) => {...}`
- `onPanResponderStart: (e, gestureState) => {...}`
- `onPanResponderEnd: (e, gestureState) => {...}`
- `onPanResponderRelease: (e, gestureState) => {...}`
- `onPanResponderMove: (e, gestureState) => {...}`
- `onPanResponderTerminate: (e, gestureState) => {...}`
- `onPanResponderTerminationRequest: (e, gestureState) => {...}`
- `onShouldBlockNativeResponder: (e, gestureState) => {...}`
In general, for events that have capture equivalents, we update the gestureState once in the capture phase and can use it in the bubble phase as well.
Be careful with onStartShould* callbacks. They only reflect updated `gestureState` for start/end events that bubble/capture to the Node. Once the node is the responder, you can rely on every start/end event being processed by the gesture and `gestureState` being updated accordingly. (numberActiveTouches) may not be totally accurate unless you are the responder.

View File

@ -1,151 +0,0 @@
---
id: permissionsandroid
title: PermissionsAndroid
layout: docs
category: APIs
permalink: docs/permissionsandroid.html
next: pixelratio
previous: panresponder
---
<div class="banner-crna-ejected">
<h3>Project with Native Code Required</h3>
<p>
This API only works in projects made with <code>react-native init</code>
or in those made with Create React Native App which have since ejected. For
more information about ejecting, please see
the <a href="https://github.com/react-community/create-react-native-app/blob/master/EJECTING.md" target="_blank">guide</a> on
the Create React Native App repository.
</p>
</div>
`PermissionsAndroid` provides access to Android M's new permissions model. Some permissions are granted by default when the application is installed so long as they appear in `AndroidManifest.xml`. However, "dangerous" permissions require a dialog prompt. You should use this module for those
permissions.
On devices before SDK version 23, the permissions are automatically granted if they appear in the manifest, so `check` and `request` should always be true.
If a user has previously turned off a permission that you prompt for, the OS will advise your app to show a rationale for needing the permission. The optional `rationale` argument will show a dialog prompt only if necessary - otherwise the normal permission prompt will appear.
### Example
```javascript
import { PermissionsAndroid } from 'react-native';
async function requestCameraPermission() {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
'title': 'Cool Photo App Camera Permission',
'message': 'Cool Photo App needs access to your camera ' +
'so you can take awesome pictures.'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use the camera")
} else {
console.log("Camera permission denied")
}
} catch (err) {
console.warn(err)
}
}
```
### Methods
- [`constructor`](docs/permissionsandroid.html#constructor)
- [`check`](docs/permissionsandroid.html#check)
- [`request`](docs/permissionsandroid.html#request)
- [`requestMultiple`](docs/permissionsandroid.html#requestmultiple)
- [`requestPermission`](docs/permissionsandroid.html#requestpermission)
- [`checkPermission`](docs/permissionsandroid.html#checkpermission)
---
# Reference
## Methods
### `constructor()`
```javascript
constructor()
```
---
### `check()`
```javascript
check(permission)
```
Returns a promise resolving to a boolean value as to whether the specified permissions has been granted
---
### `request()`
```javascript
request(permission, rationale?)
```
Prompts the user to enable a permission and returns a promise resolving to a string value indicating whether the user allowed or denied the request.
If the optional rationale argument is included (which is an object with a `title` and `message`), this function checks with the OS whether it is necessary to show a dialog [explaining why the permission is needed](https://developer.android.com/training/permissions/requesting.html#explain) and then shows the system permission dialog
---
### `requestMultiple()`
```javascript
requestMultiple(permissions)
```
Prompts the user to enable multiple permissions in the same dialog and returns an object with the permissions as keys and strings as values indicating whether the user allowed or denied the request
---
### `checkPermission()`
```javascript
checkPermission(permission)
```
**DEPRECATED** - use [check](docs/permissionsandroid.html#check)
Returns a promise resolving to a boolean value as to whether the specified permissions has been granted
---
### `requestPermission()`
```javascript
requestPermission(permission, rationale?)
```
**DEPRECATED** - use [request](docs/permissionsandroid.html#request)
Prompts the user to enable a permission and returns a promise resolving to a boolean value indicating whether the user allowed or denied the request.
If the optional rationale argument is included (which is an object with a `title` and `message`), this function checks with the OS whether it is necessary to show a dialog [explaining why the permission is needed](https://developer.android.com/training/permissions/requesting.html#explain) and then shows the system permission dialog

View File

@ -1,57 +0,0 @@
---
id: picker-item
title: Picker.Item
layout: docs
category: components
permalink: docs/picker-item.html
next: pickerios
previous: picker
---
Individual selectable item in a [Picker](docs/picker.html).
### Props
- [`label`](docs/picker-item.html#label)
- [`color`](docs/picker-item.html#color)
- [`testID`](docs/picker-item.html#testid)
- [`value`](docs/picker-item.html#value)
---
# Reference
## Props
### `label`
Text to display for this item.
| Type | Required |
| - | - |
| string | Yes |
### `color`
The value to be passed to picker's `onValueChange` callback when this item is selected. Can be a string or an integer.
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
### `testID`
Used to locate the item in end-to-end tests.
| Type | Required |
| - | - |
| string | No |
### `value`
Color of this item's text.
| Type | Required | Platform |
| - | - | - |
| any | No | Android |

View File

@ -1,32 +0,0 @@
---
id: picker-style-props
title: Picker Style Props
layout: docs
category: APIs
permalink: docs/picker-style-props.html
next: shadow-props
previous: layout-props
---
[Picker](docs/picker.html) style props.
### Props
- [View Style Props...](docs/view-style-props.html)
- [`color`](docs/picker-style-props.html#color)
---
# Reference
## Props
### `color`
| Type | Required |
| - | - |
| [color](docs/color.html) | No |

View File

@ -1,149 +0,0 @@
---
id: picker
title: Picker
layout: docs
category: components
permalink: docs/picker.html
next: picker-item
previous: navigatorios
---
Renders the native picker component on iOS and Android. Example:
<Picker
selectedValue={this.state.language}
onValueChange={(itemValue, itemIndex) => this.setState({language: itemValue})}>
<Picker.Item label="Java" value="java" />
<Picker.Item label="JavaScript" value="js" />
</Picker>
### Props
- [View props...](docs/view.html#props)
- [`onValueChange`](docs/picker.html#onvaluechange)
- [`selectedValue`](docs/picker.html#selectedvalue)
- [`enabled`](docs/picker.html#enabled)
- [`mode`](docs/picker.html#mode)
- [`prompt`](docs/picker.html#prompt)
- [`style`](docs/picker.html#style)
- [`itemStyle`](docs/picker.html#itemstyle)
- [`testID`](docs/picker.html#testid)
---
# Reference
## Props
### `onValueChange`
Callback for when an item is selected. This is called with the following parameters:
- `itemValue`: the `value` prop of the item that was selected
- `itemPosition`: the index of the selected item in this picker
| Type | Required |
| - | - |
| function | No |
---
### `selectedValue`
Value matching value of one of the items. Can be a string or an integer.
| Type | Required |
| - | - |
| any | No |
---
### `enabled`
If set to false, the picker will be disabled, i.e. the user will not be able to make a
selection.
| Type | Required | Platform |
| - | - | - |
| bool | No | Android |
---
### `mode`
On Android, specifies how to display the selection items when the user taps on the picker:
- 'dialog': Show a modal dialog. This is the default.
- 'dropdown': Shows a dropdown anchored to the picker view
| Type | Required | Platform |
| - | - | - |
| enum('dialog', 'dropdown') | No | Android |
---
### `prompt`
Prompt string for this picker, used on Android in dialog mode as the title of the dialog.
| Type | Required | Platform |
| - | - | - |
| string | No | Android |
---
### `style`
| Type | Required |
| - | - |
| [style](docs/picker-style-props.html) | No |
---
### `itemStyle`
Style to apply to each of the item labels.
| Type | Required | Platform |
| - | - | - |
| [style](docs/textstyleproptypes.html) | No | iOS |
---
### `testID`
Used to locate this view in end-to-end tests.
| Type | Required |
| - | - |
| string | No |

View File

@ -1,67 +0,0 @@
---
id: pickerios
title: PickerIOS
layout: docs
category: components
permalink: docs/pickerios.html
next: progressbarandroid
previous: picker
---
### Props
- [View props...](docs/view.html#props)
- [`itemStyle`](docs/pickerios.html#itemstyle)
- [`onValueChange`](docs/pickerios.html#onvaluechange)
- [`selectedValue`](docs/pickerios.html#selectedvalue)
---
# Reference
## Props
### `itemStyle`
| Type | Required |
| - | - |
| [style](docs/text-style-props.html) | No |
---
### `onValueChange`
| Type | Required |
| - | - |
| function | No |
---
### `selectedValue`
A string or integer.
| Type | Required |
| - | - |
| any | No |

View File

@ -1,145 +0,0 @@
---
id: pixelratio
title: PixelRatio
layout: docs
category: APIs
permalink: docs/pixelratio.html
next: pushnotificationios
previous: permissionsandroid
---
PixelRatio class gives access to the device pixel density.
## Fetching a correctly sized image
You should get a higher resolution image if you are on a high pixel density
device. A good rule of thumb is to multiply the size of the image you display
by the pixel ratio.
```
var image = getImage({
width: PixelRatio.getPixelSizeForLayoutSize(200),
height: PixelRatio.getPixelSizeForLayoutSize(100),
});
<Image source={image} style={{width: 200, height: 100}} />
```
## Pixel grid snapping
In iOS, you can specify positions and dimensions for elements with arbitrary
precision, for example 29.674825. But, ultimately the physical display only
have a fixed number of pixels, for example 640×960 for iPhone 4 or 750×1334
for iPhone 6. iOS tries to be as faithful as possible to the user value by
spreading one original pixel into multiple ones to trick the eye. The
downside of this technique is that it makes the resulting element look
blurry.
In practice, we found out that developers do not want this feature and they
have to work around it by doing manual rounding in order to avoid having
blurry elements. In React Native, we are rounding all the pixels
automatically.
We have to be careful when to do this rounding. You never want to work with
rounded and unrounded values at the same time as you're going to accumulate
rounding errors. Having even one rounding error is deadly because a one
pixel border may vanish or be twice as big.
In React Native, everything in JavaScript and within the layout engine works
with arbitrary precision numbers. It's only when we set the position and
dimensions of the native element on the main thread that we round. Also,
rounding is done relative to the root rather than the parent, again to avoid
accumulating rounding errors.
### Methods
- [`get`](docs/pixelratio.html#get)
- [`getFontScale`](docs/pixelratio.html#getfontscale)
- [`getPixelSizeForLayoutSize`](docs/pixelratio.html#getpixelsizeforlayoutsize)
- [`roundToNearestPixel`](docs/pixelratio.html#roundtonearestpixel)
- [`startDetecting`](docs/pixelratio.html#startdetecting)
---
# Reference
## Methods
### `get()`
```javascript
PixelRatio.get()
```
Returns the device pixel density. Some examples:
- PixelRatio.get() === 1
- mdpi Android devices (160 dpi)
- PixelRatio.get() === 1.5
- hdpi Android devices (240 dpi)
- PixelRatio.get() === 2
- iPhone 4, 4S
- iPhone 5, 5c, 5s
- iPhone 6, 7, 8
- xhdpi Android devices (320 dpi)
- PixelRatio.get() === 3
- iPhone 6, 7, 8 Plus
- iPhone X
- xxhdpi Android devices (480 dpi)
- PixelRatio.get() === 3.5
- Nexus 6
---
### `getFontScale()`
```javascript
PixelRatio.getFontScale()
```
Returns the scaling factor for font sizes. This is the ratio that is used to calculate the absolute font size, so any elements that heavily depend on that should use this to do calculations.
If a font scale is not set, this returns the device pixel ratio.
Currently this is only implemented on Android and reflects the user preference set in Settings > Display > Font size, on iOS it will always return the default pixel ratio.
| Platform |
| - |
| Android |
---
### `getPixelSizeForLayoutSize()`
```javascript
PixelRatio.getPixelSizeForLayoutSize(layoutSize)
```
Converts a layout size (dp) to pixel size (px).
Guaranteed to return an integer number.
---
### `roundToNearestPixel()`
```javascript
PixelRatio.roundToNearestPixel(layoutSize)
```
Rounds a layout size (dp) to the nearest layout size that corresponds to an integer number of pixels. For example, on a device with a PixelRatio of 3, `PixelRatio.roundToNearestPixel(8.4) = 8.33`, which corresponds to exactly (8.33 * 3) = 25 pixels.

View File

@ -1,110 +0,0 @@
---
id: platform-specific-code
title: Platform Specific Code
layout: docs
category: Guides
permalink: docs/platform-specific-code.html
next: navigation
previous: components-and-apis
---
When building a cross-platform app, you'll want to re-use as much code as possible. Scenarios may arise where it makes sense for the code to be different, for example you may want to implement separate visual components for iOS and Android.
React Native provides two ways to easily organize your code and separate it by platform:
* Using the [`Platform` module](docs/platform-specific-code.html#platform-module).
* Using [platform-specific file extensions](docs/platform-specific-code.html#platform-specific-extensions).
Certain components may have properties that work on one platform only. All of these props are annotated with `@platform` and have a small badge next to them on the website.
## Platform module
React Native provides a module that detects the platform in which the app is running. You can use the detection logic to implement platform-specific code. Use this option when only small parts of a component are platform-specific.
```javascript
import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
height: (Platform.OS === 'ios') ? 200 : 100,
});
```
`Platform.OS` will be `ios` when running on iOS and `android` when running on Android.
There is also a `Platform.select` method available, that given an object containing Platform.OS as keys, returns the value for the platform you are currently running on.
```javascript
import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'blue',
},
}),
},
});
```
This will result in a container having `flex: 1` on both platforms, a red background color on iOS, and a blue background color on Android.
Since it accepts `any` value, you can also use it to return platform specific component, like below:
```javascript
const Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
<Component />;
```
### Detecting the Android version
On Android, the `Platform` module can also be used to detect the version of the Android Platform in which the app is running:
```javascript
import { Platform } from 'react-native';
if (Platform.Version === 25) {
console.log('Running on Nougat!');
}
```
### Detecting the iOS version
On iOS, the `Version` is a result of `-[UIDevice systemVersion]`, which is a string with the current version of the operating system. An example of the system version is "10.3". For example, to detect the major version number on iOS:
```javascript
import { Platform } from 'react-native';
const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
console.log('Work around a change in behavior');
}
```
## Platform-specific extensions
When your platform-specific code is more complex, you should consider splitting the code out into separate files. React Native will detect when a file has a `.ios.` or `.android.` extension and load the relevant platform file when required from other components.
For example, say you have the following files in your project:
```sh
BigButton.ios.js
BigButton.android.js
```
You can then require the component as follows:
```javascript
const BigButton = require('./BigButton');
```
React Native will automatically pick up the right file based on the running platform.

View File

@ -1,139 +0,0 @@
---
id: progressbarandroid
title: ProgressBarAndroid
layout: docs
category: components
permalink: docs/progressbarandroid.html
next: progressviewios
previous: pickerios
---
React component that wraps the Android-only `ProgressBar`. This component is used to indicate
that the app is loading or there is some activity in the app.
Example:
```
render: function() {
var progressBar =
<View style={styles.container}>
<ProgressBar styleAttr="Inverse" />
</View>;
return (
<MyLoadingComponent
componentView={componentView}
loadingView={progressBar}
style={styles.loadingComponent}
/>
);
},
```
### Props
- [View props...](docs/view.html#props)
- [`animating`](docs/progressbarandroid.html#animating)
- [`color`](docs/progressbarandroid.html#color)
- [`indeterminate`](docs/progressbarandroid.html#indeterminate)
- [`progress`](docs/progressbarandroid.html#progress)
- [`styleAttr`](docs/progressbarandroid.html#styleattr)
- [`testID`](docs/progressbarandroid.html#testid)
---
# Reference
## Props
### `animating`
Whether to show the ProgressBar (true, the default) or hide it (false).
| Type | Required |
| - | - |
| bool | No |
---
### `color`
Color of the progress bar.
| Type | Required |
| - | - |
| [color](docs/colors.html) | No |
---
### `indeterminate`
If the progress bar will show indeterminate progress. Note that this
can only be false if styleAttr is Horizontal.
| Type | Required |
| - | - |
| indeterminateType | No |
---
### `progress`
The progress value (between 0 and 1).
| Type | Required |
| - | - |
| number | No |
---
### `styleAttr`
Style of the ProgressBar. One of:
- `Horizontal`
- `Normal` (default)
- `Small`
- `Large`
- `Inverse`
- `SmallInverse`
- `LargeInverse`
| Type | Required |
| - | - |
| enum('Horizontal', 'Normal', 'Small', 'Large', 'Inverse', 'SmallInverse', 'LargeInverse') | No |
---
### `testID`
Used to locate this view in end-to-end tests.
| Type | Required |
| - | - |
| string | No |

Some files were not shown because too many files have changed in this diff Show More