From 148b625cc4aead8f64554ba7981ac1b07e693437 Mon Sep 17 00:00:00 2001 From: Nicolas Charpentier Date: Wed, 4 Sep 2019 16:38:36 +0200 Subject: [PATCH 01/26] Split components and APIs grid in 2 or 3 (#1231) --- website/static/css/react-native.css | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/website/static/css/react-native.css b/website/static/css/react-native.css index 13f645d7f19..20ccc17f515 100644 --- a/website/static/css/react-native.css +++ b/website/static/css/react-native.css @@ -160,10 +160,7 @@ a code { } } -@media only screen and (min-device-width: 768px) { - .mainContainer .component-grid { - width: 768px; - } +@media only screen and (min-width: 768px) { .mainContainer .component-grid.component-grid-border { border-bottom: 1px solid #f1eff0; } @@ -176,7 +173,12 @@ a code { @supports (display: grid) { .mainContainer .component-grid { - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(2, 1fr); + } + @media only screen and (min-width: 1440px) { + .mainContainer .component-grid { + grid-template-columns: repeat(3, 1fr); + } } .mainContainer .component { width: auto; From 08feca77717ae2c44c08de4ddb6bae4e094a6c2d Mon Sep 17 00:00:00 2001 From: Kacper Wiszczuk Date: Wed, 4 Sep 2019 16:39:42 +0200 Subject: [PATCH 02/26] imp: Add snack examples to FlatList (#1221) * imp: Add snack examples to FlatList * Update flatlist.md --- docs/flatlist.md | 193 +++++++++++++----- .../versioned_docs/version-0.60/flatlist.md | 193 +++++++++++++----- 2 files changed, 276 insertions(+), 110 deletions(-) diff --git a/docs/flatlist.md b/docs/flatlist.md index c5dbd708b97..5f3793dca56 100644 --- a/docs/flatlist.md +++ b/docs/flatlist.md @@ -18,76 +18,159 @@ A performant interface for rendering simple, flat lists, supporting the most han If you need section support, use [``](sectionlist.md). -Minimal Example: +### Basic Example: + +```SnackPlayer name=flatlist-simple +import React from 'react'; +import { SafeAreaView, View, FlatList, StyleSheet, Text } from 'react-native'; +import Constants from 'expo-constants'; + +const DATA = [ + { + id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba', + title: 'First Item', + }, + { + id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63', + title: 'Second Item', + }, + { + id: '58694a0f-3da1-471f-bd96-145571e29d72', + title: 'Third Item', + }, +]; + +function Item({ title }) { + return ( + + {title} + + ); +} -```jsx - {item.key}} -/> +export default function App() { + return ( + + } + keyExtractor={item => item.id} + /> + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: Constants.statusBarHeight, + }, + item: { + backgroundColor: '#f9c2ff', + padding: 20, + marginVertical: 8, + marginHorizontal: 16, + }, + title: { + fontSize: 32, + }, +}); ``` To render multiple columns, use the [`numColumns`](flatlist.md#numcolumns) prop. Using this approach instead of a `flexWrap` layout can prevent conflicts with the item height logic. -More complex, multi-select example demonstrating `PureComponent` usage for perf optimization and avoiding bugs. +More complex, multi-select example demonstrating `` 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. +- By passing `extraData={selected}` to `FlatList` we make sure `FlatList` itself will re-render when the state changes. Without setting this prop, `FlatList` would not know it needs to re-render any items because it is 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. -```jsx -class MyListItem extends React.PureComponent { - _onPress = () => { - this.props.onPressItem(this.props.id); - }; - - render() { - const textColor = this.props.selected ? 'red' : 'black'; - return ( - - - {this.props.title} - - - ); - } +```SnackPlayer name=flatlist-selectable +import React from 'react'; +import { + SafeAreaView, + TouchableOpacity, + FlatList, + StyleSheet, + Text, +} from 'react-native'; +import Constants from 'expo-constants'; + +const DATA = [ + { + id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba', + title: 'First Item', + }, + { + id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63', + title: 'Second Item', + }, + { + id: '58694a0f-3da1-471f-bd96-145571e29d72', + title: 'Third Item', + }, +]; + +function Item({ id, title, selected, onSelect }) { + return ( + onSelect(id)} + style={[ + styles.item, + { backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' }, + ]} + > + {title} + + ); } -class MultiSelectList extends React.PureComponent { - state = {selected: (new Map(): Map)}; - - _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}) => ( - +export default function App() { + const [selected, setSelected] = React.useState(new Map()); + + const onSelect = React.useCallback( + id => { + const newSelected = new Map(selected); + newSelected.set(id, !selected.get(id)); + + setSelected(newSelected); + }, + [selected], ); - render() { - return ( + return ( + ( + + )} + keyExtractor={item => item.id} + extraData={selected} /> - ); - } + + ); } + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: Constants.statusBarHeight, + }, + item: { + backgroundColor: '#f9c2ff', + padding: 20, + marginVertical: 8, + marginHorizontal: 16, + }, + title: { + fontSize: 32, + }, +}); ``` This is a convenience wrapper around [``](virtualizedlist.md), and thus inherits its props (as well as those of [``](scrollview.md)) that aren't explicitly listed here, along with the following caveats: diff --git a/website/versioned_docs/version-0.60/flatlist.md b/website/versioned_docs/version-0.60/flatlist.md index 3bcc83baa2d..28328ce2c69 100644 --- a/website/versioned_docs/version-0.60/flatlist.md +++ b/website/versioned_docs/version-0.60/flatlist.md @@ -19,76 +19,159 @@ A performant interface for rendering simple, flat lists, supporting the most han If you need section support, use [``](sectionlist.md). -Minimal Example: +### Basic Example: + +```SnackPlayer name=flatlist-simple +import React from 'react'; +import { SafeAreaView, View, FlatList, StyleSheet, Text } from 'react-native'; +import Constants from 'expo-constants'; + +const DATA = [ + { + id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba', + title: 'First Item', + }, + { + id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63', + title: 'Second Item', + }, + { + id: '58694a0f-3da1-471f-bd96-145571e29d72', + title: 'Third Item', + }, +]; + +function Item({ title }) { + return ( + + {title} + + ); +} -```jsx - {item.key}} -/> +export default function App() { + return ( + + } + keyExtractor={item => item.id} + /> + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: Constants.statusBarHeight, + }, + item: { + backgroundColor: '#f9c2ff', + padding: 20, + marginVertical: 8, + marginHorizontal: 16, + }, + title: { + fontSize: 32, + }, +}); ``` To render multiple columns, use the [`numColumns`](flatlist.md#numcolumns) prop. Using this approach instead of a `flexWrap` layout can prevent conflicts with the item height logic. -More complex, multi-select example demonstrating `PureComponent` usage for perf optimization and avoiding bugs. +More complex, multi-select example demonstrating `` 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. +- By passing `extraData={selected}` to `FlatList` we make sure `FlatList` itself will re-render when the state changes. Without setting this prop, `FlatList` would not know it needs to re-render any items because it is 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. -```jsx -class MyListItem extends React.PureComponent { - _onPress = () => { - this.props.onPressItem(this.props.id); - }; - - render() { - const textColor = this.props.selected ? 'red' : 'black'; - return ( - - - {this.props.title} - - - ); - } +```SnackPlayer name=flatlist-selectable +import React from 'react'; +import { + SafeAreaView, + TouchableOpacity, + FlatList, + StyleSheet, + Text, +} from 'react-native'; +import Constants from 'expo-constants'; + +const DATA = [ + { + id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba', + title: 'First Item', + }, + { + id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63', + title: 'Second Item', + }, + { + id: '58694a0f-3da1-471f-bd96-145571e29d72', + title: 'Third Item', + }, +]; + +function Item({ id, title, selected, onSelect }) { + return ( + onSelect(id)} + style={[ + styles.item, + { backgroundColor: selected ? '#6e3b6e' : '#f9c2ff' }, + ]} + > + {title} + + ); } -class MultiSelectList extends React.PureComponent { - state = {selected: (new Map(): Map)}; - - _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}) => ( - +export default function App() { + const [selected, setSelected] = React.useState(new Map()); + + const onSelect = React.useCallback( + id => { + const newSelected = new Map(selected); + newSelected.set(id, !selected.get(id)); + + setSelected(newSelected); + }, + [selected], ); - render() { - return ( + return ( + ( + + )} + keyExtractor={item => item.id} + extraData={selected} /> - ); - } + + ); } + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: Constants.statusBarHeight, + }, + item: { + backgroundColor: '#f9c2ff', + padding: 20, + marginVertical: 8, + marginHorizontal: 16, + }, + title: { + fontSize: 32, + }, +}); ``` This is a convenience wrapper around [``](virtualizedlist.md), and thus inherits its props (as well as those of [``](scrollview.md)) that aren't explicitly listed here, along with the following caveats: From bba1d2e1907cdea8618e0e4d6580d14be9fe9baa Mon Sep 17 00:00:00 2001 From: Radek Pietruszewski Date: Mon, 9 Sep 2019 16:07:35 +0200 Subject: [PATCH 03/26] Update inputaccessoryview.md (#1253) --- docs/inputaccessoryview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/inputaccessoryview.md b/docs/inputaccessoryview.md index c00d4f11b9d..f4e732d698f 100644 --- a/docs/inputaccessoryview.md +++ b/docs/inputaccessoryview.md @@ -44,7 +44,7 @@ export default class UselessTextInput extends Component { } ``` -This component can also be used to create sticky text inputs (text inputs which are anchored to the top of the keyboard). To do this, wrap a `TextInput` with the `InputAccessoryView` component, and don't set a `nativeID`. For an example, look at [InputAccessoryViewExample.js](https://github.com/facebook/react-native/blob/master/RNTester/js/InputAccessoryViewExample.js). +This component can also be used to create sticky text inputs (text inputs which are anchored to the top of the keyboard). To do this, wrap a `TextInput` with the `InputAccessoryView` component, and don't set a `nativeID`. For an example, look at [InputAccessoryViewExample.js](https://github.com/facebook/react-native/blob/master/RNTester/js/examples/InputAccessoryView/InputAccessoryViewExample.js). --- From c549569366fbfeb140c8e584822d19fdd06137e9 Mon Sep 17 00:00:00 2001 From: Rachel Nabors Date: Fri, 13 Sep 2019 15:19:11 +0100 Subject: [PATCH 04/26] Adding banner for docs survey, please remove in 2 weeks (#1263) --- website/siteConfig.js | 1 + website/static/css/header.css | 37 +++++++++++++++++++++++++++ website/static/js/2019_docs-survey.js | 10 ++++++++ 3 files changed, 48 insertions(+) create mode 100644 website/static/js/2019_docs-survey.js diff --git a/website/siteConfig.js b/website/siteConfig.js index 35369225090..b20dba72cd0 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -81,6 +81,7 @@ const siteConfig = { 'https://buttons.github.io/buttons.js', baseUrl + 'js/codeblocks.js', baseUrl + 'js/tabs.js', + baseUrl + 'js/2019_docs-survey.js', ], cleanUrl: true, scrollToTop: true, diff --git a/website/static/css/header.css b/website/static/css/header.css index 7ff7da88c4e..cd293efcb51 100644 --- a/website/static/css/header.css +++ b/website/static/css/header.css @@ -182,3 +182,40 @@ input#search_input_react { input#search_input_react:focus { background-color: $light; } + +/* 2019_docs-survey */ +.callout_docs-survey-2019-2 { + background-color: rgba(5, 165, 209, 0.25); + border-radius: 0.15em; + color: #001217; + display: block; + margin: 1em 0; + position: relative; + padding: 1em 2em 1em 3.5em; + transition: transform 300ms ease-out; +} + +.callout_docs-survey-2019-2 svg { + fill: rgba(5, 165, 209, 1); + height: 2em; + width: 2em; + position: absolute; + top: 0.75em; + left: 1em; +} + +.callout_docs-survey-2019-2:link, +.callout_docs-survey-2019-2:visited { + color: #001217; +} + +.callout_docs-survey-2019-2:hover, +.callout_docs-survey-2019-2:active, +.callout_docs-survey-2019-2:focus { + color: #001217; + transform: translate(0.1em, 0.1em); +} + +.callout_docs-survey-2019-2 span { + text-decoration: underline; +} diff --git a/website/static/js/2019_docs-survey.js b/website/static/js/2019_docs-survey.js new file mode 100644 index 00000000000..54b7cc89617 --- /dev/null +++ b/website/static/js/2019_docs-survey.js @@ -0,0 +1,10 @@ +document.addEventListener('DOMContentLoaded', function() { + const container = document.querySelector('.container.mainContainer .wrapper'); + if (container) { + const div = document.createElement('div'); + div.innerHTML = + '89allHave two minutes to help us make the React Native docs even better? Take our short survey!'; + const content = div.childNodes[0]; + container.insertBefore(content, container.childNodes[0]); + } +}); From c87fe3ac9d9f0414aa958072200ac5470468e38a Mon Sep 17 00:00:00 2001 From: Nicolas Charpentier Date: Fri, 13 Sep 2019 13:52:55 -0400 Subject: [PATCH 05/26] Run sync-guides (#1228) --- .../version-0.5/accessibility.md | 154 ++-- .../versioned_docs/version-0.5/animations.md | 79 +- .../version-0.5/app-extensions.md | 2 +- .../version-0.5/communication-ios.md | 6 +- .../version-0.5/components-and-apis.md | 8 - .../versioned_docs/version-0.5/debugging.md | 4 +- .../version-0.5/direct-manipulation.md | 10 +- website/versioned_docs/version-0.5/flexbox.md | 159 +++- .../version-0.5/getting-started.md | 129 +-- .../version-0.5/handling-text-input.md | 8 +- .../version-0.5/headless-js-android.md | 39 + .../version-0.5/height-and-width.md | 15 +- website/versioned_docs/version-0.5/images.md | 4 +- .../integration-with-existing-apps.md | 34 +- .../version-0.5/javascript-environment.md | 13 +- .../version-0.5/more-resources.md | 6 +- .../version-0.5/native-components-ios.md | 73 ++ .../version-0.5/native-modules-android.md | 19 +- .../version-0.5/native-modules-setup.md | 10 +- .../versioned_docs/version-0.5/navigation.md | 8 + website/versioned_docs/version-0.5/network.md | 4 +- .../versioned_docs/version-0.5/performance.md | 56 +- website/versioned_docs/version-0.5/props.md | 16 +- .../removing-default-permissions.md | 17 +- .../version-0.5/running-on-simulator-ios.md | 2 +- .../version-0.5/signed-apk-android.md | 68 +- website/versioned_docs/version-0.5/state.md | 14 +- website/versioned_docs/version-0.5/style.md | 9 +- website/versioned_docs/version-0.5/timers.md | 23 - .../version-0.5/troubleshooting.md | 2 +- .../versioned_docs/version-0.5/tutorial.md | 2 +- .../versioned_docs/version-0.5/upgrading.md | 4 +- .../version-0.5/using-a-scrollview.md | 11 +- website/versioned_docs/version-0.59/images.md | 223 ----- .../version-0.60/accessibility.md | 306 ------- .../versioned_docs/version-0.60/animations.md | 409 --------- .../version-0.60/app-extensions.md | 27 - .../version-0.60/communication-ios.md | 201 ----- .../version-0.60/components-and-apis.md | 222 ----- .../versioned_docs/version-0.60/debugging.md | 182 ---- .../version-0.60/direct-manipulation.md | 207 ----- .../versioned_docs/version-0.60/flexbox.md | 229 ----- .../version-0.60/getting-started.md | 560 ------------ .../version-0.60/handling-text-input.md | 43 - .../version-0.60/headless-js-android.md | 185 ---- .../version-0.60/height-and-width.md | 59 -- website/versioned_docs/version-0.60/images.md | 223 ----- .../integration-with-existing-apps.md | 799 ------------------ .../version-0.60/javascript-environment.md | 90 -- .../version-0.60/more-resources.md | 44 - .../version-0.60/native-components-ios.md | 512 ----------- .../version-0.60/native-modules-android.md | 484 ----------- .../version-0.60/native-modules-setup.md | 27 - .../versioned_docs/version-0.60/navigation.md | 69 -- .../versioned_docs/version-0.60/network.md | 193 ----- .../version-0.60/performance.md | 431 ---------- website/versioned_docs/version-0.60/props.md | 62 -- .../removing-default-permissions.md | 55 -- .../version-0.60/running-on-simulator-ios.md | 15 - .../version-0.60/signed-apk-android.md | 145 ---- website/versioned_docs/version-0.60/state.md | 60 -- website/versioned_docs/version-0.60/style.md | 46 - website/versioned_docs/version-0.60/timers.md | 50 -- .../version-0.60/troubleshooting.md | 111 --- .../versioned_docs/version-0.60/tutorial.md | 46 - .../versioned_docs/version-0.60/upgrading.md | 124 --- .../version-0.60/using-a-scrollview.md | 60 -- 67 files changed, 601 insertions(+), 6906 deletions(-) delete mode 100644 website/versioned_docs/version-0.59/images.md delete mode 100644 website/versioned_docs/version-0.60/accessibility.md delete mode 100644 website/versioned_docs/version-0.60/animations.md delete mode 100644 website/versioned_docs/version-0.60/app-extensions.md delete mode 100644 website/versioned_docs/version-0.60/communication-ios.md delete mode 100644 website/versioned_docs/version-0.60/components-and-apis.md delete mode 100644 website/versioned_docs/version-0.60/debugging.md delete mode 100644 website/versioned_docs/version-0.60/direct-manipulation.md delete mode 100644 website/versioned_docs/version-0.60/flexbox.md delete mode 100644 website/versioned_docs/version-0.60/getting-started.md delete mode 100644 website/versioned_docs/version-0.60/handling-text-input.md delete mode 100644 website/versioned_docs/version-0.60/headless-js-android.md delete mode 100644 website/versioned_docs/version-0.60/height-and-width.md delete mode 100644 website/versioned_docs/version-0.60/images.md delete mode 100644 website/versioned_docs/version-0.60/integration-with-existing-apps.md delete mode 100644 website/versioned_docs/version-0.60/javascript-environment.md delete mode 100644 website/versioned_docs/version-0.60/more-resources.md delete mode 100644 website/versioned_docs/version-0.60/native-components-ios.md delete mode 100644 website/versioned_docs/version-0.60/native-modules-android.md delete mode 100644 website/versioned_docs/version-0.60/native-modules-setup.md delete mode 100644 website/versioned_docs/version-0.60/navigation.md delete mode 100644 website/versioned_docs/version-0.60/network.md delete mode 100644 website/versioned_docs/version-0.60/performance.md delete mode 100644 website/versioned_docs/version-0.60/props.md delete mode 100644 website/versioned_docs/version-0.60/removing-default-permissions.md delete mode 100644 website/versioned_docs/version-0.60/running-on-simulator-ios.md delete mode 100644 website/versioned_docs/version-0.60/signed-apk-android.md delete mode 100644 website/versioned_docs/version-0.60/state.md delete mode 100644 website/versioned_docs/version-0.60/style.md delete mode 100644 website/versioned_docs/version-0.60/timers.md delete mode 100644 website/versioned_docs/version-0.60/troubleshooting.md delete mode 100644 website/versioned_docs/version-0.60/tutorial.md delete mode 100644 website/versioned_docs/version-0.60/upgrading.md delete mode 100644 website/versioned_docs/version-0.60/using-a-scrollview.md diff --git a/website/versioned_docs/version-0.5/accessibility.md b/website/versioned_docs/version-0.5/accessibility.md index c90414f01d2..e3b4bdf6ec2 100644 --- a/website/versioned_docs/version-0.5/accessibility.md +++ b/website/versioned_docs/version-0.5/accessibility.md @@ -8,7 +8,7 @@ original_id: accessibility 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. +In addition to this documentation, you might find [this blog post](https://engineering.fb.com/ios/making-react-native-apps-accessible/) about React Native accessibility to be useful. ## Making Apps Accessible @@ -76,9 +76,9 @@ Inverting screen colors is an Accessibility feature that makes the iPhone and iP #### accessibilityRole (iOS, Android) -> **Note:** Accessibility Role and Accessibility States are meant to be a cross-platform solution to replace `accessibilityTraits` and `accessibilityComponentType`, which will soon be deprecated. When possible, use `accessibilityRole` and `accessibilityStates` instead of `accessibilityTraits` and `accessibilityComponentType`. +`accessibilityRole` communicates the purpose of a component to the user of an assistive technology. -Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on Android the type of element that is focused on. To use, set the `accessibilityRole` property to one of the following strings: +`accessibilityRole` can be one of the following: - **none** Used when the element has no role. - **button** Used when the element should be treated as a button. @@ -91,43 +91,38 @@ Accessibility Role tells a person using either VoiceOver on iOS or TalkBack on A - **imagebutton** Used when the element should be treated as a button and is also an image. - **header** Used when an element acts as a header for a content section (e.g. the title of a navigation bar). - **summary** Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches. +- **alert** Used when an element contains important text to be presented to the user. +- **checkbox** Used when an element represents a checkbox which can be checked, unchecked, or have mixed checked state. +- **combobox** Used when an element represents a combo box, which allows the user to select among several choices. +- **menu** Used when the component is a menu of choices. +- **menubar** Used when a component is a container of multiple menus. +- **menuitem** Used to represent an item within a menu. +- **progressbar** Used to represent a component which indicates progress of a task. +- **radio** Used to represent a radio button. +- **radiogroup** Used to represent a group of radio buttons. +- **scrollbar** Used to represent a scroll bar. +- **spinbutton** Used to represent a button which opens a list of choices. +- **switch** Used to represent a switch which can be turned on and off. +- **tab** Used to represent a tab. +- **tablist** Used to represent a list of tabs. +- **timer** Used to represent a timer. +- **toolbar** Used to represent a tool bar (a container of action buttons or components). #### accessibilityStates (iOS, Android) -> **Note:** > `accessibilityRole` and `accessibilityStates` are meant to be a cross-platform solution to replace `accessibilityTraits` and `accessibilityComponentType`, which will soon be deprecated. When possible, use `accessibilityRole` and `accessibilityStates` instead of `accessibilityTraits` and `accessibilityComponentType`. +Describes the current state of a component to the user of an assistive technology. -Accessibility State tells a person using either VoiceOver on iOS or TalkBack on Android the state of the element currently focused on. The state of the element can be set either to `selected` or `disabled` or both: +`accessibilityStates` is an array of values, and may include any of the following: - **selected** Used when the element is in a selected state. For example, a button is selected. - **disabled** Used when the element is disabled and cannot be interacted with. +- **checked** Used to indicate that a checkable element is currently checked. +- **unchecked** Used to indicate that a checkable element is not currently checked. +- **busy** Used to indicate that an element is currently busy. +- **expanded** Used to indicate that an expandable element is currently expanded. +- **collapsed** Used to indicate that an expandable element is currently collapsed. -To use, set the `accessibilityStates` to an array containing either `selected`, `disabled`, or both. - -#### accessibilityTraits (iOS) - -> **Note:** `accessibilityTraits` will soon be deprecated. When possible, use `accessibilityRole` and `accessibilityStates` instead of `accessibilityTraits` and `accessibilityComponentType`. - -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. +To use, set the `accessibilityStates` to an array containing the list of current states. #### accessibilityViewIsModal (iOS) @@ -153,23 +148,6 @@ Assign this property to a custom function which will be called when someone perf Assign this property to a custom function which will be called when someone performs the "escape" gesture, which is a two finger Z shaped gesture. An escape function should move back hierarchically in the user interface. This can mean moving up or back in a navigation hierarchy or dismissing a modal user interface. If the selected element does not have an `onAccessibilityEscape` function, the system will attempt to traverse up the view hierarchy until it finds a view that does or bonk to indicate it was unable to find one. -#### accessibilityComponentType (Android) - -> **Note:** > `accessibilityComponentType` will soon be deprecated. When possible, use `accessibilityRole` and `accessibilityStates` instead of `accessibilityTraits` and `accessibilityComponentType`. - -In some cases, we also want to alert the end user of the type of selected component (i.e., that it is a “button”). If we were using native buttons, this would work automatically. Since we are using javascript, we need to provide a bit more context for TalkBack. To do so, you must specify the ‘accessibilityComponentType’ property for any UI component. We support 'none', ‘button’, ‘radiobutton_checked’ and ‘radiobutton_unchecked’. - -```jsx - - - Press me! - - -``` - -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’: @@ -210,6 +188,59 @@ In the case of two overlapping UI components with the same parent, default acces 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. +### Accessibility Actions + +Accessibility actions allow an assistive technology to programmatically invoke the actions of a component. In order to support accessibility actions, a component must do two things: + +- Define the list of actions it supports via the `accessibilityActions` property. +- Implement an `onAccessibilityAction` function to handle action requests. + +The `accessibilityActions` property should contain a list of action objects. Each action object should contain the following fields: + +| Name | Type | Required | +| ----- | ------ | -------- | +| name | string | Yes | +| label | string | No | + +Actions either represent standard actions, such as clicking a button or adjusting a slider, or custom actions specific to a given component such as deleting an email message. The `name` field is required for both standard and custom actions, but `label` is optional for standard actions. + +When adding support for standard actions, `name` must be one of the following: + +- `'magicTap'` - iOS only - While VoiceOver focus is on or inside the component, the user double tapped with two fingers. +- `'escape'` - iOS only - While VoiceOver focus is on or inside the component, the user performed a two finger scrub gesture (left, right, left). +- `'activate'` - Activate the component. Typically this should perform the same action as when the user touches or clicks the component when not using an assistive technology. This is generated when a screen reader user double taps the component. +- `'increment'` - Increment an adjustable component. On iOS, VoiceOver generates this action when the component has a role of `'adjustable'` and the user places focus on it and swipes upward. On Android, TalkBack generates this action when the user places accessibility focus on the component and presses the volume up button. +- `'decrement'` - Decrement an adjustable component. On iOS, VoiceOver generates this action when the component has a role of `'adjustable'` and the user places focus on it and swipes downward. On Android, TalkBack generates this action when the user places accessibility focus on the component and presses the volume down button. +- `'longpress'` - Android only - This action is generated when the user places accessibility focus on the component and double tap and holds one finger on the screen. Typically, this should perform the same action as when the user holds down one finger on the component while not using an assistive technology. + +The `label` field is optional for standard actions, and is often unused by assistive technologies. For custom actions, it is a localized string containing a description of the action to be presented to the user. + +To handle action requests, a component must implement an `onAccessibilityAction` function. The only argument to this function is an event containing the name of the action to perform. The below example from RNTester shows how to create a component which defines and handles several custom actions. + +```jsx + { + switch (event.nativeEvent.actionName) { + case 'cut': + Alert.alert('Alert', 'cut action success'); + break; + case 'copy': + Alert.alert('Alert', 'copy action success'); + break; + case 'paste': + Alert.alert('Alert', 'paste action success'); + break; + } + }} +/> +``` + ### 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](accessibilityinfo.md) for details. @@ -245,8 +276,31 @@ In the above example we've created a custom radio button that now behaves like a ## 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, go to the Settings app on your iOS device (it's not available for simulator). 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. + +## Testing TalkBack Support (Android) + +To enable TalkBack, go to the Settings app on your Android device or emulator. Tap Accessibility, then TalkBack. Toggle the "Use service" switch to enable or disable it. + +P.S. Android emulator doesn’t have TalkBack by default. To install it: + +1. Download TalkBack file here: https://google-talkback.en.uptodown.com/android +2. Drag the downloaded `.apk` file into the emulator + +You can use the volume key shortcut to toggle TalkBack. To turn on the volume key shortcut, go to the Settings app, then Accessibility. At the top, turn on Volume key shortcut. + +To use the volume key shortcut, press both volume keys for 3 seconds to start an accessibility tool. + +Additionally, if you prefer, you can toggle TalkBack via command line with: + +``` +# disable +adb shell settings put secure enabled_accessibility_services com.android.talkback/com.google.android.marvin.talkback.TalkBackService + +# enable +adb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkback/com.google.android.marvin.talkback.TalkBackService +``` diff --git a/website/versioned_docs/version-0.5/animations.md b/website/versioned_docs/version-0.5/animations.md index 7f0f9f4ffff..7b73d696aed 100644 --- a/website/versioned_docs/version-0.5/animations.md +++ b/website/versioned_docs/version-0.5/animations.md @@ -12,56 +12,48 @@ React Native provides two complementary animation systems: [`Animated`](animatio The [`Animated`](animated.md) 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()`. +`Animated` exports six animatable component types: `View`, `Text`, `Image`, `ScrollView`, `FlatList` and `SectionList`, 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 React, { useState, useEffect } 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 - } +const FadeInView = (props) => { + const [fadeAdmin] = useState(new Animated.Value(0)) // Initial value for opacity: 0 - componentDidMount() { - Animated.timing( // Animate over time - this.state.fadeAnim, // The animated value to drive + React.useEffect(() => { + Animated.timing( + fadeAdmin, { - toValue: 1, // Animate to opacity: 1 (opaque) - duration: 10000, // Make it take a while + toValue: 1, + duration: 10000, } - ).start(); // Starts the animation - } - - render() { - let { fadeAnim } = this.state; - - return ( - - {this.props.children} - - ); - } + ).start(); + }, []) + + return ( + + {props.children} + + ); } // You can then use your `FadeInView` in place of a `View` in your components: -export default class App extends React.Component { - render() { - return ( - - - Fading in - - - ) - } +export default () => { + return ( + + + Fading in + + + ) } ``` @@ -69,8 +61,7 @@ Let's break down what's happening here. In the `FadeInView` constructor, a new ` 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. +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 @@ -258,7 +249,7 @@ You may notice that there is no obvious way to read the current value while anim ### 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. +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), 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. @@ -319,8 +310,8 @@ While using transform styles such as `rotateY`, `rotateX`, and others ensure the 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) +- [AnimatedGratuitousApp](https://github.com/facebook/react-native/tree/master/RNTester/js/examples/Animated/AnimatedGratuitousApp) +- [NativeAnimationsExample](https://github.com/facebook/react-native/blob/master/RNTester/js/examples/NativeAnimation/NativeAnimationsExample.js) ## `LayoutAnimation` API @@ -415,4 +406,4 @@ As mentioned [in the Direct Manipulation section](direct-manipulation.md), `setN 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](interactionmanager.md). You can monitor the frame rate by using the In-App Developer Menu "FPS Monitor" tool. +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). You may also want to defer any computationally intensive work until after animations are complete, using the [InteractionManager](interactionmanager.md). You can monitor the frame rate by using the In-App Developer Menu "FPS Monitor" tool. diff --git a/website/versioned_docs/version-0.5/app-extensions.md b/website/versioned_docs/version-0.5/app-extensions.md index a27630bec52..bf6f30e1dd2 100644 --- a/website/versioned_docs/version-0.5/app-extensions.md +++ b/website/versioned_docs/version-0.5/app-extensions.md @@ -10,7 +10,7 @@ App extensions let you provide custom functionality and content outside of your 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. +We highly recommend that you watch Conrad Kramer's talk on [Memory Use in Extensions](https://www.youtube.com/watch?v=GqXMqn6MXrM) to learn more about this topic. ### Today widget diff --git a/website/versioned_docs/version-0.5/communication-ios.md b/website/versioned_docs/version-0.5/communication-ios.md index 4b3fe1a4c86..2afc10b0453 100644 --- a/website/versioned_docs/version-0.5/communication-ios.md +++ b/website/versioned_docs/version-0.5/communication-ios.md @@ -35,9 +35,9 @@ RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge ```jsx import React from 'react'; -import {AppRegistry, View, Image} from 'react-native'; +import {View, Image} from 'react-native'; -class ImageBrowserApp extends React.Component { +export default class ImageBrowserApp extends React.Component { renderImage(imgURI) { return ; } @@ -45,8 +45,6 @@ class ImageBrowserApp extends React.Component { return {this.props.images.map(this.renderImage)}; } } - -AppRegistry.registerComponent('ImageBrowserApp', () => 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. diff --git a/website/versioned_docs/version-0.5/components-and-apis.md b/website/versioned_docs/version-0.5/components-and-apis.md index 9ce293713f2..af38cd9a26a 100644 --- a/website/versioned_docs/version-0.5/components-and-apis.md +++ b/website/versioned_docs/version-0.5/components-and-apis.md @@ -105,10 +105,6 @@ Many of the following components provide wrappers for commonly used UIKit classe

ImagePickerIOS

Renders a image picker on iOS.

-
-

NavigatorIOS

-

A wrapper around UINavigationController, enabling you to implement a navigation stack.

-

ProgressViewIOS

Renders a UIProgressView on iOS.

@@ -187,10 +183,6 @@ These components may come in handy for certain applications. For an exhaustive l

Animated

A library for creating fluid, powerful animations that are easy to build and maintain.

-
-

CameraRoll

-

Provides access to the local camera roll / gallery.

-

Clipboard

Provides an interface for setting and getting content from the clipboard on both iOS and Android.

diff --git a/website/versioned_docs/version-0.5/debugging.md b/website/versioned_docs/version-0.5/debugging.md index fa2b6bd3ec8..a839a4d548b 100644 --- a/website/versioned_docs/version-0.5/debugging.md +++ b/website/versioned_docs/version-0.5/debugging.md @@ -24,7 +24,7 @@ Instead of recompiling your app every time you make a change, you can reload you 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. +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) 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. @@ -89,7 +89,7 @@ However, there are some disadvantages: ## 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: +You can use [the standalone version of React Developer Tools](https://github.com/facebook/react/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 diff --git a/website/versioned_docs/version-0.5/direct-manipulation.md b/website/versioned_docs/version-0.5/direct-manipulation.md index 5229742d2ee..b759df48f30 100644 --- a/website/versioned_docs/version-0.5/direct-manipulation.md +++ b/website/versioned_docs/version-0.5/direct-manipulation.md @@ -8,7 +8,7 @@ It is sometimes necessary to make changes directly to a component without using > 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/advanced-performance.md#shouldcomponentupdate-in-action). +> 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](https://reactjs.org/docs/optimizing-performance.html#shouldcomponentupdate-in-action). ## setNativeProps with TouchableOpacity @@ -55,7 +55,7 @@ render() { 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](https://github.com/facebook/react-native/blob/master/Libraries/Renderer/oss/ReactNativeRenderer-prod.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](https://github.com/facebook/react-native/blob/fb2ec1ea47c53c2e7b873acb1cb46192ac74274e/Libraries/Renderer/oss/ReactNativeRenderer-prod.js#L5793-L5813). +If you look at the implementation of `setNativeProps` in [NativeMethodsMixin](https://github.com/facebook/react-native/blob/master/Libraries/Renderer/implementations/ReactNativeRenderer-prod.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](https://github.com/facebook/react-native/blob/fb2ec1ea47c53c2e7b873acb1cb46192ac74274e/Libraries/Renderer/oss/ReactNativeRenderer-prod.js#L5793-L5813). ## Composite components and setNativeProps @@ -140,10 +140,10 @@ export default class App extends React.Component { render() { return ( - + this._textInput = component} - style={{height: 50, flex: 1, marginHorizontal: 20, borderWidth: 1, borderColor: '#ccc'}} + style={{height: 50, width: 200, marginHorizontal: 20, borderWidth: 1, borderColor: '#ccc'}} /> Clear text @@ -190,7 +190,7 @@ Determines the location of the given view in the window and returns the values v ### 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. +Like `measure()`, but measures the view relative to 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 `findNodeHandle(component)`. diff --git a/website/versioned_docs/version-0.5/flexbox.md b/website/versioned_docs/version-0.5/flexbox.md index 236e6226c6a..b531fa1e890 100644 --- a/website/versioned_docs/version-0.5/flexbox.md +++ b/website/versioned_docs/version-0.5/flexbox.md @@ -10,13 +10,31 @@ You will normally use a combination of `flexDirection`, `alignItems`, and `justi > 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 + +[`flex`](https://facebook.github.io/react-native/docs/layout-props#flex) will define how your items are going to **“fill”** over the available space along your main axis. Space will be divided according to each element's flex property. + +In the following example the red, yellow and the green views are all children in the container view that has `flex: 1` set. The red view uses `flex: 1` , the yellow view uses `flex: 2` and the green view uses `flex: 3` . **1+2+3 = 6** which means that the red view will get `1/6` of the space, the yellow `2/6` of the space and the green `3/6` of the space. + +![Flex](https://cdn-images-1.medium.com/max/800/1*PhCFmO5tYX_sZSyCd4vO3w.png) + #### 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`. +[`flexDirection`](https://facebook.github.io/react-native/docs/layout-props#flexdirection) controls the direction in which the children of a node are laid out. This is also referred to as the _main axis_. The cross axis is the axis perpendicular to the main axis, or the axis which the wrapping lines are laid out in. + +- `row` Align children from left to right. If wrapping is enabled then the next line will start under the first item on the left of the container. + +- `column` (**default value**) Align children from top to bottom. If wrapping is enabled then the next line will start to the left first item on the top of the container. + +- `row-reverse` Align children from right to left. If wrapping is enabled then the next line will start under the first item on the right of the container. + +- `column-reverse` Align children from bottom to top. If wrapping is enabled then the next line will start to the left first item on the bottom of the container. + +LEARN MORE [HERE](https://yogalayout.com/docs/flex-direction) -```SnackPlayer +```SnackPlayer name=Flex%20Direction import React, { Component } from 'react'; -import { AppRegistry, View } from 'react-native'; +import { View } from 'react-native'; export default class FlexDirectionBasics extends Component { render() { @@ -30,18 +48,39 @@ export default class FlexDirectionBasics extends Component { ); } }; - -// skip this line if using Create React Native App -AppRegistry.registerComponent('AwesomeProject', () => FlexDirectionBasics); ``` +![Flex Direction](https://cdn-images-1.medium.com/max/800/1*rA7IbuUsJWsx6evKAsabVw.png) + +### Layout Direction + +Layout direction specifies the direction in which children and text in a hierarchy should be laid out. Layout direction also affects what edge `start` and `end` refer to. By default React Native lays out with LTR layout direction. In this mode `start` refers to left and `end` refers to right. + +- `LTR` (**default value**) Text and children are laid out from left to right. Margin and padding applied the start of an element are applied on the left side. + +- `RTL` Text and children are laid out from right to left. Margin and padding applied the start of an element are applied on the right side. + #### 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`, `space-between` and `space-evenly`. +[`justifyContent`](https://facebook.github.io/react-native/docs/layout-props#justifycontent) describes how to align children within the main axis of their container. For example, you can use this property to center a child horizontally within a container with `flexDirection` set to `row` or vertically within a container with `flexDirection` set to `column`. + +- `flex-start`(**default value**) Align children of a container to the start of the container's main axis. + +- `flex-end` Align children of a container to the end of the container's main axis. + +- `center` Align children of a container in the center of the container's main axis. -```SnackPlayer +- `space-between` Evenly space of children across the container's main axis, distributing remaining space between the children. + +- `space-around` Evenly space of children across the container's main axis, distributing remaining space around the children. Compared to `space-between` using `space-around` will result in space being distributed to the beginning of the first child and end of the last child. + +- `space-evenly` Evenly distributed within the alignment container along the main axis. The spacing between each pair of adjacent items, the main-start edge and the first item, and the main-end edge and the last item, are all exactly the same. + +LEARN MORE [HERE](https://yogalayout.com/docs/justify-content) + +```SnackPlayer name=Justify%20Content import React, { Component } from 'react'; -import { AppRegistry, View } from 'react-native'; +import { View } from 'react-native'; export default class JustifyContentBasics extends Component { render() { @@ -60,20 +99,31 @@ export default class JustifyContentBasics extends Component { ); } }; - -// skip this line if using Create React Native App -AppRegistry.registerComponent('AwesomeProject', () => JustifyContentBasics); ``` +![Justify Content](https://cdn-images-1.medium.com/max/800/1*i5TVlme-TisAVvD5ax2yPA.png) + #### 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`. +[`alignItems`](https://facebook.github.io/react-native/docs/layout-props#alignitems) describes how to align children along the cross axis of their container. Align items is very similar to `justifyContent` but instead of applying to the main axis, `alignItems` applies to the cross axis. + +- `stretch` (**default value**) Stretch children of a container to match the `height` of the container's cross axis. + +- `flex-start` Align children of a container to the start of the container's cross axis. + +- `flex-end` Align children of a container to the end of the container's cross axis. + +- `center` Align children of a container in the center of the container's cross axis. + +- `baseline` Align children of a container along a common baseline. Individual children can be set to be the reference baseline for their parents. > 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 `width: 50` is removed from the children. -```SnackPlayer +LEARN MORE [HERE](https://yogalayout.com/docs/align-items) + +```SnackPlayer name=Align%20Items import React, { Component } from 'react'; -import { AppRegistry, View } from 'react-native'; +import { View } from 'react-native'; export default class AlignItemsBasics extends Component { render() { @@ -94,13 +144,86 @@ export default class AlignItemsBasics extends Component { ); } }; - -// skip this line if using Create React Native App -AppRegistry.registerComponent('AwesomeProject', () => AlignItemsBasics); ``` +![Align Items](https://cdn-images-1.medium.com/max/800/1*evkM7zfxt-9p-HJ1M0Bh2g.png) + +### Align Self + +[`alignSelf`](https://facebook.github.io/react-native/docs/layout-props#alignself) has the same options and effect as `alignItems` but instead of affecting the children within a container, you can apply this property to a single child to change its alignment within its parent. `alignSelf` overrides any option set by the parent with `alignItems`. + +![Align Self](https://cdn-images-1.medium.com/max/800/1*J1JCoKwLCokX9JXVBvP71g.png) + +### Align Content + +[alignContent](https://facebook.github.io/react-native/docs/layout-props#aligncontent) defines the distribution of lines along the cross-axis. This only has effect when items are wrapped to multiple lines using `flexWrap`. + +- `flex-start` (**default value**) Align wrapped lines to the start of the container's cross axis. + +- `flex-end` Align wrapped lines to the end of the container's cross axis. + +- `stretch` wrapped lines to match the height of the container's cross axis. + +- `center` Align wrapped lines in the center of the container's cross axis. + +- `space-between` Evenly space wrapped lines across the container's main axis, distributing remaining space between the lines. + +- `space-around` Evenly space wrapped lines across the container's main axis, distributing remaining space around the lines. Compared to space between using space around will result in space being distributed to the begining of the first lines and end of the last line. + +LEARN MORE [HERE](https://yogalayout.com/docs/align-content) + +![Align Content](https://cdn-images-1.medium.com/max/800/1*cC2XFyCF_igp20Ombt4wBw.png) + +### Flex Wrap + +The [`flexWrap`](https://facebook.github.io/react-native/docs/layout-props#flexwrap) property is set on containers and controls what happens when children overflow the size of the container along the main axis. By default children are forced into a single line (which can shrink elements). If wrapping is allowed items are wrapped into multiple lines along the main axis if needed. + +When wrapping lines `alignContent` can be used to specify how the lines are placed in the container. learn more [here](https://yogalayout.com/docs/flex-wrap) + +![Flex Wrap](https://cdn-images-1.medium.com/max/800/1*_7v4uQhSsuCn1cfeOMVfrA.png) + +### Flex Basis, Grow, and Shrink + +- [`flexGrow`](https://facebook.github.io/react-native/docs/layout-props#flexgrow) describes how any space within a container should be distributed among its children along the main axis. After laying out its children, a container will distribute any remaining space according to the flex grow values specified by its children. + + flexGrow accepts any floating point value >= 0, with 0 being the default value. A container will distribute any remaining space among its children weighted by the child’s flex grow value. + +- [`flexShrink`](https://facebook.github.io/react-native/docs/layout-props#flexshrink) describes how to shrink children along the main axis in the case that the total size of the children overflow the size of the container on the main axis. Flex shrink is very similar to flex grow and can be thought of in the same way if any overflowing size is considered to be negative remaining space. These two properties also work well together by allowing children to grow and shrink as needed. + + Flex shrink accepts any floating point value >= 0, with 1 being the default value. A container will shrink its children weighted by the child’s flex shrink value. + +- [`flexBasis`](https://facebook.github.io/react-native/docs/layout-props#flexbasis) is an axis-independent way of providing the default size of an item along the main axis. Setting the flex basis of a child is similar to setting the `width` of that child if its parent is a container with `flexDirection: row` or setting the `height` of a child if its parent is a container with `flexDirection: column`. The flex basis of an item is the default size of that item, the size of the item before any flex grow and flex shrink calculations are performed. + +LEARN MORE [HERE](https://yogalayout.com/docs/flex) + +### Width and Height + +The `width` property in Yoga specifies the width of the element's content area. Similarly height property specifies the `height` of the element's content area. + +Both `width` and `height` can take following values: + +- `auto` Is the **default Value**, React Native calculates the width/height for the element based on its content, whether that is other children, text, or an image. + +- `pixels` Defines the width/height in absolute pixels. Depending on other styles set on the component, this may or may not be the final dimension of the node. + +- `percentage` Defines the width or height in percentage of its parent's width or height respectively. + +### Absolute & Relative Layout + +The `position` type of an element defines how it is positioned within its parent. + +`relative` (**default value**) By default an element is positioned relatively. This means an element is positioned according to the normal flow of the layout, and then offset relative to that position based on the values of `top`, `right`, `bottom`, and `left`. The offset does not affect the position of any sibling or parent elements. + +`absolute` When positioned absolutely an element doesn't take part in the normal layout flow. It is instead laid out independent of its siblings. The position is determined based on the `top`, `right`, `bottom`, and `left` values. + +![Absolute & Relative Layoutp](https://cdn-images-1.medium.com/max/800/1*NlPeRQCQK3Vb5nyjL0Mqxw.png) + #### Going Deeper +Check out the interactive [yoga playground](https://yogalayout.com/playground) that you can use to get a better understanding of flexbox. + 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](./layout-props.md). 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](handling-text-input.md). + +See some examples from [Wix Engineers](https://medium.com/wix-engineering/the-full-react-native-layout-cheat-sheet-a4147802405c): diff --git a/website/versioned_docs/version-0.5/getting-started.md b/website/versioned_docs/version-0.5/getting-started.md index 031a6711cfe..c2e04056c11 100644 --- a/website/versioned_docs/version-0.5/getting-started.md +++ b/website/versioned_docs/version-0.5/getting-started.md @@ -6,9 +6,9 @@ original_id: getting-started 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](tutorial.md). -If you are coming from a web background, the easiest way to get started with React Native is with Expo tools because they allow you to start a project without installing and configuring Xcode or Android Studio. Expo CLI sets up a development environment on your local machine and you can be writing a React Native app within minutes. For instant development, you can use [Snack](https://snack.expo.io/) to try React Native out directly in your web browser. +If you are new to mobile development, the easiest way to get started is with Expo CLI. Expo is a set of tools built around React Native and, while it has many [features](https://expo.io/features), the most relevant feature for us right now is that it can get you writing a React Native app within minutes. You will only need a recent version of Node.js and a phone or emulator. If you'd like to try out React Native directly in your web browser before installing any tools, you can try out [Snack](https://snack.expo.io/). -If you are familiar with native development, you will likely want to use React Native CLI. It requires Xcode or Android Studio to get started. If you already have one of these tools installed, you should be able to get up and running within a few minutes. If they are not installed, you should expect to spend about an hour installing and configuring them. +If you are already familiar with mobile development, you may want to use React Native CLI. It requires Xcode or Android Studio to get started. If you already have one of these tools installed, you should be able to get up and running within a few minutes. If they are not installed, you should expect to spend about an hour installing and configuring them.
    @@ -23,7 +23,7 @@ This page will help you install and build your first React Native app. If you al -Assuming that you have [Node 10+](https://nodejs.org/en/download/) installed, you can use npm to install the Expo CLI command line utility: +Assuming that you have [Node 10 LTS](https://nodejs.org/en/download/) or greater installed, you can use npm to install the Expo CLI command line utility: ```sh npm install -g expo-cli @@ -40,21 +40,21 @@ npm start # you can also use: expo start This will start a development server for you. -## Running your React Native application +

    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. On Android, use the Expo app to scan the QR code from your terminal to open your project. On iOS, follow on-screen instructions to get a link. -### Modifying your app +

    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! +

    That's it!

    Congratulations! You've successfully run and modified your first React Native app.
    -## Now what? +

    Now what?

    Expo also has [docs](https://docs.expo.io) you can reference if you have questions specific to the tool. You can also ask for help at [Expo forums](https://forums.expo.io). @@ -67,54 +67,54 @@ If you have a problem with Expo, before creating a new issue, please see if ther If you're curious to learn more about React Native, continue on to the [Tutorial](tutorial.md). -### Running your app on a simulator or virtual device +

    Running your app on a simulator or virtual device

    -Expo CLI 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 or set up your Android development environment. +Expo CLI 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 "React Native CLI Quickstart" to learn how to install Xcode or 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 +

    Caveats

    Because you don't build any native code when using Expo 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, Expo is still a good way to get started. In that case you'll just need to "[eject](https://docs.expo.io/versions/latest/expokit/eject)" eventually to create your own native builds. If you do eject, the "Building Projects with Native Code" instructions will be required to continue working on your project. +If you know that you'll eventually need to include your own native code, Expo is still a good way to get started. In that case you'll just need to "[eject](https://docs.expo.io/versions/latest/expokit/eject)" eventually to create your own native builds. If you do eject, the "React Native CLI Quickstart" instructions will be required to continue working on your project. Expo CLI 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://docs.expo.io/versions/latest/sdk/#sdk-version) to find out what versions are supported. -If you're integrating React Native into an existing project, you'll want to skip Expo CLI 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. +If you're integrating React Native into an existing project, you'll want to skip Expo CLI and go directly to setting up the native build environment. Select "React Native CLI Quickstart" above for instructions on configuring a native build environment for React Native. -

    Follow these instructions if you need to build native code in your project. For example, if you are integrating React Native into an existing application, or if you "ejected" from Expo or Create React Native App, you'll need this section.

    +

    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 Expo, you'll need this section.

    The instructions are a bit different depending on your development operating system, and whether you want to start developing for iOS or Android. If you want to develop for both iOS and Android, that's fine - you just have to pick one to start with, since the setup is a bit different.
    Development OS: - - - +
    Target OS: - - +
    -## Unsupported +

    Unsupported

    -

    A Mac is required to build projects with native code for iOS. You can follow the Quick Start to learn how to build your app using Expo instead.

    +

    A Mac is required to build projects with native code for iOS. You can follow the Quick Start to learn how to build your app using Expo instead.

    -## Installing dependencies +

    Installing dependencies

    You will need Node, Watchman, the React Native command line interface, and Xcode. @@ -122,19 +122,19 @@ While you can use any editor of your choice to develop your app, you will need t -## Installing dependencies +

    Installing dependencies

    You will need Node, Watchman, the React Native command line interface, a JDK, and Android Studio. -## Installing dependencies +

    Installing dependencies

    You will need Node, the React Native command line interface, a JDK, and Android Studio. -## Installing dependencies +

    Installing dependencies

    You will need Node, the React Native command line interface, Python2, a JDK, and Android Studio. @@ -144,28 +144,33 @@ While you can use any editor of your choice to develop your app, you will need t -### Node, Watchman +

    Node, Watchman, JDK

    -We recommend installing Node and Watchman using [Homebrew](http://brew.sh/). Run the following commands in a Terminal after installing Homebrew: +We recommend installing Node, Watchman, and JDK using [Homebrew](http://brew.sh/). Run the following commands in a Terminal after installing Homebrew: ``` +brew install yarn brew install node brew install watchman +brew tap AdoptOpenJDK/openjdk +brew cask install adoptopenjdk8 ``` If you have already installed Node on your system, make sure it is Node 8.3 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. +If you have already installed JDK on your system, make sure it is JDK 8 or newer. + -### Node +

    Node

    Follow the [installation instructions for your Linux distribution](https://nodejs.org/en/download/package-manager/) to install Node 8.3 or newer. -### Node, Python2, JDK +

    Node, Python2, JDK

    We recommend installing Node and Python2 via [Chocolatey](https://chocolatey.org), a popular package manager for Windows. @@ -183,7 +188,7 @@ If you have already installed Node on your system, make sure it is Node 8.3 or n -### The React Native CLI +

    The React Native CLI

    Node comes with npm, which lets you install the React Native command line interface. @@ -197,7 +202,7 @@ npm install -g react-native-cli -### The React Native CLI +

    The React Native CLI

    Node comes with npm, which lets you install the React Native command line interface. @@ -211,33 +216,33 @@ npm install -g react-native-cli -### Xcode +

    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 9.4 or newer. -#### Command Line Tools +

    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](/react-native/docs/assets/GettingStartedXcodeCommandLineTools.png) - + -### Java Development Kit +

    Java Development Kit

    -React Native requires a recent version of the Java SE Development Kit (JDK). [Download and install Oracle JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) if needed. You can also use [OpenJDK 8](http://openjdk.java.net/install/) as an alternative. +React Native requires version 8 of the Java SE Development Kit (JDK). You may download and install [OpenJDK](http://openjdk.java.net) from [AdoptOpenJDK](https://adoptopenjdk.net/) or your system packager. You may also [Download and install Oracle JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) if desired. -### Android development environment +

    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. -#### 1. Install Android Studio +

    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: @@ -262,7 +267,7 @@ Then, click "Next" to install all of these components. Once setup has finalized and you're presented with the Welcome screen, proceed to the next step. -#### 2. Install the Android SDK +

    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 9 (Pie)` SDK in particular. Additional Android SDKs can be installed through the SDK Manager in Android Studio. @@ -289,13 +294,13 @@ Next, select the "SDK Tools" tab and check the box next to "Show Package Details Finally, click "Apply" to download and install the Android SDK and related build tools. -#### 3. Configure the ANDROID_HOME environment variable +

    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. -Add the following lines to your `$HOME/.bash_profile` config file: +Add the following lines to your `$HOME/.bash_profile` or `$HOME/.bashrc` config file: @@ -341,7 +346,7 @@ You can find the actual location of the SDK in the Android Studio "Preferences" Open a new Command Prompt window to ensure the new environment variable is loaded before proceeding to the next step. -#### 4. Add platform-tools to Path +

    4. Add platform-tools to Path

    Open the System pane under **System and Security** in the Windows Control Panel, then click on **Change settings...**. Open the **Advanced** tab and click on **Environment Variables...**. Select the **Path** variable, then click **Edit**. Click **New** and add the path to platform-tools to the list. @@ -353,7 +358,7 @@ c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk\platform-tools -### Watchman +

    Watchman

    Follow the [Watchman installation guide](https://facebook.github.io/watchman/docs/install.html#buildinstall) to compile and install Watchman from source. @@ -361,7 +366,7 @@ Follow the [Watchman installation guide](https://facebook.github.io/watchman/doc -## Creating a new application +

    Creating a new application

    Use the React Native command line interface to generate a new React Native project called "AwesomeProject": @@ -371,9 +376,9 @@ react-native init AwesomeProject This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Expo (or Create React Native App), or if you're adding iOS support to an existing React Native project (see [Platform Specific Code](platform-specific-code.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). -### [Optional] Using a specific version +

    [Optional] Using a specific version

    -If you want to start a new project with a specifc React Native version, you can use the `--version` argument: +If you want to start a new project with a specific React Native version, you can use the `--version` argument: ``` react-native init AwesomeProject --version X.XX.X @@ -385,7 +390,7 @@ react-native init AwesomeProject --version react-native@next -## Creating a new application +

    Creating a new application

    Use the React Native command line interface to generate a new React Native project called "AwesomeProject": @@ -395,9 +400,9 @@ 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](platform-specific-code.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). -### [Optional] Using a specific version +

    [Optional] Using a specific version

    -If you want to start a new project with a specifc React Native version, you can use the `--version` argument: +If you want to start a new project with a specific React Native version, you can use the `--version` argument: ``` react-native init AwesomeProject --version X.XX.X @@ -409,17 +414,17 @@ react-native init AwesomeProject --version react-native@next -## Preparing the Android device +

    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 +

    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](running-on-device.md). -### Using a virtual device +

    Using a virtual device

    If you use Android Studio to open `./AwesomeProject/android`, 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: @@ -445,7 +450,7 @@ Click "Next" then "Finish" to create your AVD. At this point you should be able -## Running your React Native application +

    Running your React Native application

    Run `react-native run-ios` inside your React Native project folder: @@ -458,17 +463,17 @@ You should see your new app running in the iOS Simulator shortly. ![AwesomeProject on iOS](/react-native/docs/assets/GettingStartediOSSuccess.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/). +`react-native run-ios` is just one way to run your app. You can also run it directly from within Xcode. > If you can't get this to work, see the [Troubleshooting](troubleshooting.md#content) page. -### Running on a device +

    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](running-on-device.md). -## Running your React Native application +

    Running your React Native application

    Run `react-native run-android` inside your React Native project folder: @@ -489,13 +494,13 @@ If everything is set up correctly, you should see your new app running in your A -`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/). +`react-native run-android` is just one way to run your app - you can also run it directly from within Android Studio. > If you can't get this to work, see the [Troubleshooting](troubleshooting.md#content) page. -### Modifying your app +

    Modifying your app

    Now that you have successfully run the app, let's modify it. @@ -511,7 +516,7 @@ Now that you have successfully run the app, let's modify it. -### Modifying your app +

    Modifying your app

    Now that you have successfully run the app, let's modify it. @@ -520,7 +525,7 @@ Now that you have successfully run the app, let's modify it. -### That's it! +

    That's it!

    Congratulations! You've successfully run and modified your first React Native app. @@ -528,7 +533,7 @@ Congratulations! You've successfully run and modified your first React Native ap -### That's it! +

    That's it!

    Congratulations! You've successfully run and modified your first React Native app. @@ -536,7 +541,7 @@ Congratulations! You've successfully run and modified your first React Native ap -## Now what? +

    Now what?

    - Turn on [Live Reload](debugging.md#reloading-javascript) in the Developer Menu. Your app will now reload automatically whenever you save any changes! @@ -546,7 +551,7 @@ If you're curious to learn more about React Native, continue on to the [Tutorial -## Now what? +

    Now what?

    - Turn on [Live Reload](debugging.md#reloading-javascript) in the Developer Menu. Your app will now reload automatically whenever you save any changes! diff --git a/website/versioned_docs/version-0.5/handling-text-input.md b/website/versioned_docs/version-0.5/handling-text-input.md index 70622bf5993..e7cd81c83d7 100644 --- a/website/versioned_docs/version-0.5/handling-text-input.md +++ b/website/versioned_docs/version-0.5/handling-text-input.md @@ -8,9 +8,9 @@ original_id: handling-text-input 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 "🍕🍕🍕". -```SnackPlayer +```SnackPlayer name=Handling%20Text%20Input import React, { Component } from 'react'; -import { AppRegistry, Text, TextInput, View } from 'react-native'; +import { Text, TextInput, View } from 'react-native'; export default class PizzaTranslator extends Component { constructor(props) { @@ -25,6 +25,7 @@ export default class PizzaTranslator extends Component { style={{height: 40}} placeholder="Type here to translate!" onChangeText={(text) => this.setState({text})} + value={this.state.text} /> {this.state.text.split(' ').map((word) => word && '🍕').join(' ')} @@ -33,9 +34,6 @@ export default class PizzaTranslator extends Component { ); } } - -// 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. diff --git a/website/versioned_docs/version-0.5/headless-js-android.md b/website/versioned_docs/version-0.5/headless-js-android.md index e26f0d6c3e5..7cfa4e67dba 100644 --- a/website/versioned_docs/version-0.5/headless-js-android.md +++ b/website/versioned_docs/version-0.5/headless-js-android.md @@ -67,8 +67,47 @@ service.putExtras(bundle); getApplicationContext().startService(service); ``` +## Retries + +By default, the headless JS task will not perform any retries. In order to do so, you need to create a `HeadlessJsRetryPolicy` and throw a specfic `Error`. + +`LinearCountingRetryPolicy` is an implementation of `HeadlessJsRetryPolicy` that allows you to specify a maximum number of retries with a fixed delay between each attempt. If that does not suit your needs then you can easily implement your own `HeadlessJsRetryPolicy`. These policies can simply be passed as an extra argument to the `HeadlessJsTaskConfig` constructor, e.g. + +```java +HeadlessJsRetryPolicy retryPolicy = new LinearCountingRetryPolicy( + 3, // Max number of retry attempts + 1000 // Delay between each retry attempt +); + +return new HeadlessJsTaskConfig( + 'SomeTaskName', + Arguments.fromBundle(extras), + 5000, + false, + retryPolicy +); +``` + +A retry attempt will only be made when a specific `Error` is thrown. Inside a headless JS task, you can import the error and throw it when a retry attempt is required. + +Example: + +```jsx +import {HeadlessJsTaskError} from 'HeadlessJsTask'; + +module.exports = async (taskData) => { + const condition = ...; + if (!condition) { + throw new HeadlessJsTaskError(); + } +}; +``` + +If you wish all errors to cause a retry attempt, you will need to catch them and throw the above error. + ## Caveats +- The function passed to `setTimeout` does not always behave as expected. Instead the function is called only when the application is launched again. If you just need to wait, use the retry functionality. - 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()`. diff --git a/website/versioned_docs/version-0.5/height-and-width.md b/website/versioned_docs/version-0.5/height-and-width.md index 95a7b6f9fbb..e478ba61d9a 100644 --- a/website/versioned_docs/version-0.5/height-and-width.md +++ b/website/versioned_docs/version-0.5/height-and-width.md @@ -10,9 +10,9 @@ A component's height and width determine its size on the screen. The simplest way to set the dimensions of a component is by adding a fixed `width` and `height` to style. All dimensions in React Native are unitless, and represent density-independent pixels. -```SnackPlayer +```SnackPlayer name=Height%20and%20Width import React, { Component } from 'react'; -import { AppRegistry, View } from 'react-native'; +import { View } from 'react-native'; export default class FixedDimensionsBasics extends Component { render() { @@ -25,9 +25,6 @@ export default class FixedDimensionsBasics extends Component { ); } } - -// 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. @@ -38,9 +35,9 @@ Use `flex` in a component's style to have the component expand and shrink dynami > 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. -```SnackPlayer +````SnackPlayer name=Flex%20Dimensions import React, { Component } from 'react'; -import { AppRegistry, View } from 'react-native'; +import { View } from 'react-native'; export default class FlexDimensionsBasics extends Component { render() { @@ -56,9 +53,7 @@ export default class FlexDimensionsBasics extends Component { ); } } - -// 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](flexbox.md). +```` diff --git a/website/versioned_docs/version-0.5/images.md b/website/versioned_docs/version-0.5/images.md index 169d3d12e0d..b5644f98d29 100644 --- a/website/versioned_docs/version-0.5/images.md +++ b/website/versioned_docs/version-0.5/images.md @@ -68,7 +68,7 @@ Note that image sources required this way include size (width, height) info for 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-config/src/defaults/defaults.js#L14-L44) 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#L68) for the full list of configuration options). +You can add support for other types by adding an [`assetExts` resolver option](https://facebook.github.io/metro/docs/en/configuration#assetexts) in your [Metro configuration](https://facebook.github.io/metro/docs/en/configuration). 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. @@ -163,7 +163,7 @@ In some cases you might only want to display an image if it is already in the lo ## Local Filesystem Images -See [CameraRoll](cameraroll.md) for an example of using local resources that are outside of `Images.xcassets`. +See [CameraRoll](https://github.com/react-native-community/react-native-cameraroll) for an example of using local resources that are outside of `Images.xcassets`. ### Best Camera Roll Image diff --git a/website/versioned_docs/version-0.5/integration-with-existing-apps.md b/website/versioned_docs/version-0.5/integration-with-existing-apps.md index 6a9b8f00f38..6fbb390f945 100644 --- a/website/versioned_docs/version-0.5/integration-with-existing-apps.md +++ b/website/versioned_docs/version-0.5/integration-with-existing-apps.md @@ -9,7 +9,7 @@ React Native is great when you are starting a new mobile app from scratch. Howev The specific steps are different depending on what platform you're targeting.
    -
      +
        @@ -165,24 +165,30 @@ 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', - '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 - 'RCTAnimation', # Needed for FlatList and animations running on native UI thread - # Add any other subspecs you want to use in your project - ] - # Explicitly include Yoga if you are using RN >= 0.42.0 + pod 'React', :path => '../node_modules/react-native/' + pod 'React-Core', :path => '../node_modules/react-native/React' + pod 'React-DevSupport', :path => '../node_modules/react-native/React' + pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook' + pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' + pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' + pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' + pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' + pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' + pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' + pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' + pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' + pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' + pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' + + pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' + pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' + pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' + pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' 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 ``` diff --git a/website/versioned_docs/version-0.5/javascript-environment.md b/website/versioned_docs/version-0.5/javascript-environment.md index 23d21f67617..92dc226aad9 100644 --- a/website/versioned_docs/version-0.5/javascript-environment.md +++ b/website/versioned_docs/version-0.5/javascript-environment.md @@ -9,7 +9,7 @@ original_id: javascript-environment When using React Native, you're going to be running your JavaScript code in two environments: - In most cases, React Native will use [JavaScriptCore](http://trac.webkit.org/wiki/JavaScriptCore), the JavaScript engine that powers Safari. Note that on iOS, JavaScriptCore does not use JIT due to the absence of writable executable memory in iOS apps. -- When using Chrome debugging, all JavaScript code runs within Chrome itself, communicating with native code via WebSockets. Chrome uses [V8](https://code.google.com/p/v8/) as its JavaScript engine. +- When using Chrome debugging, all JavaScript code runs within Chrome itself, communicating with native code via WebSockets. Chrome uses [V8](https://v8.dev/) as its JavaScript engine. While both environments are very similar, you may end up hitting some inconsistencies. We're likely going to experiment with other JavaScript engines in the future, so it's best to avoid relying on specifics of any runtime. @@ -48,16 +48,16 @@ ES8 Stage 3 -- [Object Spread](https://github.com/sebmarkbage/ecmascript-rest-spread): `var extended = { ...obj, a: 10 };` - -Stage 1 - +- [Object Spread](https://github.com/tc39/proposal-object-rest-spread): `var extended = { ...obj, a: 10 };` +- [Static class fields](https://github.com/tc39/proposal-static-class-features): `class CustomDate { static epoch = new CustomDate(0); }` - [Optional Chaining](https://github.com/tc39/proposal-optional-chaining): `var name = obj.user?.name;` Specific - [JSX](https://reactjs.org/docs/jsx-in-depth.html): `` -- [Flow](http://flowtype.org/): `function foo(x: ?number): string {};` +- [Flow](https://flowtype.org/): `function foo(x: ?number): string {};` +- [TypeScript](https://flowtype.org/): `function foo(x: number | undefined): string {};` +- [Babel Template](https://babeljs.io/docs/en/babel-template): allows AST templating ## Polyfills @@ -69,7 +69,6 @@ Browser - [CommonJS require](https://nodejs.org/docs/latest/api/modules.html) - [XMLHttpRequest, fetch](network.md#content) - [{set, clear}{Timeout, Interval, Immediate}, {request, cancel}AnimationFrame](timers.md#content) -- [navigator.geolocation](geolocation.md#content) ES6 diff --git a/website/versioned_docs/version-0.5/more-resources.md b/website/versioned_docs/version-0.5/more-resources.md index 0f195877cf3..938c2c28ae3 100644 --- a/website/versioned_docs/version-0.5/more-resources.md +++ b/website/versioned_docs/version-0.5/more-resources.md @@ -16,7 +16,7 @@ If you're looking for a library that does a specific thing, check out [Awesome R ## Examples -Try out apps from the [Showcase](/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. +Try out apps from the [Showcase](/react-native/showcase/) 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 also [open-sourced the code](https://github.com/fbsamples/f8app) and wrote up a [detailed series of tutorials](http://makeitopen.com/). This is useful if you want a more in-depth example that's more realistic than most sample apps out there. @@ -25,7 +25,7 @@ The folks who built the app for Facebook's F8 conference also [open-sourced the - 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](native-modules-ios.md), [Android](native-modules-android.md)) and Native UI Components ([iOS](native-components-ios.md), [Android](native-components-android.md)) if you are interested in extending native functionality. -- Looking for a pre-built component? Check [JS.coach](https://js.coach/react-native) or [Native Directory](https://native.directory/) to find what the community has been creating. +- Looking for a pre-built component? Check [JS.coach](https://js.coach/react-native) or [Native Directory](https://www.native.directory) to find what the community has been creating. ## Development Tools @@ -39,6 +39,6 @@ The folks who built the app for Facebook's F8 conference also [open-sourced the [Yoga](https://yogalayout.com/) is a stand-alone layout engine that extends beyond React Native and allows product engineers to build layouts quickly for multiple platforms with a highly optimized open source layout engine designed with speed, size, and ease of use in mind. -[Bugsnag](https://www.bugsnag.com/), [Microsoft App Center](https://appcenter.ms/), and [Sentry](https://sentry.io/welcome/) all provide excellent crash and error monitoring services for React and React Native apps. These services allow you to proactively monitor crashes and issues occuring on your apps in real time so you can fix them quickly and improve user experience. +[Bugsnag](https://www.bugsnag.com/), [Microsoft App Center](https://appcenter.ms/), and [Sentry](https://sentry.io/welcome/) all provide excellent crash and error monitoring services for React and React Native apps. These services allow you to proactively monitor crashes and issues occurring on your apps in real time so you can fix them quickly and improve user experience. The [React Developer Tools](debugging.md#react-developer-tools) are great for debugging React and React Native apps. diff --git a/website/versioned_docs/version-0.5/native-components-ios.md b/website/versioned_docs/version-0.5/native-components-ios.md index f55f5584bb6..15e3c60295b 100644 --- a/website/versioned_docs/version-0.5/native-components-ios.md +++ b/website/versioned_docs/version-0.5/native-components-ios.md @@ -383,6 +383,79 @@ class MyApp extends React.Component { } ``` +## Handling multiple native views + +A React Native view can have more than one child view in the view tree eg. + +```jsx + + + +
    - -
    - Target OS: - -
    - - - -

    Unsupported

    - -

    A Mac is required to build projects with native code for iOS. You can follow the Quick Start to learn how to build your app using Expo instead.

    - - - -

    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. - - - -

    Installing dependencies

    - -You will need Node, Watchman, the React Native command line interface, a JDK, and Android Studio. - - - -

    Installing dependencies

    - -You will need Node, the React Native command line interface, a JDK, and Android Studio. - - - -

    Installing dependencies

    - -You will need Node, the React Native command line interface, Python2, a JDK, and Android Studio. - - - -While you can use any editor of your choice to develop your app, you will need to install Android Studio in order to set up the necessary tooling to build your React Native app for Android. - - - -

    Node, Watchman, JDK

    - -We recommend installing Node, Watchman, and JDK using [Homebrew](http://brew.sh/). Run the following commands in a Terminal after installing Homebrew: - -``` -brew install yarn -brew install node -brew install watchman -brew tap AdoptOpenJDK/openjdk -brew cask install adoptopenjdk8 -``` - -If you have already installed Node on your system, make sure it is Node 8.3 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. - -If you have already installed JDK on your system, make sure it is JDK 8 or newer. - - - -

    Node

    - -Follow the [installation instructions for your Linux distribution](https://nodejs.org/en/download/package-manager/) to install Node 8.3 or newer. - - - -

    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 Node 8.3 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/). - - - -

    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`. - - - -

    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`. - - - -

    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 9.4 or newer. - -

    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](/react-native/docs/assets/GettingStartedXcodeCommandLineTools.png) - - - -

    Java Development Kit

    - -React Native requires version 8 of the Java SE Development Kit (JDK). You may download and install [OpenJDK](http://openjdk.java.net) from [AdoptOpenJDK](https://adoptopenjdk.net/) or your system packager. You may also [Download and install Oracle JDK 8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) if desired. - - - -

    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. - - - -

    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: - - - -- `Android SDK` -- `Android SDK Platform` -- `Performance (Intel ® HAXM)` ([See here for AMD](https://android-developers.googleblog.com/2018/07/android-emulator-amd-processor-hyper-v.html)) -- `Android Virtual Device` - - - -- `Android SDK` -- `Android SDK Platform` -- `Android Virtual Device` - - - -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 9 (Pie)` 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". - - - -![Android Studio Welcome](/react-native/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png) - - - -![Android Studio Welcome](/react-native/docs/assets/GettingStartedAndroidStudioWelcomeWindows.png) - - - -> 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 9 (Pie)` entry, then make sure the following items are checked: - -- `Android SDK Platform 28` -- `Intel x86 Atom_64 System Image` or `Google APIs Intel x86 Atom System Image` - -Next, select the "SDK Tools" tab and check the box next to "Show Package Details" here as well. Look for and expand the "Android SDK Build-Tools" entry, then make sure that `28.0.3` is selected. - -Finally, click "Apply" to download and install the Android SDK and related build tools. - -

    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. - - - -Add the following lines to your `$HOME/.bash_profile` or `$HOME/.bashrc` config file: - - - -``` -export ANDROID_HOME=$HOME/Library/Android/sdk -export PATH=$PATH:$ANDROID_HOME/emulator -export PATH=$PATH:$ANDROID_HOME/tools -export PATH=$PATH:$ANDROID_HOME/tools/bin -export PATH=$PATH:$ANDROID_HOME/platform-tools -``` - - - -``` -export ANDROID_HOME=$HOME/Android/Sdk -export PATH=$PATH:$ANDROID_HOME/emulator -export PATH=$PATH:$ANDROID_HOME/tools -export PATH=$PATH:$ANDROID_HOME/tools/bin -export PATH=$PATH:$ANDROID_HOME/platform-tools -``` - - - -> `.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**. - - - -Open the System pane under **System and Security** in the Windows 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](/react-native/docs/assets/GettingStartedAndroidEnvironmentVariableANDROID_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. - -

    4. Add platform-tools to Path

    - -Open the System pane under **System and Security** in the Windows Control Panel, then click on **Change settings...**. Open the **Advanced** tab and click on **Environment Variables...**. Select the **Path** variable, then click **Edit**. Click **New** and add the path to platform-tools to the list. - -The default location for this folder is: - -```powershell -c:\Users\YOUR_USERNAME\AppData\Local\Android\Sdk\platform-tools -``` - - - -

    Watchman

    - -Follow the [Watchman installation guide](https://facebook.github.io/watchman/docs/install.html#buildinstall) 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 and increased compatibility in certain edge cases (translation: you may be able to get by without installing this, but your mileage may vary; installing this now may save you from a headache later). - - - -

    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 Expo (or Create React Native App), or if you're adding iOS support to an existing React Native project (see [Platform Specific Code](platform-specific-code.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). - -

    [Optional] Using a specific version

    - -If you want to start a new project with a specific React Native version, you can use the `--version` argument: - -``` -react-native init AwesomeProject --version X.XX.X -``` - -``` -react-native init AwesomeProject --version react-native@next -``` - - - -

    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](platform-specific-code.md)). You can also use a third-party CLI to init your React Native app, such as [Ignite CLI](https://github.com/infinitered/ignite). - -

    [Optional] Using a specific version

    - -If you want to start a new project with a specific React Native version, you can use the `--version` argument: - -``` -react-native init AwesomeProject --version X.XX.X -``` - -``` -react-native init AwesomeProject --version react-native@next -``` - - - -

    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](running-on-device.md). - -

    Using a virtual device

    - -If you use Android Studio to open `./AwesomeProject/android`, 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](/react-native/docs/assets/GettingStartedAndroidStudioAVD.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", then select the **Pie** API Level 28 image. - - - -> 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. - - - -> If you don't have HAXM installed, click on "Install HAXM" or follow [these instructions](https://github.com/intel/haxm/wiki/Installation-Instructions-on-Windows) to set it up, then go back to the AVD Manager. - - - -> If you don't have HAXM installed, follow [these instructions](https://github.com/intel/haxm/wiki/Installation-Instructions-on-macOS) to set it up, then go back to the AVD Manager. - - - -Click "Next" then "Finish" to create your AVD. At this point you should be able to click on the green triangle button next to your AVD to launch it, then proceed to the next step. - - - -

    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](/react-native/docs/assets/GettingStartediOSSuccess.png) - -`react-native run-ios` is just one way to run your app. You can also run it directly from within Xcode. - -> If you can't get this to work, see the [Troubleshooting](troubleshooting.md#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](running-on-device.md). - - - -

    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. - - - -![AwesomeProject on Android](/react-native/docs/assets/GettingStartedAndroidSuccessMacOS.png) - - - -![AwesomeProject on Android](/react-native/docs/assets/GettingStartedAndroidSuccessWindows.png) - - - -`react-native run-android` is just one way to run your app - you can also run it directly from within Android Studio. - -> If you can't get this to work, see the [Troubleshooting](troubleshooting.md#content) page. - - - -

    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. -- Hit `⌘R` in your iOS Simulator to reload the app and see your changes! - - - -- 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! - - - -

    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! - - - -

    That's it!

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

    That's it!

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

    Now what?

    - -- Turn on [Live Reload](debugging.md#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](integration-with-existing-apps.md). - -If you're curious to learn more about React Native, continue on to the [Tutorial](tutorial.md). - - - -

    Now what?

    - -- Turn on [Live Reload](debugging.md#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](integration-with-existing-apps.md). - -If you're curious to learn more about React Native, continue on to the [Tutorial](tutorial.md). diff --git a/website/versioned_docs/version-0.60/handling-text-input.md b/website/versioned_docs/version-0.60/handling-text-input.md deleted file mode 100644 index 3790f2d002e..00000000000 --- a/website/versioned_docs/version-0.60/handling-text-input.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -id: version-0.60-handling-text-input -title: Handling Text Input -original_id: handling-text-input ---- - -[`TextInput`](textinput.md#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 "🍕🍕🍕". - -```SnackPlayer name=Handling%20Text%20Input -import React, { Component } from 'react'; -import { Text, TextInput, View } from 'react-native'; - -export default class PizzaTranslator extends Component { - constructor(props) { - super(props); - this.state = {text: ''}; - } - - render() { - return ( - - this.setState({text})} - value={this.state.text} - /> - - {this.state.text.split(' ').map((word) => word && '🍕').join(' ')} - - - ); - } -} -``` - -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://reactjs.org/docs/forms.html#controlled-components), or the [reference docs for TextInput](textinput.md). - -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](handling-touches.md). diff --git a/website/versioned_docs/version-0.60/headless-js-android.md b/website/versioned_docs/version-0.60/headless-js-android.md deleted file mode 100644 index 66b5abf1081..00000000000 --- a/website/versioned_docs/version-0.60/headless-js-android.md +++ /dev/null @@ -1,185 +0,0 @@ ---- -id: version-0.60-headless-js-android -title: Headless JS -original_id: headless-js-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: - -```jsx -AppRegistry.registerHeadlessTask('SomeTaskName', () => require('SomeTaskName')); -``` - -Then, in `SomeTaskName.js`: - -```jsx -module.exports = async (taskData) => { - // do stuff -}; -``` - -You can do anything in your task such as network requests, timers and so on, as long as it doesn't touch UI. Once your task completes (i.e. the promise is resolved), React Native will go into "paused" mode (unless there are other tasks running, or there is a foreground app). - -## 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: - -``` - -``` - -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); -``` - -## Retries - -By default, the headless JS task will not perform any retries. In order to do so, you need to create a `HeadlessJsRetryPolicy` and throw a specfic `Error`. - -`LinearCountingRetryPolicy` is an implementation of `HeadlessJsRetryPolicy` that allows you to specify a maximum number of retries with a fixed delay between each attempt. If that does not suit your needs then you can easily implement your own `HeadlessJsRetryPolicy`. These policies can simply be passed as an extra argument to the `HeadlessJsTaskConfig` constructor, e.g. - -```java -HeadlessJsRetryPolicy retryPolicy = new LinearCountingRetryPolicy( - 3, // Max number of retry attempts - 1000 // Delay between each retry attempt -); - -return new HeadlessJsTaskConfig( - 'SomeTaskName', - Arguments.fromBundle(extras), - 5000, - false, - retryPolicy -); -``` - -A retry attempt will only be made when a specific `Error` is thrown. Inside a headless JS task, you can import the error and throw it when a retry attempt is required. - -Example: - -```jsx -import {HeadlessJsTaskError} from 'HeadlessJsTask'; - -module.exports = async (taskData) => { - const condition = ...; - if (!condition) { - throw new HeadlessJsTaskError(); - } -}; -``` - -If you wish all errors to cause a retry attempt, you will need to catch them and throw the above error. - -## Caveats - -- The function passed to `setTimeout` does not always behave as expected. Instead the function is called only when the application is launched again. If you just need to wait, use the retry functionality. -- 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 - - - - - -``` - -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 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) diff --git a/website/versioned_docs/version-0.60/height-and-width.md b/website/versioned_docs/version-0.60/height-and-width.md deleted file mode 100644 index ed0f86dc8c6..00000000000 --- a/website/versioned_docs/version-0.60/height-and-width.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -id: version-0.60-height-and-width -title: Height and Width -original_id: height-and-width ---- - -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. - -```SnackPlayer name=Height%20and%20Width -import React, { Component } from 'react'; -import { View } from 'react-native'; - -export default class FixedDimensionsBasics extends Component { - render() { - return ( - - - - - - ); - } -} -``` - -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 other components 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. - -````SnackPlayer name=Flex%20Dimensions -import React, { Component } from 'react'; -import { 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`? - - - - - - ); - } -} -``` - -After you can control a component's size, the next step is to [learn how to lay it out on the screen](flexbox.md). -```` diff --git a/website/versioned_docs/version-0.60/images.md b/website/versioned_docs/version-0.60/images.md deleted file mode 100644 index 5392c803970..00000000000 --- a/website/versioned_docs/version-0.60/images.md +++ /dev/null @@ -1,223 +0,0 @@ ---- -id: version-0.60-images -title: Images -original_id: images ---- - -## 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: - -```jsx - -``` - -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.png - ├── check@2x.png - └── check@3x.png -``` - -...and `button.js` code contains: - -```jsx - -``` - -...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. - -```jsx -// GOOD -; - -// BAD -var icon = this.props.active ? 'my-icon-active' : 'my-icon-inactive'; -; - -// GOOD -var icon = this.props.active - ? require('./my-icon-active.png') - : require('./my-icon-inactive.png'); -; -``` - -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-config/src/defaults/defaults.js#L14-L44) for the full list. - -You can add support for other types by adding an [`assetExts` resolver option](https://facebook.github.io/metro/docs/en/configuration#assetexts) in your [Metro configuration](https://facebook.github.io/metro/docs/en/configuration). - -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: - -```jsx - -``` - -For images in the Android assets folder, use the `asset:/` scheme: - -```jsx - -``` - -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](running-on-device.md#app-transport-security) requirements on iOS. - -```jsx -// GOOD - - -// BAD - -``` - -### 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: - -```jsx - -``` - -## 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. - -```jsx -// include at least width and height! - -``` - -### 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. - -```jsx - -``` - -## Local Filesystem Images - -See [CameraRoll](https://github.com/react-native-community/react-native-cameraroll) 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: - -```jsx -{"__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. - -```jsx - -``` - -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 `` component, which has the same props as ``, and add whatever children to it you would like to layer on top of it. - -You might not want to use `` in some cases, since the implementation is very simple. Refer to ``'s [documentation](imagebackground.md) for more insight, and create your own custom component when needed. - -```jsx -return ( - - Inside - -); -``` - -Note that you must specify some width and height style attributes. - -## 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. diff --git a/website/versioned_docs/version-0.60/integration-with-existing-apps.md b/website/versioned_docs/version-0.60/integration-with-existing-apps.md deleted file mode 100644 index 75e1345a4de..00000000000 --- a/website/versioned_docs/version-0.60/integration-with-existing-apps.md +++ /dev/null @@ -1,799 +0,0 @@ ---- -id: version-0.60-integration-with-existing-apps -title: Integration with Existing Apps -original_id: integration-with-existing-apps ---- - -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. - -
    -
      - - - -
    -
    - - - -## Key Concepts - - - -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. - - - -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. - - - -## Prerequisites - - - -Follow the instructions for building apps with native code from the [Getting Started guide](getting-started.md) 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. - - - -Follow the instructions for building apps with native code from the [Getting Started guide](getting-started.md) 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 an `/android` subfolder. - - - -### 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": "yarn react-native start" - } -} -``` - -Next, make sure you have [installed the yarn package manager](https://yarnpkg.com/lang/en/docs/install/). - -Install the `react` and `react-native` packages. Open a terminal or command prompt, then navigate to the directory with your `package.json` file and run: - -``` -$ yarn add react-native -``` - -This will print a message similar to the following (scroll up in the yarn output to see it): - -> warning "react-native@0.52.2" has unmet peer dependency "react@16.2.0". - -This is OK, it means we also need to install React: - -``` -$ yarn add react@version_printed_above -``` - -Yarn has created a new `/node_modules` folder. This folder stores all the JavaScript dependencies required to build your project. - -Add `node_modules/` to your `.gitignore` file. - - - -### 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. - - - -## Adding React Native to your app - - - -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. - - - -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. - - - -![Before RN Integration](/react-native/docs/assets/react-native-existing-app-integration-ios-before.png) - -### Command Line Tools for Xcode - -Install the Command Line Tools. Choose "Preferences..." in 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](/react-native/docs/assets/GettingStartedXcodeCommandLineTools.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 `` elements), then you will need the `RCTText` `subspec`. If you want the `Image` library (e.g., for `` 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: - - - -``` -# 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/' - pod 'React-Core', :path => '../node_modules/react-native/React' - pod 'React-DevSupport', :path => '../node_modules/react-native/React' - pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook' - pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' - pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' - pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' - pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' - pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' - pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' - pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' - pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' - pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' - pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket' - - pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' - pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' - pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' - pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' - pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga' - - 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 -``` - - - -``` -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 -``` - - - -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. -``` - -> If this fails with errors mentioning `xcrun`, make sure that in Xcode in Preferences > Locations the Command Line Tools are assigned. - - - -> 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)`. - - - -### 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 `` component within a styled `` - -```jsx -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) => ( - - {score.name}:{score.value} - {'\n'} - - )); - return ( - - 2048 High Scores! - {contents} - - ); - } -} - -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](/react-native/docs/assets/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. - - - -First `import` the `RCTRootView` header. - -```objectivec -#import -``` - -> 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`. - - - -First `import` the `React` library. - -```jsx -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`. - - - -> 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. - - - -> 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. - - - -##### 3. Wire Up - -Wire up the new link in the main menu to the newly added event handler method. - -![Event Path](/react-native/docs/assets/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 -NSAppTransportSecurity - - NSExceptionDomains - - localhost - - NSTemporaryExceptionAllowsInsecureHTTPLoads - - - - -``` - -> 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](/react-native/docs/assets/react-native-add-react-native-integration-example-home-screen.png) - -Here is the _React Native_ high score screen: - -![High Scores](/react-native/docs/assets/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 - - - -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). - - - -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). - - - -## Adding React Native to your app - -### Configuring maven - -Add the React Native dependency to your app's `build.gradle` file: - -```gradle -dependencies { - implementation 'com.android.support:appcompat-v7:27.1.1' - ... - implementation "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, above other maven repositories: - -```gradle -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 shouldn’t 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`: - - - -If you need to access to the `DevSettingsActivity` add to your `AndroidManifest.xml`: - - - -This is only used in dev mode when reloading JavaScript from the development server, so you can strip this in release builds if you need to. - -### Cleartext Traffic (API level 28+) - -> Starting with Android 9 (API level 28), cleartext traffic is disabled by default; this prevents your application from connecting to the React Native packager. The changes below allow cleartext traffic in debug builds. - -#### 1. Apply the `usesCleartextTraffic` option to your Debug `AndroidManifest.xml` - -```xml - - - - - -``` - -This is not required for Release builds. - -To learn more about Network Security Config and the cleartext traffic policy [see this link](https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted). - -### 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 `` component within a styled ``: - -```jsx -import React from 'react'; -import {AppRegistry, StyleSheet, Text, View} from 'react-native'; - -class HelloWorld extends React.Component { - render() { - return ( - - Hello, World - - ); - } -} -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 permission `android.permission.SYSTEM_ALERT_WINDOW` enabled for the development build. You can check this 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 (Android M), the user needs to approve it. This can be achieved by adding the following code to your Activity's in `onCreate()` method. - -```java -private final int OVERLAY_PERMISSION_REQ_CODE = 1; // Choose any value - -... - -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. Also, for integrating Native Modules which use `startActivityForResult`, we need to pass the result to the `onActivityResult` method of our `ReactInstanceManager` instance. - -```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 - } - } - } - mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data ); -} -``` - -#### The Magic: `ReactRootView` - -Let's add some native code in order to start the React Native runtime and tell it to render our JS component. 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()) - .setCurrentActivity(this) - .setBundleAssetName("index.android.bundle") - .setJSMainModulePath("index") - .addPackage(new MainReactPackage()) - .setUseDeveloperSupport(BuildConfig.DEBUG) - .setInitialLifecycleState(LifecycleState.RESUMED) - .build(); - // The string here (e.g. "MyReactNativeApp") has to match - // the string in AppRegistry.registerComponent() in index.js - 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 (it’s the first argument to the `AppRegistry.registerComponent()` method). - -If you are using Android Studio, use `Alt + Enter` to add all missing imports in your MyReactActivity class. Be careful to use your package’s `BuildConfig` and not the one from the `facebook` package. - -We need set the theme of `MyReactActivity` to `Theme.AppCompat.Light.NoActionBar` because some React Native UI components rely on this theme. - -```xml - - -``` - -> A `ReactInstanceManager` can be shared by 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 to the `ReactInstanceManager` and `ReactRootView`: - -```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); - } - if (mReactRootView != null) { - mReactRootView.unmountReactApplication(); - } -} -``` - -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 the back button 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: - -``` -$ yarn 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](/react-native/docs/assets/EmbeddedAppAndroid.png) - -### Creating a release build in Android Studio - -You can use Android Studio to create your release builds too! It’s as easy as creating release builds of your previously-existing native Android app. There’s just one additional step, which you’ll have to do before every release build. You need to execute the following to create a React Native bundle, which will be included with your native Android app: - -``` -$ 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/ -``` - -> Don’t forget to replace the paths with correct ones and create the assets folder if it doesn’t exist. - -Now just create a release build of your native app from within Android Studio as usual and you should be good to go! - - - -### Now what? - -At this point you can continue developing your app as usual. Refer to our [debugging](debugging.md) and [deployment](running-on-device.md) docs to learn more about working with React Native. diff --git a/website/versioned_docs/version-0.60/javascript-environment.md b/website/versioned_docs/version-0.60/javascript-environment.md deleted file mode 100644 index 25473b10a9e..00000000000 --- a/website/versioned_docs/version-0.60/javascript-environment.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -id: version-0.60-javascript-environment -title: JavaScript Environment -original_id: javascript-environment ---- - -## JavaScript Runtime - -When using React Native, you're going to be running your JavaScript code in two environments: - -- In most cases, React Native will use [JavaScriptCore](http://trac.webkit.org/wiki/JavaScriptCore), the JavaScript engine that powers Safari. Note that on iOS, JavaScriptCore does not use JIT due to the absence of writable executable memory in iOS apps. -- When using Chrome debugging, all JavaScript code runs within Chrome itself, communicating with native code via WebSockets. Chrome uses [V8](https://v8.dev/) as its JavaScript engine. - -While both environments are very similar, you may end up hitting some inconsistencies. We're likely going to experiment with other JavaScript 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. - -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. - -A full list of React Native's enabled transformations can be found in [metro-react-native-babel-preset](https://github.com/facebook/metro/tree/master/packages/metro-react-native-babel-preset). - -ES5 - -- Reserved Words: `promise.catch(function() { });` - -ES6 - -- [Arrow functions](http://babeljs.io/docs/learn-es2015/#arrows): ` 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 ; } }` -- [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}`; `` - -ES8 - -- [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(); };` - -Stage 3 - -- [Object Spread](https://github.com/tc39/proposal-object-rest-spread): `var extended = { ...obj, a: 10 };` -- [Static class fields](https://github.com/tc39/proposal-static-class-features): `class CustomDate { static epoch = new CustomDate(0); }` -- [Optional Chaining](https://github.com/tc39/proposal-optional-chaining): `var name = obj.user?.name;` - -Specific - -- [JSX](https://reactjs.org/docs/jsx-in-depth.html): `` -- [Flow](https://flowtype.org/): `function foo(x: ?number): string {};` -- [TypeScript](https://flowtype.org/): `function foo(x: number | undefined): string {};` -- [Babel Template](https://babeljs.io/docs/en/babel-template): allows AST templating - -## Polyfills - -Many standards functions are also available on all the supported JavaScript runtimes. - -Browser - -- [console.{log, warn, error, info, trace, table, group, groupEnd}](https://developer.chrome.com/devtools/docs/console-api) -- [CommonJS require](https://nodejs.org/docs/latest/api/modules.html) -- [XMLHttpRequest, fetch](network.md#content) -- [{set, clear}{Timeout, Interval, Immediate}, {request, cancel}AnimationFrame](timers.md#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/repeat), [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)} - -ES7 - -- Array.prototype.{[includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)} - -ES8 - -- 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__` diff --git a/website/versioned_docs/version-0.60/more-resources.md b/website/versioned_docs/version-0.60/more-resources.md deleted file mode 100644 index c2061248e6a..00000000000 --- a/website/versioned_docs/version-0.60/more-resources.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -id: version-0.60-more-resources -title: More Resources -original_id: more-resources ---- - -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](/react-native/showcase/) 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 also [open-sourced the code](https://github.com/fbsamples/f8app) and wrote up a [detailed series of tutorials](http://makeitopen.com/). This is useful if you want a more in-depth example that's more realistic than most sample apps out there. - -## Extending 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](native-modules-ios.md), [Android](native-modules-android.md)) and Native UI Components ([iOS](native-components-ios.md), [Android](native-components-android.md)) if you are interested in extending native functionality. -- Looking for a pre-built component? Check [JS.coach](https://js.coach/react-native) or [Native Directory](https://www.native.directory) to find what the community has been creating. - -## 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. - -[App Center](https://appcenter.ms/) is a service from Microsoft that makes it easy to deploy live updates to your React Native app. If you don't like going through the app store process to deploy little tweaks, and you also don't like setting up your own backend, give App Center a try. - -[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. - -[Yoga](https://yogalayout.com/) is a stand-alone layout engine that extends beyond React Native and allows product engineers to build layouts quickly for multiple platforms with a highly optimized open source layout engine designed with speed, size, and ease of use in mind. - -[Bugsnag](https://www.bugsnag.com/), [Microsoft App Center](https://appcenter.ms/), and [Sentry](https://sentry.io/welcome/) all provide excellent crash and error monitoring services for React and React Native apps. These services allow you to proactively monitor crashes and issues occurring on your apps in real time so you can fix them quickly and improve user experience. - -The [React Developer Tools](debugging.md#react-developer-tools) are great for debugging React and React Native apps. diff --git a/website/versioned_docs/version-0.60/native-components-ios.md b/website/versioned_docs/version-0.60/native-components-ios.md deleted file mode 100644 index d1457705995..00000000000 --- a/website/versioned_docs/version-0.60/native-components-ios.md +++ /dev/null @@ -1,512 +0,0 @@ ---- -id: version-0.60-native-components-ios -title: Native UI Components -original_id: native-components-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 - -#import - -@interface RNTMapManager : RCTViewManager -@end - -@implementation RNTMapManager - -RCT_EXPORT_MODULE(RNTMap) - -- (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: - -```jsx -// MapView.js - -import { requireNativeComponent } from 'react-native'; - -// requireNativeComponent automatically resolves 'RNTMap' to 'RNTMapManager' -module.exports = requireNativeComponent('RNTMap'); - -// MyApp.js - -import MapView from './MapView.js'; - -... - -render() { - return ; -} -``` - -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. - -```jsx - render() { - return ; - } -``` - -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: - -```jsx -// MyApp.js - -``` - -To document the properties (and which values they accept) of our MapView component we'll add a wrapper component and document the interface with React `PropTypes`: - -```jsx -// MapView.js -import PropTypes from 'prop-types'; -import React from 'react'; -import {requireNativeComponent} from 'react-native'; - -class MapView extends React.Component { - render() { - return ; - } -} - -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 `requireNativeComponent`'s second argument from `null` to the new `MapView` wrapper component. This allows the infrastructure to verify that the propTypes match the native props in order to reduce the chances of mismatches between the Objective-C and JavaScript 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 -#import -#import -#import - -@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: - -```jsx -// 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 ( - - ); -} -``` - -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. - -```jsx -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 - -#import - -@interface RNTMapView: MKMapView - -@property (nonatomic, copy) RCTBubblingEventBlock onRegionChange; - -@end - -// RNTMapView.m - -#import "RNTMapView.h" - -@implementation RNTMapView - -@end -``` - -Note that all `RCTBubblingEventBlock` must be prefixed with `on`. 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 -#import - -#import "RNTMapView.h" -#import "RCTConvert+Mapkit.m" - -@interface RNTMapManager : RCTViewManager -@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: - -```jsx -// MapView.js - -class MapView extends React.Component { - _onRegionChange = (event) => { - if (!this.props.onRegionChange) { - return; - } - - // process raw event... - this.props.onRegionChange(event.nativeEvent); - } - render() { - return ( - - ); - } -} -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 ( - - ); - } -} -``` - -## Handling multiple native views - -A React Native view can have more than one child view in the view tree eg. - -```jsx - - - - (#1269) --- docs/getting-started.md | 10 +++++----- website/versioned_docs/version-0.5/getting-started.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index f23f4250a78..ae4553671d4 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -91,17 +91,17 @@ The instructions are a bit different depending on your development operating sys
    Development OS: - + +
    Target OS: - +
    diff --git a/website/versioned_docs/version-0.5/getting-started.md b/website/versioned_docs/version-0.5/getting-started.md index c2e04056c11..d3d0c8ac85d 100644 --- a/website/versioned_docs/version-0.5/getting-started.md +++ b/website/versioned_docs/version-0.5/getting-started.md @@ -92,17 +92,17 @@ The instructions are a bit different depending on your development operating sys
    Development OS: - + +
    Target OS: - +
    From 2ed6793299ac9f2054eac13bc2f35ec7db83a8cf Mon Sep 17 00:00:00 2001 From: Nicolas Charpentier Date: Fri, 13 Sep 2019 16:10:06 -0400 Subject: [PATCH 19/26] Republish 0.60 (#1270) * Republish 0.60 * Prettify --- docs/native-modules-android.md | 1 - docs/navigation.md | 2 +- website/versionedDocsBlacklist.json | 3 +- .../version-0.5/components-and-apis.md | 244 +++++++++++------- .../version-0.5/height-and-width.md | 3 +- .../version-0.5/native-modules-android.md | 49 ++-- .../versioned_docs/version-0.5/navigation.md | 11 +- .../optimizing-flatlist-configuration.md | 10 +- website/versioned_docs/version-0.60/hermes.md | 4 +- .../version-0.60/inputaccessoryview.md | 2 +- .../version-0.60/out-of-tree-platforms.md | 1 + .../version-0.60/refreshcontrol.md | 81 +++--- .../version-0.60/safeareaview.md | 23 +- .../versioned_docs/version-0.60/scrollview.md | 40 +++ .../version-0.60/sectionlist.md | 101 ++++++-- 15 files changed, 376 insertions(+), 199 deletions(-) rename website/versioned_docs/{version-0.60 => version-0.5}/optimizing-flatlist-configuration.md (96%) diff --git a/docs/native-modules-android.md b/docs/native-modules-android.md index 5932c3a1c8e..82d5fca3ddd 100644 --- a/docs/native-modules-android.md +++ b/docs/native-modules-android.md @@ -338,7 +338,6 @@ import { NativeEventEmitter, NativeModules } from 'react-native'; } ``` - ### 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, diff --git a/docs/navigation.md b/docs/navigation.md index 5bedc57ca32..651f8d3a24b 100644 --- a/docs/navigation.md +++ b/docs/navigation.md @@ -39,7 +39,7 @@ Then you can quickly create an app with a home screen and a profile screen: ```jsx import {createAppContainer} from 'react-navigation'; -import {createStackNavigator} from 'react-navigation-stack' +import {createStackNavigator} from 'react-navigation-stack'; const MainNavigator = createStackNavigator({ Home: {screen: HomeScreen}, diff --git a/website/versionedDocsBlacklist.json b/website/versionedDocsBlacklist.json index 3652422625a..21be57b3d29 100644 --- a/website/versionedDocsBlacklist.json +++ b/website/versionedDocsBlacklist.json @@ -43,5 +43,6 @@ "native-components-android", "headless-js-android", "signed-apk-android", - "removing-default-permissions" + "removing-default-permissions", + "optimizing-flatlist-configuration" ] diff --git a/website/versioned_docs/version-0.5/components-and-apis.md b/website/versioned_docs/version-0.5/components-and-apis.md index af38cd9a26a..202fbafa327 100644 --- a/website/versioned_docs/version-0.5/components-and-apis.md +++ b/website/versioned_docs/version-0.5/components-and-apis.md @@ -21,28 +21,40 @@ Most apps will end up using one of these basic components. You'll want to get yo
    -

    View

    -

    The most fundamental component for building a UI.

    + +

    View

    +

    The most fundamental component for building a UI.

    +
    -

    Text

    -

    A component for displaying text.

    + +

    Text

    +

    A component for displaying text.

    +
    -

    Image

    -

    A component for displaying images.

    + +

    Image

    +

    A component for displaying images.

    +
    -

    TextInput

    -

    A component for inputting text into the app via a keyboard.

    + +

    TextInput

    +

    A component for inputting text into the app via a keyboard.

    +
    -

    ScrollView

    -

    Provides a scrolling container that can host multiple components and views.

    + +

    ScrollView

    +

    Provides a scrolling container that can host multiple components and views.

    +
    -

    StyleSheet

    -

    Provides an abstraction layer similar to CSS stylesheets.

    + +

    StyleSheet

    +

    Provides an abstraction layer similar to CSS stylesheets.

    +
    @@ -52,35 +64,47 @@ Render common user interface controls on any platform using the following compon
    -

    Button

    -

    A basic button component for handling touches that should render nicely on any platform.

    + +

    Button

    +

    A basic button component for handling touches that should render nicely on any platform.

    +
    -

    Picker

    -

    Renders the native picker component on iOS and Android.

    + +

    Picker

    +

    Renders the native picker component on iOS and Android.

    +
    -

    Slider

    -

    A component used to select a single value from a range of values.

    + +

    Slider

    +

    A component used to select a single value from a range of values.

    +
    -

    Switch

    -

    Renders a boolean input.

    + +

    Switch

    +

    Renders a boolean input.

    +
    ## 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. +Unlike the more generic [`ScrollView`](./scrollview.md), 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.
    -

    FlatList

    -

    A component for rendering performant scrollable lists.

    + +

    FlatList

    +

    A component for rendering performant scrollable lists.

    +
    -

    SectionList

    -

    Like FlatList, but for sectioned lists.

    + +

    SectionList

    +

    Like FlatList, but for sectioned lists.

    +
    @@ -90,36 +114,46 @@ Many of the following components provide wrappers for commonly used UIKit classe
    -

    ActionSheetIOS

    -

    API to display an iOS action sheet or share sheet.

    + +

    ActionSheetIOS

    +

    API to display an iOS action sheet or share sheet.

    +
    -

    AlertIOS

    -

    Create an iOS alert dialog with a message or create a prompt for user input.

    + +

    AlertIOS

    +

    Create an iOS alert dialog with a message or create a prompt for user input.

    +
    -

    PushNotificationIOS

    -

    Handle push notifications for your app, including permission handling and icon badge number.

    + +

    PushNotificationIOS

    +

    Handle push notifications for your app, including permission handling and icon badge number.

    +
    -

    SegmentedControlIOS

    -

    Renders a UISegmentedControl on iOS.

    -
    -
    @@ -129,40 +163,58 @@ Many of the following components provide wrappers for commonly used Android clas
    -

    BackHandler

    -

    Detect hardware button presses for back navigation.

    + +

    BackHandler

    +

    Detect hardware button presses for back navigation.

    +
    -

    PermissionsAndroid

    -

    Provides access to the permissions model introduced in Android M.

    + +

    PermissionsAndroid

    +

    Provides access to the permissions model introduced in Android M.

    +
    -

    ViewPagerAndroid

    -

    Container that allows to flip left and right between child views.

    + +

    ViewPagerAndroid

    +

    Container that allows to flip left and right between child views.

    +
    @@ -172,51 +224,69 @@ These components may come in handy for certain applications. For an exhaustive l
    -

    ActivityIndicator

    -

    Displays a circular loading indicator.

    -
    -
    -

    Alert

    -

    Launches an alert dialog with the specified title and message.

    + +

    ActivityIndicator

    +

    Displays a circular loading indicator.

    +
    -

    Animated

    -

    A library for creating fluid, powerful animations that are easy to build and maintain.

    + +

    Alert

    +

    Launches an alert dialog with the specified title and message.

    +
    -

    Clipboard

    -

    Provides an interface for setting and getting content from the clipboard on both iOS and Android.

    + +

    Animated

    +

    A library for creating fluid, powerful animations that are easy to build and maintain.

    +
    -

    KeyboardAvoidingView

    -

    Provides a view that moves out of the way of the virtual keyboard automatically.

    + +

    Dimensions

    +

    Provides an interface for getting device dimensions.

    +
    -

    Linking

    -

    Provides a general interface to interact with both incoming and outgoing app links.

    + +

    KeyboardAvoidingView

    +

    Provides a view that moves out of the way of the virtual keyboard automatically.

    +
    -

    Modal

    -

    Provides a simple way to present content above an enclosing view.

    + +

    Linking

    +

    Provides a general interface to interact with both incoming and outgoing app links.

    +
    -

    RefreshControl

    -

    This component is used inside a ScrollView to add pull to refresh functionality.

    + +

    PixelRatio

    +

    Provides access to the device pixel density.

    +
    -

    WebView

    -

    A component that renders web content in a native view.

    + +

    StatusBar

    +

    Component to control the app status bar.

    +
    diff --git a/website/versioned_docs/version-0.5/height-and-width.md b/website/versioned_docs/version-0.5/height-and-width.md index e478ba61d9a..29b63956bf6 100644 --- a/website/versioned_docs/version-0.5/height-and-width.md +++ b/website/versioned_docs/version-0.5/height-and-width.md @@ -35,7 +35,7 @@ Use `flex` in a component's style to have the component expand and shrink dynami > 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. -````SnackPlayer name=Flex%20Dimensions +```SnackPlayer name=Flex%20Dimensions import React, { Component } from 'react'; import { View } from 'react-native'; @@ -56,4 +56,3 @@ export default class FlexDimensionsBasics extends Component { ``` After you can control a component's size, the next step is to [learn how to lay it out on the screen](flexbox.md). -```` diff --git a/website/versioned_docs/version-0.5/native-modules-android.md b/website/versioned_docs/version-0.5/native-modules-android.md index 6f9e3488886..d5ec5ca9045 100644 --- a/website/versioned_docs/version-0.5/native-modules-android.md +++ b/website/versioned_docs/version-0.5/native-modules-android.md @@ -41,12 +41,14 @@ import java.util.Map; import java.util.HashMap; public class ToastModule extends ReactContextBaseJavaModule { + private static ReactApplicationContext reactContext; private static final String DURATION_SHORT_KEY = "SHORT"; private static final String DURATION_LONG_KEY = "LONG"; - ToastModule(ReactApplicationContext reactContext) { - super(reactContext); + ToastModule(ReactApplicationContext context) { + super(context); + reactContext = context; } } ``` @@ -304,6 +306,8 @@ Native modules can signal events to JavaScript without being invoked directly. T ```java ... import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.Arguments; ... private void sendEvent(ReactContext reactContext, String eventName, @@ -314,48 +318,25 @@ private void sendEvent(ReactContext reactContext, } ... WritableMap params = Arguments.createMap(); +params.putString("eventProperty", "someValue"); ... -sendEvent(reactContext, "keyboardWillShow", params); +sendEvent(reactContext, "EventReminder", params); ``` -JavaScript modules can then register to receive events by `addListenerOn` using the `Subscribable` mixin. +JavaScript modules can then register to receive events by `addListener` on the NativeEventEmitter class. ```jsx -import { DeviceEventEmitter } from 'react-native'; +import { NativeEventEmitter, NativeModules } from 'react-native'; ... -var ScrollResponderMixin = { - mixins: [Subscribable.Mixin], - - componentDidMount() { ... - this.addListenerOn(DeviceEventEmitter, - 'keyboardWillShow', - this.scrollResponderKeyboardWillShow); + const eventEmitter = new NativeEventEmitter(NativeModules.ToastExample); + eventEmitter.addListener('EventReminder', (event) => { + console.log(event.eventProperty) // "someValue" + } ... - }, - 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. - -```jsx -... -componentDidMount() { - this.subscription = DeviceEventEmitter.addListener('keyboardWillShow', function(e: Event) { - // handle event - }); -} - -componentWillUnmount() { - // When you want to stop listening to new events, simply call .remove() on the subscription - this.subscription.remove(); -} -... + } ``` ### Getting activity result from `startActivityForResult` diff --git a/website/versioned_docs/version-0.5/navigation.md b/website/versioned_docs/version-0.5/navigation.md index a752c40b0cb..70a52e73108 100644 --- a/website/versioned_docs/version-0.5/navigation.md +++ b/website/versioned_docs/version-0.5/navigation.md @@ -28,10 +28,19 @@ yarn add react-native-gesture-handler # npm install --save react-native-gesture-handler ``` +The third step is to install react-navigation-stack + +``` +yarn add react-navigation-stack +# or with npm +# npm install --save react-navigation-stack +``` + Then you can quickly create an app with a home screen and a profile screen: ```jsx -import {createStackNavigator, createAppContainer} from 'react-navigation'; +import {createAppContainer} from 'react-navigation'; +import {createStackNavigator} from 'react-navigation-stack'; const MainNavigator = createStackNavigator({ Home: {screen: HomeScreen}, diff --git a/website/versioned_docs/version-0.60/optimizing-flatlist-configuration.md b/website/versioned_docs/version-0.5/optimizing-flatlist-configuration.md similarity index 96% rename from website/versioned_docs/version-0.60/optimizing-flatlist-configuration.md rename to website/versioned_docs/version-0.5/optimizing-flatlist-configuration.md index 421524f1202..b0bcaad2f01 100644 --- a/website/versioned_docs/version-0.60/optimizing-flatlist-configuration.md +++ b/website/versioned_docs/version-0.5/optimizing-flatlist-configuration.md @@ -1,12 +1,12 @@ --- -id: version-0.60-optimizing-flatlist-configuration +id: version-0.5-optimizing-flatlist-configuration title: Optimizing Flatlist Configuration original_id: optimizing-flatlist-configuration --- ## Terms -- **VirtualizedList:** The component behind `FlatList` (React Native's implementation of the '[Virtual List](https://bvaughn.github.io/react-virtualized/#/components/List)' concept.) +- **VirtualizedList:** The component behind `FlatList` (React Native's implementation of the [`Virtual List`](https://bvaughn.github.io/react-virtualized/#/components/List) concept.) - **Memory consumption:** How much information about your list is being stored in memory, which could lead to an app crash. @@ -111,9 +111,9 @@ The heavier your components are, the slower they render. Avoid heavy images (use Implement update verification to your components. React's `PureComponent` implement a [`shouldComponentUpdate`](https://reactjs.org/docs/react-component.html#shouldcomponentupdate) with shallow comparison. This is expensive here because it need to check all your props. If you want a good bit-level performance, create the strictest rules for your list item components, checking only props that could potentially change. If your list is simple enough, you could even use ```jsx - shouldComponentUpdate() { - return false - } +shouldComponentUpdate() { + return false +} ``` ### Use cached optimized images diff --git a/website/versioned_docs/version-0.60/hermes.md b/website/versioned_docs/version-0.60/hermes.md index f5073e6fd78..e5e81c0e78b 100644 --- a/website/versioned_docs/version-0.60/hermes.md +++ b/website/versioned_docs/version-0.60/hermes.md @@ -10,7 +10,9 @@ original_id: hermes [Hermes](https://hermesengine.dev) is an open-source JavaScript engine optimized for running React Native apps on Android. For many apps, simply enabling Hermes will result in improved start-up time, decreased memory usage, and smaller app size. At this time Hermes is an **opt-in** React Native feature, and this guide explains how to enable it. -First, ensure you're using at least version 0.60.4 of React Native. If you're upgrading an existing app ensure everything works before trying to switch to Hermes. +First, ensure you're using at least version 0.60.4 of React Native. + +If you have an existing app based on an earlier version of React Native, you will have to upgrade it first. See [Upgrading to new React Native Versions](/react-native/docs/upgrading) for how to do this. Make especially sure that all changes to `android/app/build.gradle` have been applied, as detailed by the [React Native upgrade helper](https://react-native-community.github.io/upgrade-helper/?from=0.59.0). After upgrading the app, make sure everything works before trying to switch to Hermes. > ## Note for Windows users. > diff --git a/website/versioned_docs/version-0.60/inputaccessoryview.md b/website/versioned_docs/version-0.60/inputaccessoryview.md index a1f096229a3..e8543bf2f33 100644 --- a/website/versioned_docs/version-0.60/inputaccessoryview.md +++ b/website/versioned_docs/version-0.60/inputaccessoryview.md @@ -45,7 +45,7 @@ export default class UselessTextInput extends Component { } ``` -This component can also be used to create sticky text inputs (text inputs which are anchored to the top of the keyboard). To do this, wrap a `TextInput` with the `InputAccessoryView` component, and don't set a `nativeID`. For an example, look at [InputAccessoryViewExample.js](https://github.com/facebook/react-native/blob/master/RNTester/js/InputAccessoryViewExample.js). +This component can also be used to create sticky text inputs (text inputs which are anchored to the top of the keyboard). To do this, wrap a `TextInput` with the `InputAccessoryView` component, and don't set a `nativeID`. For an example, look at [InputAccessoryViewExample.js](https://github.com/facebook/react-native/blob/master/RNTester/js/examples/InputAccessoryView/InputAccessoryViewExample.js). --- diff --git a/website/versioned_docs/version-0.60/out-of-tree-platforms.md b/website/versioned_docs/version-0.60/out-of-tree-platforms.md index 43731ddbcad..d79a023f421 100644 --- a/website/versioned_docs/version-0.60/out-of-tree-platforms.md +++ b/website/versioned_docs/version-0.60/out-of-tree-platforms.md @@ -11,6 +11,7 @@ React Native is not just for Android and iOS - there are community-supported pro - [React Native Turbolinks](https://github.com/lazaronixon/react-native-turbolinks) - React Native adapter for building hybrid apps with Turbolinks 5. - [React Native Desktop](https://github.com/status-im/react-native-desktop) - A project aiming to bring React Native to the Desktop with Qt's QML. A fork of [React Native Ubuntu](https://github.com/CanonicalLtd/react-native/), which is no longer maintained. - [React Native macOS](https://github.com/ptmt/react-native-macos) - An experimental React Native fork targeting macOS and Cocoa +- [React Native tvOS](https://github.com/react-native-community/react-native-tvos) - adaptation of React Native for Apple tvOS - [alita](https://github.com/areslabs/alita) - An experimental, comprehensive port of React Native to mini-program(微信小程序). ## Creating your own React Native platform diff --git a/website/versioned_docs/version-0.60/refreshcontrol.md b/website/versioned_docs/version-0.60/refreshcontrol.md index 2ace228bc77..b9692b9f7ec 100644 --- a/website/versioned_docs/version-0.60/refreshcontrol.md +++ b/website/versioned_docs/version-0.60/refreshcontrol.md @@ -6,41 +6,60 @@ original_id: refreshcontrol This component is used inside a ScrollView or ListView to add pull to refresh functionality. When the ScrollView is at `scrollY: 0`, swiping down triggers an `onRefresh` event. -### Usage example - -```jsx -import { ScrollView, RefreshControl } from 'react-native'; - -class RefreshableList extends Component { - constructor(props) { - super(props); - this.state = { - refreshing: false, - }; - } - - _onRefresh = () => { - this.setState({refreshing: true}); - fetchData().then(() => { - this.setState({refreshing: false}); - }); - } - - render() { - return ( +### Example + +```SnackPlayer name=RefreshControl +import React from 'react'; +import { + ScrollView, + RefreshControl, + StyleSheet, + Text, + SafeAreaView, +} from 'react-native'; +import Constants from 'expo-constants'; + +function wait(timeout) { + return new Promise(resolve => { + setTimeout(resolve, timeout); + }); +} + +export default function App() { + const [refreshing, setRefreshing] = React.useState(false); + + const onRefresh = React.useCallback(() => { + setRefreshing(true); + + wait(2000).then(() => setRefreshing(false)); + }, [refreshing]); + + return ( + + } - ... - /> - ); - } - ... + > + Pull down to see RefreshControl indicator + + + ); } + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: Constants.statusBarHeight, + }, + scrollView: { + flex: 1, + backgroundColor: 'pink', + alignItems: 'center', + justifyContent: 'center', + }, +}); ``` **Note:** `refreshing` is a controlled prop, this is why it needs to be set to true in the `onRefresh` function otherwise the refresh indicator will stop immediately. diff --git a/website/versioned_docs/version-0.60/safeareaview.md b/website/versioned_docs/version-0.60/safeareaview.md index 412ff12117c..eff80c75e2b 100644 --- a/website/versioned_docs/version-0.60/safeareaview.md +++ b/website/versioned_docs/version-0.60/safeareaview.md @@ -12,12 +12,23 @@ The purpose of `SafeAreaView` is to render content within the safe area boundari Simply wrap your top level view with a `SafeAreaView` with a `flex: 1` style applied to it. You may also want to use a background color that matches your application's design. -```jsx - - - Hello World! - - +```SnackPlayer name=SafeAreaView +import React from 'react'; +import { StyleSheet, Text, SafeAreaView } from 'react-native'; + +export default function App() { + return ( + + Page content + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, +}); ``` --- diff --git a/website/versioned_docs/version-0.60/scrollview.md b/website/versioned_docs/version-0.60/scrollview.md index da975227c32..76273bc3da2 100644 --- a/website/versioned_docs/version-0.60/scrollview.md +++ b/website/versioned_docs/version-0.60/scrollview.md @@ -20,6 +20,46 @@ This is where `FlatList` comes into play. `FlatList` renders items lazily, just `FlatList` is also handy if you want to render separators between your items, multiple columns, infinite scroll loading, or any number of other features it supports out of the box. +### Example + +```SnackPlayer name=ScrollView +import React from 'react'; +import { StyleSheet, Text, SafeAreaView, ScrollView } from 'react-native'; +import Constants from 'expo-constants'; + +export default function App() { + return ( + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut + aliquip ex ea commodo consequat. Duis aute irure dolor in + reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in + culpa qui officia deserunt mollit anim id est laborum. + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: Constants.statusBarHeight, + }, + scrollView: { + backgroundColor: 'pink', + marginHorizontal: 20, + }, + text: { + fontSize: 42, + }, +}); +``` + --- # Reference diff --git a/website/versioned_docs/version-0.60/sectionlist.md b/website/versioned_docs/version-0.60/sectionlist.md index 390745f0cbb..92c7381c696 100644 --- a/website/versioned_docs/version-0.60/sectionlist.md +++ b/website/versioned_docs/version-0.60/sectionlist.md @@ -21,34 +21,79 @@ If you don't need section support and want a simpler interface, use [` Simple Examples: -```jsx -// Example 1 (Homogeneous Rendering) - {item}} - renderSectionHeader={({section: {title}}) => ( - {title} - )} - sections={[ - {title: 'Title1', data: ['item1', 'item2']}, - {title: 'Title2', data: ['item3', 'item4']}, - {title: 'Title3', data: ['item5', 'item6']}, - ]} - keyExtractor={(item, index) => item + index} -/> -``` - -```jsx -// Example 2 (Heterogeneous Rendering / No Section Headers) -const overrideRenderItem = ({ item, index, section: { title, data } }) => Override{item} - - {item}} - sections={[ - { title: 'Title1', data: ['item1', 'item2'], renderItem: overrideRenderItem }, - { title: 'Title2', data: ['item3', 'item4'] }, - { title: 'Title3', data: ['item5', 'item6'] }, - ]} -/> +### Example + +```SnackPlayer name=SectionList +import React from 'react'; +import { + StyleSheet, + Text, + View, + SafeAreaView, + SectionList, +} from 'react-native'; +import Constants from 'expo-constants'; + +const DATA = [ + { + title: 'Main dishes', + data: ['Pizza', 'Burger', 'Risotto'], + }, + { + title: 'Sides', + data: ['French Fries', 'Onion Rings', 'Fried Shrimps'], + }, + { + title: 'Drinks', + data: ['Water', 'Coke', 'Beer'], + }, + { + title: 'Desserts', + data: ['Cheese Cake', 'Ice Cream'], + }, +]; + +function Item({ title }) { + return ( + + {title} + + ); +} + +export default function App() { + return ( + + item + index} + renderItem={({ item }) => } + renderSectionHeader={({ section: { title } }) => ( + {title} + )} + /> + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + marginTop: Constants.statusBarHeight, + marginHorizontal: 16, + }, + item: { + backgroundColor: '#f9c2ff', + padding: 20, + marginVertical: 8, + }, + header: { + fontSize: 32, + }, + title: { + fontSize: 24, + }, +}); ``` This is a convenience wrapper around [``](virtualizedlist.md), and thus inherits its props (as well as those of [``](scrollview.md) that aren't explicitly listed here, along with the following caveats: From 31e1a9105f139ef04702a9465c2440cdee9519bf Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Wed, 18 Sep 2019 16:10:45 +0100 Subject: [PATCH 20/26] Add 0.61 blog post --- website/blog/2019-09-18-version-0.61.md | 57 +++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 website/blog/2019-09-18-version-0.61.md diff --git a/website/blog/2019-09-18-version-0.61.md b/website/blog/2019-09-18-version-0.61.md new file mode 100644 index 00000000000..c9b0d8c423f --- /dev/null +++ b/website/blog/2019-09-18-version-0.61.md @@ -0,0 +1,57 @@ +--- +title: Announcing React Native 0.61 with Fast Refresh +author: Dan Abramov +authorTitle: React Core at Facebook +authorURL: https://twitter.com/dan_abramov +authorImageURL: https://avatars1.githubusercontent.com/u/810438?s=460&v=4 +authorTwitter: dan_abramov +category: announcements +--- + +We’re excited to announce React Native 0.61, which includes a new reloading experience we’re calling Fast Refresh. + +## Fast Refresh + +When we asked the React Native community about [common pain points](https://github.com/react-native-community/discussions-and-proposals/issues/64), one of the top answers was that the “hot reloading” feature was broken. It didn’t work reliably for function components, often failed to update the screen, and wasn’t resilient to typos and mistakes. We heard that most people turned it off because it was too unreliable. + +In React Native 0.61, **we’re unifying the existing “live reloading” (reload on save) and “hot reloading” features into a single new feature called “Fast Refresh”**. Fast Refresh was implemented from scratch with the following principles: + +- Fast Refresh **fully supports modern React**, including function components and Hooks. +- Fast Refresh **gracefully recovers after typos** and other mistakes, and falls back to a full reload when needed. +- Fast Refresh **doesn’t perform invasive code transformations** so it’s reliable enough to be on by default. + +To see Fast Refresh in action, check out this video: + +

    + +

    + +Give it a try, and let us know what you think! If you prefer, you can turn it off in the Dev Menu (Cmd+D on iOS, Cmd+M or Ctrl+M on Android). Turning it on and off is instant so you can do it any time. + +Here are a few Fast Refresh tips: + +- Fast Refresh preserves React local state in function components (and Hooks!) by default. +- If you need to reset the React state on every edit, you can add a special `// @refresh reset` comment to the file with that component. +- Fast Refresh always remounts class components without preserving state. This ensures it works reliably. +- We all make mistakes in the code! Fast Refresh automatically retries rendering after you save a file. You don't need to reload the app manually after fixing a syntax or a runtime error. +- Adding a `console.log` or a `debugger` statement during edits is a neat debugging technique. + +Please report any issues with Fast Refresh on GitHub, and we’ll look into them. + +## Other Improvements + +- **Fixed use_frameworks! CocoaPods support.** In 0.60 we made some updates to integrate CocoaPods by default. Unfortunately, this broke builds using [use_frameworks!](https://guides.cocoapods.org/syntax/podfile.html#use_frameworks_bang). This is [fixed in 0.61](https://github.com/facebook/react-native/pull/25619), making it easier to integrate React Native into your iOS projects that require building with dynamic frameworks. +- **Add useWindowDimensions Hook. **This new Hook automatically provides and subscribes to dimension updates, and can be used instead of the Dimensions API in most cases. See [x] for more information. +- **React was upgraded to 16.9.** This version deprecates old names for the UNSAFE\_ lifecycle methods, contains improvements to `act`, and more. See the [React 16.9 blog post](https://reactjs.org/blog/2019/08/08/react-v16.9.0.html) for an automated migration script and more information. + +## Breaking Changes + +- **Remove React .xcodeproj.** In 0.60, we introduced auto-linking support via CocoaPods. We have also integrated CocoaPods into the e2e tests runs, so that from now on, we have a unified standard way of integrating RN into iOS apps. This effectively deprecates the React .xcodeproj support, and the file has been removed starting 0.61. Note: if you use 0.60 auto-linking already, you shouldn't be affected. + +## Thanks + +Thanks to all of the contributors that helped make 0.61 possible! + +To see all the updates, take a look at the 0.61 changelog. From 8db7d81b09c19c2e22800bcba56d416ba3c36294 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Wed, 18 Sep 2019 17:16:20 +0100 Subject: [PATCH 21/26] Fix from review --- website/blog/2019-09-18-version-0.61.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/blog/2019-09-18-version-0.61.md b/website/blog/2019-09-18-version-0.61.md index c9b0d8c423f..c73ba7969a6 100644 --- a/website/blog/2019-09-18-version-0.61.md +++ b/website/blog/2019-09-18-version-0.61.md @@ -43,7 +43,7 @@ Please report any issues with Fast Refresh on GitHub, and we’ll look into them ## Other Improvements - **Fixed use_frameworks! CocoaPods support.** In 0.60 we made some updates to integrate CocoaPods by default. Unfortunately, this broke builds using [use_frameworks!](https://guides.cocoapods.org/syntax/podfile.html#use_frameworks_bang). This is [fixed in 0.61](https://github.com/facebook/react-native/pull/25619), making it easier to integrate React Native into your iOS projects that require building with dynamic frameworks. -- **Add useWindowDimensions Hook. **This new Hook automatically provides and subscribes to dimension updates, and can be used instead of the Dimensions API in most cases. See [x] for more information. +- **Add useWindowDimensions Hook.** This new Hook automatically provides and subscribes to dimension updates, and can be used instead of the Dimensions API in most cases. - **React was upgraded to 16.9.** This version deprecates old names for the UNSAFE\_ lifecycle methods, contains improvements to `act`, and more. See the [React 16.9 blog post](https://reactjs.org/blog/2019/08/08/react-v16.9.0.html) for an automated migration script and more information. ## Breaking Changes From 6b180a4ea6e76cd152609ab2623864231db577e4 Mon Sep 17 00:00:00 2001 From: Rachel Nabors Date: Thu, 19 Sep 2019 18:48:33 +0100 Subject: [PATCH 22/26] Adding DEV and Spectrum to communities footer --- website/core/Footer.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/core/Footer.js b/website/core/Footer.js index a81fc25b970..efbf77bfb96 100644 --- a/website/core/Footer.js +++ b/website/core/Footer.js @@ -47,6 +47,14 @@ class Footer extends React.Component { Contributor Guide + + DEV Community + + + Spectrum Chat +

More Resources
From 4ddf860b62caf8580578c702187b656312fd0cea Mon Sep 17 00:00:00 2001 From: Ricky Date: Fri, 20 Sep 2019 10:28:07 +0100 Subject: [PATCH 23/26] Only add DEV --- website/core/Footer.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/website/core/Footer.js b/website/core/Footer.js index efbf77bfb96..783c74b6edc 100644 --- a/website/core/Footer.js +++ b/website/core/Footer.js @@ -50,11 +50,6 @@ class Footer extends React.Component { DEV Community - - Spectrum Chat -
More Resources
From 0016e2cdfc7587ef0684eac7f4f5fc9e1cea804f Mon Sep 17 00:00:00 2001 From: Ricky Date: Fri, 20 Sep 2019 18:04:45 +0100 Subject: [PATCH 24/26] Add changelog link Co-Authored-By: Lorenzo Sciandra --- website/blog/2019-09-18-version-0.61.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/blog/2019-09-18-version-0.61.md b/website/blog/2019-09-18-version-0.61.md index c73ba7969a6..534e39739a6 100644 --- a/website/blog/2019-09-18-version-0.61.md +++ b/website/blog/2019-09-18-version-0.61.md @@ -54,4 +54,4 @@ Please report any issues with Fast Refresh on GitHub, and we’ll look into them Thanks to all of the contributors that helped make 0.61 possible! -To see all the updates, take a look at the 0.61 changelog. +To see all the updates, take a look at the [0.61 changelog](https://github.com/react-native-community/releases/blob/master/CHANGELOG.md). From 42beca1138f37bcd57c37c5cba74b134d7ad9bac Mon Sep 17 00:00:00 2001 From: Ricky Date: Wed, 25 Sep 2019 14:12:33 +0100 Subject: [PATCH 25/26] Add guide for Fast Refresh (#1282) * Add guide for Fast Refresh * Remove URL * Better wording for "fall", remove bang * Update debugging.md Adding a reference here to Fast Refresh. Section still needs intro paragraph. But that seemed tangential to this commit in light of upcoming sectional changes. --- docs/debugging.md | 21 ++---- docs/fast-refresh.md | 38 +++++++++++ website/i18n/en.json | 145 +++++++++++++++++++++--------------------- website/sidebars.json | 1 + 4 files changed, 114 insertions(+), 91 deletions(-) create mode 100644 docs/fast-refresh.md diff --git a/docs/debugging.md b/docs/debugging.md index 602fe0deb2b..12862d9a224 100644 --- a/docs/debugging.md +++ b/docs/debugging.md @@ -3,10 +3,6 @@ id: debugging title: Debugging --- -## 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 on Mac OS and `Ctrl+M` on Windows and Linux. Alternatively for Android, you can run the command `adb shell input keyevent 82` to open the dev menu (82 being the Menu key code). @@ -15,22 +11,13 @@ You can access the developer menu by shaking your device or by selecting "Shake > 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. +## Enabling Fast Refresh -### Automatic reloading +Fast Refresh is a React Native feature that allows you to get near-instant feedback for changes in your React components. While debugging, it can help to have [Fast Refresh](fast-refresh.md) enabled. Fast Refresh is enabled by default, and you can toggle "Enable Fast Refresh" in the React Native developer menu. When enabled, most of your edits should be visible within a second or two. -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) 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: +## Enabling Keyboard Shortcuts -- 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). +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. ## In-app Errors and Warnings diff --git a/docs/fast-refresh.md b/docs/fast-refresh.md new file mode 100644 index 00000000000..79dc1326f89 --- /dev/null +++ b/docs/fast-refresh.md @@ -0,0 +1,38 @@ +--- +id: fast-refresh +title: Fast Refresh +--- + +Fast Refresh is a React Native feature that allows you to get near-instant feedback for changes in your React components. Fast Refresh is enabled by default, and you can toggle "Enable Fast Refresh" in the React Native developer menu. With Fast Refresh enabled, most edits should be visible within a second or two. + +## How It Works + +- If you edit a module that **only exports React component(s)**, Fast Refresh will update the code just for that module, and re-render your component. You can edit anything in that file, including styles, rendering logic, event handlers, or effects. +- If you edit a module with exports that _aren't_ React components, Fast Refresh will re-run both that module, and the other modules importing it. So if both `Button.js` and `Modal.js` import `Theme.js`, editing `Theme.js` will update both components. +- Finally, if you **edit a file** that's **imported by modules outside of the React tree**, Fast Refresh **will fall back to doing a full reload**. You might have a file which renders a React component but also exports a value that is imported by a **non-React component**. For example, maybe your component also exports a constant, and a non-React utility module imports it. In that case, consider migrating the query to a separate file and importing it into both files. This will re-enable Fast Refresh to work. Other cases can usually be solved in a similar way. + +## Error Resilience + +If you make a **syntax error** during a Fast Refresh session, you can fix it and save the file again. The redbox will disappear. Modules with syntax errors are prevented from running, so you won't need to reload the app. + +If you make a **runtime error during the module initialization** (for example, typing `Style.create` instead of `StyleSheet.create`), the Fast Refresh session will continue once you fix the error. The redbox will disappear, and the module will be updated. + +If you make a mistake that leads to a **runtime error inside your component**, the Fast Refresh session will _also_ continue after you fix the error. In that case, React will remount your application using the updated code. + +If you have [error boundaries](https://reactjs.org/docs/error-boundaries.html) in your app (which is a good idea for graceful failures in production), they will retry rendering on the next edit after a redbox. In that sense, having an error boundary can prevent you from always getting kicked out to the root app screen. However, keep in mind that error boundaries shouldn't be _too_ granular. They are used by React in production, and should always be designed intentionally. + +## Limitations + +Fast Refresh tries to preserve local React state in the component you're editing, but only if it's safe to do so. Here's a few reasons why you might see local state being reset on every edit to a file: + +- Local state is not preserved for class components (only function components and Hooks preserve state). +- The module you're editing might have _other_ exports in addition to a React component. +- Sometimes, a module would export the result of calling higher-order component like `createNavigationContainer(MyScreen)`. If the returned component is a class, state will be reset. + +In longer term, as more of your codebase moves to function components and Hooks, you can expect state to be preserved in more cases. + +## Tips + +- Fast Refresh preserves React local state in function components (and Hooks) by default. +- Sometimes you might want to _force_ the state to be reset, and a component to be remounted. For example, this can be handy if you're tweaking an animation that only happens on mount. To do this, you can add `// @refresh reset` anywhere in the file you're editing. This directive is local to the file, and instructs Fast Refresh to remount components defined in that file on every edit. +- You can put `console.log` or `debugger;` into the components you edit during a Fast Refresh session. diff --git a/website/i18n/en.json b/website/i18n/en.json index 3dcd2b62d1f..8a84f330730 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -101,6 +101,9 @@ "easing": { "title": "Easing" }, + "fast-refresh": { + "title": "Fast Refresh" + }, "flatlist": { "title": "FlatList" }, @@ -353,6 +356,9 @@ "tutorial": { "title": "Learn the Basics" }, + "typescript": { + "title": "Using TypeScript with React Native" + }, "upgrading": { "title": "Upgrading to new React Native versions" }, @@ -2243,6 +2249,9 @@ "version-0.5/version-0.5-network": { "title": "Networking" }, + "version-0.5/version-0.5-optimizing-flatlist-configuration": { + "title": "Optimizing Flatlist Configuration" + }, "version-0.5/version-0.5-panresponder": { "title": "PanResponder" }, @@ -2313,7 +2322,7 @@ "title": "Share" }, "version-0.5/version-0.5-signed-apk-android": { - "title": "Generating Signed APK" + "title": "Publishing to Google Play Store" }, "version-0.5/version-0.5-slider": { "title": "Slider" @@ -3083,9 +3092,6 @@ "version-0.59/version-0.59-image-style-props": { "title": "Image Style Props" }, - "version-0.59/version-0.59-images": { - "title": "Images" - }, "version-0.59/version-0.59-imagestore": { "title": "ImageStore" }, @@ -3164,9 +3170,6 @@ "version-0.6/version-0.6-touchablewithoutfeedback": { "title": "TouchableWithoutFeedback" }, - "version-0.60/version-0.60-accessibility": { - "title": "Accessibility" - }, "version-0.60/version-0.60-accessibilityinfo": { "title": "AccessibilityInfo" }, @@ -3179,44 +3182,44 @@ "version-0.60/version-0.60-alert": { "title": "Alert" }, + "version-0.60/version-0.60-alertios": { + "title": "AlertIOS" + }, "version-0.60/version-0.60-animated": { "title": "Animated" }, - "version-0.60/version-0.60-animations": { - "title": "Animations" - }, - "version-0.60/version-0.60-app-extensions": { - "title": "App Extensions" - }, "version-0.60/version-0.60-appregistry": { "title": "AppRegistry" }, "version-0.60/version-0.60-appstate": { "title": "AppState" }, + "version-0.60/version-0.60-asyncstorage": { + "title": "AsyncStorage" + }, "version-0.60/version-0.60-backhandler": { "title": "BackHandler" }, "version-0.60/version-0.60-button": { "title": "Button" }, + "version-0.60/version-0.60-clipboard": { + "title": "Clipboard" + }, "version-0.60/version-0.60-communication-android": { "title": "Communication between native and React Native" }, - "version-0.60/version-0.60-components-and-apis": { - "title": "Components and APIs" + "version-0.60/version-0.60-datepickerandroid": { + "title": "DatePickerAndroid" }, "version-0.60/version-0.60-datepickerios": { "title": "DatePickerIOS" }, - "version-0.60/version-0.60-debugging": { - "title": "Debugging" - }, "version-0.60/version-0.60-dimensions": { "title": "Dimensions" }, - "version-0.60/version-0.60-direct-manipulation": { - "title": "Direct Manipulation" + "version-0.60/version-0.60-drawerlayoutandroid": { + "title": "DrawerLayoutAndroid" }, "version-0.60/version-0.60-easing": { "title": "Easing" @@ -3224,32 +3227,29 @@ "version-0.60/version-0.60-flatlist": { "title": "FlatList" }, - "version-0.60/version-0.60-flexbox": { - "title": "Layout with Flexbox" - }, - "version-0.60/version-0.60-getting-started": { - "title": "Getting Started" - }, - "version-0.60/version-0.60-handling-text-input": { - "title": "Handling Text Input" - }, - "version-0.60/version-0.60-headless-js-android": { - "title": "Headless JS" - }, "version-0.60/version-0.60-hermes": { "title": "Using Hermes" }, + "version-0.60/version-0.60-image-style-props": { + "title": "Image Style Props" + }, "version-0.60/version-0.60-image": { "title": "Image" }, + "version-0.60/version-0.60-imagebackground": { + "title": "ImageBackground" + }, + "version-0.60/version-0.60-imageeditor": { + "title": "ImageEditor" + }, "version-0.60/version-0.60-imagepickerios": { "title": "ImagePickerIOS" }, - "version-0.60/version-0.60-images": { - "title": "Images" + "version-0.60/version-0.60-inputaccessoryview": { + "title": "InputAccessoryView" }, - "version-0.60/version-0.60-javascript-environment": { - "title": "JavaScript Environment" + "version-0.60/version-0.60-interactionmanager": { + "title": "InteractionManager" }, "version-0.60/version-0.60-keyboard": { "title": "Keyboard" @@ -3269,44 +3269,35 @@ "version-0.60/version-0.60-modal": { "title": "Modal" }, - "version-0.60/version-0.60-more-resources": { - "title": "More Resources" - }, - "version-0.60/version-0.60-native-components-ios": { - "title": "Native UI Components" - }, - "version-0.60/version-0.60-native-modules-android": { - "title": "Native Modules" - }, - "version-0.60/version-0.60-navigation": { - "title": "Navigating Between Screens" - }, - "version-0.60/version-0.60-optimizing-flatlist-configuration": { - "title": "Optimizing Flatlist Configuration" - }, "version-0.60/version-0.60-out-of-tree-platforms": { "title": "Out-of-Tree Platforms" }, "version-0.60/version-0.60-panresponder": { "title": "PanResponder" }, - "version-0.60/version-0.60-performance": { - "title": "Performance" + "version-0.60/version-0.60-permissionsandroid": { + "title": "PermissionsAndroid" + }, + "version-0.60/version-0.60-picker": { + "title": "Picker" }, "version-0.60/version-0.60-pickerios": { "title": "PickerIOS" }, + "version-0.60/version-0.60-pixelratio": { + "title": "PixelRatio" + }, "version-0.60/version-0.60-progressbarandroid": { "title": "ProgressBarAndroid" }, + "version-0.60/version-0.60-progressviewios": { + "title": "ProgressViewIOS" + }, "version-0.60/version-0.60-pushnotificationios": { "title": "PushNotificationIOS" }, - "version-0.60/version-0.60-removing-default-permissions": { - "title": "Removing Default Permissions" - }, - "version-0.60/version-0.60-running-on-simulator-ios": { - "title": "Running On Simulator" + "version-0.60/version-0.60-refreshcontrol": { + "title": "RefreshControl" }, "version-0.60/version-0.60-safeareaview": { "title": "SafeAreaView" @@ -3317,23 +3308,26 @@ "version-0.60/version-0.60-sectionlist": { "title": "SectionList" }, + "version-0.60/version-0.60-segmentedcontrolios": { + "title": "SegmentedControlIOS" + }, "version-0.60/version-0.60-settings": { "title": "Settings" }, - "version-0.60/version-0.60-signed-apk-android": { - "title": "Publishing to Google Play Store" + "version-0.60/version-0.60-shadow-props": { + "title": "Shadow Props" + }, + "version-0.60/version-0.60-share": { + "title": "Share" }, "version-0.60/version-0.60-slider": { "title": "Slider" }, - "version-0.60/version-0.60-state": { - "title": "State" - }, "version-0.60/version-0.60-statusbar": { "title": "StatusBar" }, - "version-0.60/version-0.60-style": { - "title": "Style" + "version-0.60/version-0.60-statusbarios": { + "title": "StatusBarIOS" }, "version-0.60/version-0.60-stylesheet": { "title": "StyleSheet" @@ -3353,8 +3347,11 @@ "version-0.60/version-0.60-textinput": { "title": "TextInput" }, - "version-0.60/version-0.60-timers": { - "title": "Timers" + "version-0.60/version-0.60-timepickerandroid": { + "title": "TimePickerAndroid" + }, + "version-0.60/version-0.60-toastandroid": { + "title": "ToastAndroid" }, "version-0.60/version-0.60-toolbarandroid": { "title": "ToolbarAndroid" @@ -3374,14 +3371,11 @@ "version-0.60/version-0.60-transforms": { "title": "Transforms" }, - "version-0.60/version-0.60-troubleshooting": { - "title": "Troubleshooting" - }, - "version-0.60/version-0.60-upgrading": { - "title": "Upgrading to new React Native versions" + "version-0.60/version-0.60-typescript": { + "title": "Using TypeScript with React Native" }, - "version-0.60/version-0.60-using-a-scrollview": { - "title": "Using a ScrollView" + "version-0.60/version-0.60-vibration": { + "title": "Vibration" }, "version-0.60/version-0.60-view-style-props": { "title": "View Style Props" @@ -3389,6 +3383,9 @@ "version-0.60/version-0.60-view": { "title": "View" }, + "version-0.60/version-0.60-viewpagerandroid": { + "title": "ViewPagerAndroid" + }, "version-0.60/version-0.60-virtualizedlist": { "title": "VirtualizedList" }, diff --git a/website/sidebars.json b/website/sidebars.json index 86b071aa38a..69f701d1c04 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -16,6 +16,7 @@ "more-resources" ], "Guides": [ + "fast-refresh", "components-and-apis", "platform-specific-code", "navigation", From 83f7e3d1d4ad2a1f04fb8b42a4ef24e31cd27b4e Mon Sep 17 00:00:00 2001 From: Rachel Nabors Date: Wed, 25 Sep 2019 15:09:02 +0100 Subject: [PATCH 26/26] Add 0.61 docs (#1287) --- website/i18n/en.json | 6 + .../versioned_docs/version-0.61/debugging.md | 169 ++++++++++++++++++ .../version-0.61/fast-refresh.md | 39 ++++ .../version-0.61-sidebars.json | 139 ++++++++++++++ website/versions.json | 1 + 5 files changed, 354 insertions(+) create mode 100644 website/versioned_docs/version-0.61/debugging.md create mode 100644 website/versioned_docs/version-0.61/fast-refresh.md create mode 100644 website/versioned_sidebars/version-0.61-sidebars.json diff --git a/website/i18n/en.json b/website/i18n/en.json index 8a84f330730..65ec2e7c60a 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -3389,6 +3389,12 @@ "version-0.60/version-0.60-virtualizedlist": { "title": "VirtualizedList" }, + "version-0.61/version-0.61-debugging": { + "title": "Debugging" + }, + "version-0.61/version-0.61-fast-refresh": { + "title": "Fast Refresh" + }, "version-0.7/version-0.7-pushnotificationios": { "title": "PushNotificationIOS" }, diff --git a/website/versioned_docs/version-0.61/debugging.md b/website/versioned_docs/version-0.61/debugging.md new file mode 100644 index 00000000000..ad18313325f --- /dev/null +++ b/website/versioned_docs/version-0.61/debugging.md @@ -0,0 +1,169 @@ +--- +id: version-0.61-debugging +title: Debugging +original_id: debugging +--- + +## 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 on Mac OS and `Ctrl+M` on Windows and Linux. Alternatively for Android, you can run the command `adb shell input keyevent 82` to open the dev menu (82 being the Menu key code). + +![](/react-native/docs/assets/DeveloperMenu.png) + +> The Developer Menu is disabled in release (production) builds. + +## Enabling Fast Refresh + +Fast Refresh is a React Native feature that allows you to get near-instant feedback for changes in your React components. While debugging, it can help to have [Fast Refresh](fast-refresh.md) enabled. Fast Refresh is enabled by default, and you can toggle "Enable Fast Refresh" in the React Native developer menu. When enabled, most of your edits should be visible within a second or two. + +## 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. + +## 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: + +```jsx +import {YellowBox} from 'react-native'; +YellowBox.ignoreWarnings(['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](debugging.md#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. + +## Safari Developer Tools + +You can use Safari to debug the iOS version of your app without having to enable "Debug JS Remotely". + +- Enable Develop menu in Safari: `Preferences → Advanced → Select "Show Develop menu in menu bar"` +- Select your app's JSContext: `Develop → Simulator → JSContext` +- Safari's Web Inspector should open which has a Console and a Debugger + +However, there are some disadvantages: + +1. No sourcemaps when debugging +2. Every time the app is reloaded (using live reload, or by manually reloading), a new JSContext is created. Choosing "Automatically Show Web Inspectors for JSContexts" saves you from having to select the latest JSContext manually. + +## React Developer Tools + +You can use [the standalone version of React Developer Tools](https://github.com/facebook/react/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](/react-native/docs/assets/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 "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it: + +![React Native Inspector](/react-native/docs/assets/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](/react-native/docs/assets/ReactDevToolsInspector.gif) + +You can choose "Toggle 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](/react-native/docs/assets/ReactDevToolsDollarR.gif) + +## Performance Monitor + +You can enable a performance overlay to help you debug performance problems by selecting "Perf Monitor" in the Developer Menu. + +
+ +# Debugging in Ejected Apps + + + +## 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 or Expo CLI, 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 or Expo CLI, 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 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. diff --git a/website/versioned_docs/version-0.61/fast-refresh.md b/website/versioned_docs/version-0.61/fast-refresh.md new file mode 100644 index 00000000000..f986938d74f --- /dev/null +++ b/website/versioned_docs/version-0.61/fast-refresh.md @@ -0,0 +1,39 @@ +--- +id: version-0.61-fast-refresh +title: Fast Refresh +original_id: fast-refresh +--- + +Fast Refresh is a React Native feature that allows you to get near-instant feedback for changes in your React components. Fast Refresh is enabled by default, and you can toggle "Enable Fast Refresh" in the React Native developer menu. With Fast Refresh enabled, most edits should be visible within a second or two. + +## How It Works + +- If you edit a module that **only exports React component(s)**, Fast Refresh will update the code just for that module, and re-render your component. You can edit anything in that file, including styles, rendering logic, event handlers, or effects. +- If you edit a module with exports that _aren't_ React components, Fast Refresh will re-run both that module, and the other modules importing it. So if both `Button.js` and `Modal.js` import `Theme.js`, editing `Theme.js` will update both components. +- Finally, if you **edit a file** that's **imported by modules outside of the React tree**, Fast Refresh **will fall back to doing a full reload**. You might have a file which renders a React component but also exports a value that is imported by a **non-React component**. For example, maybe your component also exports a constant, and a non-React utility module imports it. In that case, consider migrating the query to a separate file and importing it into both files. This will re-enable Fast Refresh to work. Other cases can usually be solved in a similar way. + +## Error Resilience + +If you make a **syntax error** during a Fast Refresh session, you can fix it and save the file again. The redbox will disappear. Modules with syntax errors are prevented from running, so you won't need to reload the app. + +If you make a **runtime error during the module initialization** (for example, typing `Style.create` instead of `StyleSheet.create`), the Fast Refresh session will continue once you fix the error. The redbox will disappear, and the module will be updated. + +If you make a mistake that leads to a **runtime error inside your component**, the Fast Refresh session will _also_ continue after you fix the error. In that case, React will remount your application using the updated code. + +If you have [error boundaries](https://reactjs.org/docs/error-boundaries.html) in your app (which is a good idea for graceful failures in production), they will retry rendering on the next edit after a redbox. In that sense, having an error boundary can prevent you from always getting kicked out to the root app screen. However, keep in mind that error boundaries shouldn't be _too_ granular. They are used by React in production, and should always be designed intentionally. + +## Limitations + +Fast Refresh tries to preserve local React state in the component you're editing, but only if it's safe to do so. Here's a few reasons why you might see local state being reset on every edit to a file: + +- Local state is not preserved for class components (only function components and Hooks preserve state). +- The module you're editing might have _other_ exports in addition to a React component. +- Sometimes, a module would export the result of calling higher-order component like `createNavigationContainer(MyScreen)`. If the returned component is a class, state will be reset. + +In longer term, as more of your codebase moves to function components and Hooks, you can expect state to be preserved in more cases. + +## Tips + +- Fast Refresh preserves React local state in function components (and Hooks) by default. +- Sometimes you might want to _force_ the state to be reset, and a component to be remounted. For example, this can be handy if you're tweaking an animation that only happens on mount. To do this, you can add `// @refresh reset` anywhere in the file you're editing. This directive is local to the file, and instructs Fast Refresh to remount components defined in that file on every edit. +- You can put `console.log` or `debugger;` into the components you edit during a Fast Refresh session. diff --git a/website/versioned_sidebars/version-0.61-sidebars.json b/website/versioned_sidebars/version-0.61-sidebars.json new file mode 100644 index 00000000000..7cb623a90a5 --- /dev/null +++ b/website/versioned_sidebars/version-0.61-sidebars.json @@ -0,0 +1,139 @@ +{ + "version-0.61-docs": { + "The Basics": [ + "version-0.61-getting-started", + "version-0.61-tutorial", + "version-0.61-props", + "version-0.61-state", + "version-0.61-style", + "version-0.61-height-and-width", + "version-0.61-flexbox", + "version-0.61-handling-text-input", + "version-0.61-handling-touches", + "version-0.61-using-a-scrollview", + "version-0.61-using-a-listview", + "version-0.61-network", + "version-0.61-more-resources" + ], + "Guides": [ + "version-0.61-fast-refresh", + "version-0.61-components-and-apis", + "version-0.61-platform-specific-code", + "version-0.61-navigation", + "version-0.61-images", + "version-0.61-animations", + "version-0.61-accessibility", + "version-0.61-improvingux", + "version-0.61-optimizing-flatlist-configuration", + "version-0.61-timers", + "version-0.61-debugging", + "version-0.61-performance", + "version-0.61-gesture-responder-system", + "version-0.61-javascript-environment", + "version-0.61-typescript", + "version-0.61-direct-manipulation", + "version-0.61-colors", + "version-0.61-integration-with-existing-apps", + "version-0.61-building-for-apple-tv", + "version-0.61-running-on-device", + "version-0.61-upgrading", + "version-0.61-troubleshooting", + "version-0.61-native-modules-setup", + "version-0.61-out-of-tree-platforms" + ], + "Guides (iOS)": [ + "version-0.61-native-modules-ios", + "version-0.61-native-components-ios", + "version-0.61-linking-libraries-ios", + "version-0.61-running-on-simulator-ios", + "version-0.61-communication-ios", + "version-0.61-app-extensions" + ], + "Guides (Android)": [ + "version-0.61-native-modules-android", + "version-0.61-native-components-android", + "version-0.61-headless-js-android", + "version-0.61-signed-apk-android", + "version-0.61-removing-default-permissions", + "version-0.61-hermes" + ] + }, + "version-0.61-api": { + "Components": [ + "version-0.61-activityindicator", + "version-0.61-button", + "version-0.61-datepickerios", + "version-0.61-drawerlayoutandroid", + "version-0.61-flatlist", + "version-0.61-image", + "version-0.61-imagebackground", + "version-0.61-inputaccessoryview", + "version-0.61-keyboardavoidingview", + "version-0.61-maskedviewios", + "version-0.61-modal", + "version-0.61-picker", + "version-0.61-pickerios", + "version-0.61-progressbarandroid", + "version-0.61-progressviewios", + "version-0.61-refreshcontrol", + "version-0.61-safeareaview", + "version-0.61-scrollview", + "version-0.61-sectionlist", + "version-0.61-segmentedcontrolios", + "version-0.61-slider", + "version-0.61-statusbar", + "version-0.61-switch", + "version-0.61-tabbarios", + "version-0.61-tabbarios-item", + "version-0.61-text", + "version-0.61-textinput", + "version-0.61-toolbarandroid", + "version-0.61-touchablehighlight", + "version-0.61-touchablenativefeedback", + "version-0.61-touchableopacity", + "version-0.61-touchablewithoutfeedback", + "version-0.61-view", + "version-0.61-viewpagerandroid", + "version-0.61-virtualizedlist" + ], + "APIs": [ + "version-0.61-accessibilityinfo", + "version-0.61-actionsheetios", + "version-0.61-alert", + "version-0.61-alertios", + "version-0.61-animated", + "version-0.61-appregistry", + "version-0.61-appstate", + "version-0.61-asyncstorage", + "version-0.61-backhandler", + "version-0.61-clipboard", + "version-0.61-datepickerandroid", + "version-0.61-dimensions", + "version-0.61-easing", + "version-0.61-imageeditor", + "version-0.61-imagepickerios", + "version-0.61-image-style-props", + "version-0.61-interactionmanager", + "version-0.61-keyboard", + "version-0.61-layout-props", + "version-0.61-layoutanimation", + "version-0.61-linking", + "version-0.61-panresponder", + "version-0.61-permissionsandroid", + "version-0.61-pixelratio", + "version-0.61-pushnotificationios", + "version-0.61-settings", + "version-0.61-shadow-props", + "version-0.61-share", + "version-0.61-statusbarios", + "version-0.61-stylesheet", + "version-0.61-systrace", + "version-0.61-text-style-props", + "version-0.61-timepickerandroid", + "version-0.61-toastandroid", + "version-0.61-transforms", + "version-0.61-vibration", + "version-0.61-view-style-props" + ] + } +} diff --git a/website/versions.json b/website/versions.json index 4b2e05a6182..88a1bfd1081 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,4 +1,5 @@ [ + "0.61", "0.60", "0.59", "0.58",