From eb0b17096413fb4fa94cd204ee4edcaae0dd68b5 Mon Sep 17 00:00:00 2001 From: Lorenzo Sciandra Date: Mon, 23 Mar 2020 13:58:06 +0000 Subject: [PATCH 1/3] add new versioned version --- .../version-0.62/accessibility.md | 306 +++++++ .../version-0.62/accessibilityinfo.md | 279 ++++++ .../version-0.62/actionsheetios.md | 117 +++ .../version-0.62/activityindicator.md | 129 +++ website/versioned_docs/version-0.62/alert.md | 197 ++++ .../versioned_docs/version-0.62/alertios.md | 187 ++++ .../versioned_docs/version-0.62/animated.md | 614 +++++++++++++ .../version-0.62/animatedvalue.md | 229 +++++ .../version-0.62/animatedvaluexy.md | 223 +++++ .../versioned_docs/version-0.62/animations.md | 848 ++++++++++++++++++ .../versioned_docs/version-0.62/appearance.md | 67 ++ .../version-0.62/appregistry.md | 324 +++++++ .../versioned_docs/version-0.62/appstate.md | 180 ++++ .../version-0.62/asyncstorage.md | 355 ++++++++ .../version-0.62/backhandler.md | 306 +++++++ .../version-0.62/building-for-apple-tv.md | 167 ++++ website/versioned_docs/version-0.62/button.md | 240 +++++ .../versioned_docs/version-0.62/checkbox.md | 75 ++ .../versioned_docs/version-0.62/clipboard.md | 106 +++ website/versioned_docs/version-0.62/colors.md | 195 ++++ .../version-0.62/communication-android.md | 106 +++ .../version-0.62/communication-ios.md | 201 +++++ .../version-0.62/components-and-apis.md | 215 +++++ .../version-0.62/datepickerandroid.md | 74 ++ .../version-0.62/datepickerios.md | 218 +++++ .../versioned_docs/version-0.62/debugging.md | 174 ++++ .../version-0.62/devsettings.md | 39 + .../versioned_docs/version-0.62/dimensions.md | 189 ++++ .../version-0.62/direct-manipulation.md | 197 ++++ .../version-0.62/drawerlayoutandroid.md | 222 +++++ website/versioned_docs/version-0.62/easing.md | 386 ++++++++ .../version-0.62/fast-refresh.md | 48 + .../versioned_docs/version-0.62/flatlist.md | 716 +++++++++++++++ .../versioned_docs/version-0.62/flexbox.md | 221 +++++ .../version-0.62/getting-started.md | 594 ++++++++++++ .../version-0.62/handling-text-input.md | 37 + .../version-0.62/handling-touches.md | 175 ++++ .../version-0.62/headless-js-android.md | 194 ++++ .../version-0.62/height-and-width.md | 54 ++ website/versioned_docs/version-0.62/hermes.md | 92 ++ .../version-0.62/image-style-props.md | 635 +++++++++++++ website/versioned_docs/version-0.62/image.md | 617 +++++++++++++ .../version-0.62/imagebackground.md | 73 ++ .../version-0.62/inputaccessoryview.md | 79 ++ .../integration-with-existing-apps.md | 810 +++++++++++++++++ .../version-0.62/interactionmanager.md | 233 +++++ .../intro-react-native-components.md | 70 ++ .../version-0.62/intro-react.md | 527 +++++++++++ .../version-0.62/introduction.md | 145 +++ .../version-0.62/javascript-environment.md | 90 ++ .../versioned_docs/version-0.62/keyboard.md | 203 +++++ .../version-0.62/keyboardavoidingview.md | 108 +++ .../version-0.62/layout-props.md | 763 ++++++++++++++++ .../version-0.62/layoutanimation.md | 560 ++++++++++++ .../version-0.62/linking-libraries-ios.md | 65 ++ .../versioned_docs/version-0.62/linking.md | 400 +++++++++ website/versioned_docs/version-0.62/modal.md | 366 ++++++++ .../version-0.62/more-resources.md | 44 + .../version-0.62/native-components-android.md | 191 ++++ .../version-0.62/native-components-ios.md | 512 +++++++++++ .../version-0.62/native-modules-android.md | 469 ++++++++++ .../version-0.62/native-modules-ios.md | 524 +++++++++++ .../version-0.62/native-modules-setup.md | 27 + .../versioned_docs/version-0.62/navigation.md | 119 +++ .../versioned_docs/version-0.62/network.md | 232 +++++ .../optimizing-flatlist-configuration.md | 152 ++++ .../version-0.62/out-of-tree-platforms.md | 44 + .../version-0.62/panresponder.md | 269 ++++++ .../version-0.62/performance.md | 109 +++ .../version-0.62/permissionsandroid.md | 259 ++++++ website/versioned_docs/version-0.62/picker.md | 128 +++ .../versioned_docs/version-0.62/pixelratio.md | 162 ++++ .../version-0.62/platform-specific-code.md | 137 +++ .../versioned_docs/version-0.62/profiling.md | 147 +++ .../version-0.62/progressbarandroid.md | 128 +++ .../version-0.62/progressviewios.md | 123 +++ website/versioned_docs/version-0.62/props.md | 56 ++ .../version-0.62/pushnotificationios.md | 506 +++++++++++ .../ram-bundles-inline-requires.md | 183 ++++ .../version-0.62/refreshcontrol.md | 171 ++++ .../removing-default-permissions.md | 61 ++ .../version-0.62/running-on-device.md | 316 +++++++ .../version-0.62/running-on-simulator-ios.md | 15 + .../version-0.62/safeareaview.md | 46 + .../versioned_docs/version-0.62/scrollview.md | 755 ++++++++++++++++ .../version-0.62/sectionlist.md | 499 +++++++++++ .../versioned_docs/version-0.62/security.md | 124 +++ .../versioned_docs/version-0.62/settings.md | 94 ++ .../version-0.62/shadow-props.md | 141 +++ website/versioned_docs/version-0.62/share.md | 156 ++++ .../version-0.62/signed-apk-android.md | 145 +++ website/versioned_docs/version-0.62/slider.md | 177 ++++ website/versioned_docs/version-0.62/state.md | 51 ++ .../versioned_docs/version-0.62/statusbar.md | 324 +++++++ .../version-0.62/statusbarios.md | 9 + website/versioned_docs/version-0.62/style.md | 47 + .../versioned_docs/version-0.62/stylesheet.md | 337 +++++++ website/versioned_docs/version-0.62/switch.md | 119 +++ .../versioned_docs/version-0.62/systrace.md | 198 ++++ .../versioned_docs/version-0.62/testing.md | 268 ++++++ .../version-0.62/text-style-props.md | 509 +++++++++++ website/versioned_docs/version-0.62/text.md | 697 ++++++++++++++ .../versioned_docs/version-0.62/textinput.md | 845 +++++++++++++++++ .../version-0.62/timepickerandroid.md | 72 ++ .../version-0.62/toastandroid.md | 200 +++++ .../version-0.62/touchablehighlight.md | 269 ++++++ .../version-0.62/touchablenativefeedback.md | 191 ++++ .../version-0.62/touchableopacity.md | 234 +++++ .../version-0.62/touchablewithoutfeedback.md | 369 ++++++++ .../versioned_docs/version-0.62/transforms.md | 298 ++++++ .../version-0.62/troubleshooting.md | 111 +++ .../versioned_docs/version-0.62/tutorial.md | 172 ++++ .../versioned_docs/version-0.62/typescript.md | 233 +++++ .../versioned_docs/version-0.62/upgrading.md | 124 +++ .../version-0.62/usecolorscheme.md | 28 + .../version-0.62/usewindowdimensions.md | 78 ++ .../version-0.62/using-a-listview.md | 98 ++ .../version-0.62/using-a-scrollview.md | 62 ++ .../versioned_docs/version-0.62/vibration.md | 241 +++++ .../version-0.62/view-style-props.md | 265 ++++++ website/versioned_docs/version-0.62/view.md | 648 +++++++++++++ .../version-0.62/viewpagerandroid.md | 181 ++++ .../version-0.62/virtualizedlist.md | 648 +++++++++++++ .../version-0.62-sidebars.json | 188 ++++ website/versions.json | 1 + yarn.lock | 4 + 126 files changed, 30380 insertions(+) create mode 100644 website/versioned_docs/version-0.62/accessibility.md create mode 100644 website/versioned_docs/version-0.62/accessibilityinfo.md create mode 100644 website/versioned_docs/version-0.62/actionsheetios.md create mode 100644 website/versioned_docs/version-0.62/activityindicator.md create mode 100644 website/versioned_docs/version-0.62/alert.md create mode 100644 website/versioned_docs/version-0.62/alertios.md create mode 100644 website/versioned_docs/version-0.62/animated.md create mode 100644 website/versioned_docs/version-0.62/animatedvalue.md create mode 100644 website/versioned_docs/version-0.62/animatedvaluexy.md create mode 100644 website/versioned_docs/version-0.62/animations.md create mode 100644 website/versioned_docs/version-0.62/appearance.md create mode 100644 website/versioned_docs/version-0.62/appregistry.md create mode 100644 website/versioned_docs/version-0.62/appstate.md create mode 100644 website/versioned_docs/version-0.62/asyncstorage.md create mode 100644 website/versioned_docs/version-0.62/backhandler.md create mode 100644 website/versioned_docs/version-0.62/building-for-apple-tv.md create mode 100644 website/versioned_docs/version-0.62/button.md create mode 100644 website/versioned_docs/version-0.62/checkbox.md create mode 100644 website/versioned_docs/version-0.62/clipboard.md create mode 100644 website/versioned_docs/version-0.62/colors.md create mode 100644 website/versioned_docs/version-0.62/communication-android.md create mode 100644 website/versioned_docs/version-0.62/communication-ios.md create mode 100644 website/versioned_docs/version-0.62/components-and-apis.md create mode 100644 website/versioned_docs/version-0.62/datepickerandroid.md create mode 100644 website/versioned_docs/version-0.62/datepickerios.md create mode 100644 website/versioned_docs/version-0.62/debugging.md create mode 100644 website/versioned_docs/version-0.62/devsettings.md create mode 100644 website/versioned_docs/version-0.62/dimensions.md create mode 100644 website/versioned_docs/version-0.62/direct-manipulation.md create mode 100644 website/versioned_docs/version-0.62/drawerlayoutandroid.md create mode 100644 website/versioned_docs/version-0.62/easing.md create mode 100644 website/versioned_docs/version-0.62/fast-refresh.md create mode 100644 website/versioned_docs/version-0.62/flatlist.md create mode 100644 website/versioned_docs/version-0.62/flexbox.md create mode 100644 website/versioned_docs/version-0.62/getting-started.md create mode 100644 website/versioned_docs/version-0.62/handling-text-input.md create mode 100644 website/versioned_docs/version-0.62/handling-touches.md create mode 100644 website/versioned_docs/version-0.62/headless-js-android.md create mode 100644 website/versioned_docs/version-0.62/height-and-width.md create mode 100644 website/versioned_docs/version-0.62/hermes.md create mode 100644 website/versioned_docs/version-0.62/image-style-props.md create mode 100644 website/versioned_docs/version-0.62/image.md create mode 100644 website/versioned_docs/version-0.62/imagebackground.md create mode 100644 website/versioned_docs/version-0.62/inputaccessoryview.md create mode 100644 website/versioned_docs/version-0.62/integration-with-existing-apps.md create mode 100644 website/versioned_docs/version-0.62/interactionmanager.md create mode 100644 website/versioned_docs/version-0.62/intro-react-native-components.md create mode 100644 website/versioned_docs/version-0.62/intro-react.md create mode 100644 website/versioned_docs/version-0.62/introduction.md create mode 100644 website/versioned_docs/version-0.62/javascript-environment.md create mode 100644 website/versioned_docs/version-0.62/keyboard.md create mode 100644 website/versioned_docs/version-0.62/keyboardavoidingview.md create mode 100644 website/versioned_docs/version-0.62/layout-props.md create mode 100644 website/versioned_docs/version-0.62/layoutanimation.md create mode 100644 website/versioned_docs/version-0.62/linking-libraries-ios.md create mode 100644 website/versioned_docs/version-0.62/linking.md create mode 100644 website/versioned_docs/version-0.62/modal.md create mode 100644 website/versioned_docs/version-0.62/more-resources.md create mode 100644 website/versioned_docs/version-0.62/native-components-android.md create mode 100644 website/versioned_docs/version-0.62/native-components-ios.md create mode 100644 website/versioned_docs/version-0.62/native-modules-android.md create mode 100644 website/versioned_docs/version-0.62/native-modules-ios.md create mode 100644 website/versioned_docs/version-0.62/native-modules-setup.md create mode 100644 website/versioned_docs/version-0.62/navigation.md create mode 100644 website/versioned_docs/version-0.62/network.md create mode 100644 website/versioned_docs/version-0.62/optimizing-flatlist-configuration.md create mode 100644 website/versioned_docs/version-0.62/out-of-tree-platforms.md create mode 100644 website/versioned_docs/version-0.62/panresponder.md create mode 100644 website/versioned_docs/version-0.62/performance.md create mode 100644 website/versioned_docs/version-0.62/permissionsandroid.md create mode 100644 website/versioned_docs/version-0.62/picker.md create mode 100644 website/versioned_docs/version-0.62/pixelratio.md create mode 100644 website/versioned_docs/version-0.62/platform-specific-code.md create mode 100644 website/versioned_docs/version-0.62/profiling.md create mode 100644 website/versioned_docs/version-0.62/progressbarandroid.md create mode 100644 website/versioned_docs/version-0.62/progressviewios.md create mode 100644 website/versioned_docs/version-0.62/props.md create mode 100644 website/versioned_docs/version-0.62/pushnotificationios.md create mode 100644 website/versioned_docs/version-0.62/ram-bundles-inline-requires.md create mode 100644 website/versioned_docs/version-0.62/refreshcontrol.md create mode 100644 website/versioned_docs/version-0.62/removing-default-permissions.md create mode 100644 website/versioned_docs/version-0.62/running-on-device.md create mode 100644 website/versioned_docs/version-0.62/running-on-simulator-ios.md create mode 100644 website/versioned_docs/version-0.62/safeareaview.md create mode 100644 website/versioned_docs/version-0.62/scrollview.md create mode 100644 website/versioned_docs/version-0.62/sectionlist.md create mode 100644 website/versioned_docs/version-0.62/security.md create mode 100644 website/versioned_docs/version-0.62/settings.md create mode 100644 website/versioned_docs/version-0.62/shadow-props.md create mode 100644 website/versioned_docs/version-0.62/share.md create mode 100644 website/versioned_docs/version-0.62/signed-apk-android.md create mode 100644 website/versioned_docs/version-0.62/slider.md create mode 100644 website/versioned_docs/version-0.62/state.md create mode 100644 website/versioned_docs/version-0.62/statusbar.md create mode 100644 website/versioned_docs/version-0.62/statusbarios.md create mode 100644 website/versioned_docs/version-0.62/style.md create mode 100644 website/versioned_docs/version-0.62/stylesheet.md create mode 100644 website/versioned_docs/version-0.62/switch.md create mode 100644 website/versioned_docs/version-0.62/systrace.md create mode 100644 website/versioned_docs/version-0.62/testing.md create mode 100644 website/versioned_docs/version-0.62/text-style-props.md create mode 100644 website/versioned_docs/version-0.62/text.md create mode 100644 website/versioned_docs/version-0.62/textinput.md create mode 100644 website/versioned_docs/version-0.62/timepickerandroid.md create mode 100644 website/versioned_docs/version-0.62/toastandroid.md create mode 100644 website/versioned_docs/version-0.62/touchablehighlight.md create mode 100644 website/versioned_docs/version-0.62/touchablenativefeedback.md create mode 100644 website/versioned_docs/version-0.62/touchableopacity.md create mode 100644 website/versioned_docs/version-0.62/touchablewithoutfeedback.md create mode 100644 website/versioned_docs/version-0.62/transforms.md create mode 100644 website/versioned_docs/version-0.62/troubleshooting.md create mode 100644 website/versioned_docs/version-0.62/tutorial.md create mode 100644 website/versioned_docs/version-0.62/typescript.md create mode 100644 website/versioned_docs/version-0.62/upgrading.md create mode 100644 website/versioned_docs/version-0.62/usecolorscheme.md create mode 100644 website/versioned_docs/version-0.62/usewindowdimensions.md create mode 100644 website/versioned_docs/version-0.62/using-a-listview.md create mode 100644 website/versioned_docs/version-0.62/using-a-scrollview.md create mode 100644 website/versioned_docs/version-0.62/vibration.md create mode 100644 website/versioned_docs/version-0.62/view-style-props.md create mode 100644 website/versioned_docs/version-0.62/view.md create mode 100644 website/versioned_docs/version-0.62/viewpagerandroid.md create mode 100644 website/versioned_docs/version-0.62/virtualizedlist.md create mode 100644 website/versioned_sidebars/version-0.62-sidebars.json create mode 100644 yarn.lock diff --git a/website/versioned_docs/version-0.62/accessibility.md b/website/versioned_docs/version-0.62/accessibility.md new file mode 100644 index 00000000000..3277391856e --- /dev/null +++ b/website/versioned_docs/version-0.62/accessibility.md @@ -0,0 +1,306 @@ +--- +id: version-0.62-accessibility +title: Accessibility +description: Create mobile apps accessible to assistive technology with React Native's suite of APIs designed to work with Android and iOS. +original_id: accessibility +--- + +Both Android and iOS provide APIs for integrating apps with assitive technologies like the bundled screen readers VoiceOver (iOS) and Talkback (Android). React Native has complimentary APIs that let your app accommodate all users. + +> Android and iOS differ slightly in their approaches, and thus the React Native implementations may vary by platform. + +## Accessibility properties + +### accessible (iOS, Android) + +When `true`, indicates that the view is an accessibility element. When a view is an accessibility element, it groups its children into a single selectable component. By default, all touchable elements are accessible. + +On Android, `accessible={true}` property for a react-native View will be translated into native `focusable={true}`. + +```jsx + + text one + text two + +``` + +In the above example, we can't get accessibility focus separately on 'text one' and 'text two'. Instead we get focus on a parent view with 'accessible' property. + +### accessibilityLabel (iOS, Android) + +When a view is marked as accessible, it is a good practice to set an accessibilityLabel on the view, so that people who use VoiceOver know what element they have selected. VoiceOver will read this string when a user selects the associated element. + +To use, set the `accessibilityLabel` property to a custom string on your View, Text or Touchable: + +```jsx + + + Press me! + + +``` + +In the above example, the `accessibilityLabel` on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces. + +### accessibilityHint (iOS, Android) + +An accessibility hint helps users understand what will happen when they perform an action on the accessibility element when that result is not clear from the accessibility label. + +To use, set the `accessibilityHint` property to a custom string on your View, Text or Touchable: + +```jsx + + + Back + + +``` + +iOS In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for accessibilityHint in the [iOS Developer Docs](https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint) + +Android In the above example, Talkback will read the hint after the label. At this time, hints cannot be turned off on Android. + +### accessibilityIgnoresInvertColors(iOS) + +Inverting screen colors is an Accessibility feature that makes the iPhone and iPad easier on the eyes for some people with a sensitivity to brightness, easier to distinguish for some people with color blindness, and easier to make out for some people with low vision. However, sometimes you have views such as photos that you don't want to be inverted. In this case, you can set this property to be false so that these specific views won't have their colors inverted. + +### accessibilityRole (iOS, Android) + +`accessibilityRole` communicates the purpose of a component to the user of an assistive technology. + +`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. +- **link** Used when the element should be treated as a link. +- **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. +- **keyboardkey** Used when the element acts as a keyboard key. +- **text** Used when the element should be treated as static text that cannot change. +- **adjustable** Used when an element can be "adjusted" (e.g. a slider). +- **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). + +### accessibilityState (iOS, Android) + +Describes the current state of a component to the user of an assistive technology. + +`accessibilityState` is an object. It contains the following fields: + +| Name | Description | Type | Required | +| -------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------- | +| disabled | Indicates whether the element is disabled or not. | boolean | No | +| selected | Indicates whether a selectable element is currently selected or not. | boolean | No | +| checked | Indicates the state of a checkable element. This field can either take a boolean or the "mixed" string to represent mixed checkboxes. | boolean or 'mixed' | No | +| busy | Indicates whether an element is currently busy or not. | boolean | No | +| expanded | Indicates whether an expandable element is currently expanded or collapsed. | boolean | No | + +To use, set the `accessibilityState` to an object with a specific definition. + +### accessibilityValue (iOS, Android) + +Represents the current value of a component. It can be a textual description of a component's value, or for range-based components, such as sliders and progress bars, it contains range information (minimum, current, and maximum). + +`accessibilityValue` is an object. It contains the following fields: + +| Name | Description | Type | Required | +| ---- | ---------------------------------------------------------------------------------------------- | ------- | ------------------------- | +| min | The minimum value of this component's range. | integer | Required if `now` is set. | +| max | The maximum value of this component's range. | integer | Required if `now` is set. | +| now | The current value of this component's range. | integer | No | +| text | A textual description of this component's value. Will override `min`, `now`, and `max` if set. | string | No | + +### accessibilityViewIsModal (iOS) + +A Boolean value indicating whether VoiceOver should ignore the elements within views that are siblings of the receiver. + +For example, in a window that contains sibling views `A` and `B`, setting `accessibilityViewIsModal` to `true` on view `B` causes VoiceOver to ignore the elements in the view `A`. On the other hand, if view `B` contains a child view `C` and you set `accessibilityViewIsModal` to `true` on view `C`, VoiceOver does not ignore the elements in view `A`. + +### accessibilityElementsHidden (iOS) + +A Boolean value indicating whether the accessibility elements contained within this accessibility element are hidden. + +For example, in a window that contains sibling views `A` and `B`, setting `accessibilityElementsHidden` to `true` on view `B` causes VoiceOver to ignore the elements in the view `B`. This is similar to the Android property `importantForAccessibility="no-hide-descendants"`. + +### onAccessibilityTap (iOS, Android) + +Use this property to assign a custom function to be called when someone activates an accessible element by double tapping on it while it's selected. + +### onMagicTap (iOS) + +Assign this property to a custom function which will be called when someone performs the "magic tap" gesture, which is a double-tap with two fingers. A magic tap function should perform the most relevant action a user could take on a component. In the Phone app on iPhone, a magic tap answers a phone call, or ends the current one. If the selected element does not have an `onMagicTap` function, the system will traverse up the view hierarchy until it finds a view that does. + +### onAccessibilityEscape (iOS) + +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. + +### accessibilityLiveRegion (Android) + +When components dynamically change, we want TalkBack to alert the end user. This is made possible by the ‘accessibilityLiveRegion’ property. It can be set to ‘none’, ‘polite’ and ‘assertive’: + +- **none** Accessibility services should not announce changes to this view. +- **polite** Accessibility services should announce changes to this view. +- **assertive** Accessibility services should interrupt ongoing speech to immediately announce changes to this view. + +```jsx + + + Click me + + + + Clicked {this.state.count} times + +``` + +In the above example method \_addOne changes the state.count variable. As soon as an end user clicks the TouchableWithoutFeedback, TalkBack reads text in the Text view because of its 'accessibilityLiveRegion=”polite”' property. + +### importantForAccessibility (Android) + +In the case of two overlapping UI components with the same parent, default accessibility focus can have unpredictable behavior. The ‘importantForAccessibility’ property will resolve this by controlling if a view fires accessibility events and if it is reported to accessibility services. It can be set to ‘auto’, ‘yes’, ‘no’ and ‘no-hide-descendants’ (the last value will force accessibility services to ignore the component and all of its children). + +```jsx + + + First layout + + + Second layout + + +``` + +In the above example, the yellow layout and its descendants are completely invisible to TalkBack and all other accessibility services. So we can 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) for details. + +## Sending Accessibility Events (Android) + +Sometimes it is useful to trigger an accessibility event on a UI component (i.e. when a custom view appears on a screen or set accessibility focus to a view). Native UIManager module exposes a method ‘sendAccessibilityEvent’ for this purpose. It takes two arguments: view tag and a type of an event. The supported event types are `typeWindowStateChanged`, `typeViewFocused` and `typeViewClicked`. + +```jsx +import { Platform, UIManager, findNodeHandle } from 'react-native'; + +if (Platform.OS === 'android') { + UIManager.sendAccessibilityEvent( + findNodeHandle(this), + UIManager.AccessibilityEventTypes.typeViewFocused); + } +} +``` + +## Testing VoiceOver Support (iOS) + +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 +``` + +## Additional Resources + +- [Making React Native Apps Accessible](https://engineering.fb.com/ios/making-react-native-apps-accessible/) diff --git a/website/versioned_docs/version-0.62/accessibilityinfo.md b/website/versioned_docs/version-0.62/accessibilityinfo.md new file mode 100644 index 00000000000..7e5c602782f --- /dev/null +++ b/website/versioned_docs/version-0.62/accessibilityinfo.md @@ -0,0 +1,279 @@ +--- +id: version-0.62-accessibilityinfo +title: AccessibilityInfo +original_id: accessibilityinfo +--- + +Sometimes it's useful to know whether or not the device has a screen reader that is currently active. The `AccessibilityInfo` API is designed for this purpose. You can use it to query the current state of the screen reader as well as to register to be notified when the state of the screen reader changes. + +## Example + +
+
    + + +
+
+ + + +```SnackPlayer name=AccessibilityInfo%20Function%20Component%20Example + +import React, { useState, useEffect } from "react"; +import { AccessibilityInfo, View, Text, StyleSheet } from "react-native"; + +export default function App() { + const [reduceMotionEnabled, setReduceMotionEnabled] = useState(false); + const [screenReaderEnabled, setScreenReaderEnabled] = useState(false); + + useEffect(() => { + AccessibilityInfo.addEventListener( + "reduceMotionChanged", + handleReduceMotionToggled + ); + AccessibilityInfo.addEventListener( + "screenReaderChanged", + handleScreenReaderToggled + ); + + AccessibilityInfo.fetch().then(reduceMotionEnabled => { + setReduceMotionEnabled(reduceMotionEnabled); + }); + AccessibilityInfo.fetch().then(screenReaderEnabled => { + setScreenReaderEnabled(screenReaderEnabled); + }); + return () => { + AccessibilityInfo.removeEventListener( + "reduceMotionChanged", + handleReduceMotionToggled + ); + + AccessibilityInfo.removeEventListener( + "screenReaderChanged", + handleScreenReaderToggled + ); + }; + }, []); + + const handleReduceMotionToggled = reduceMotionEnabled => { + setReduceMotionEnabled(reduceMotionEnabled); + }; + + const handleScreenReaderToggled = screenReaderEnabled => { + setScreenReaderEnabled(screenReaderEnabled); + }; + + return ( + + + The reduce motion is {reduceMotionEnabled ? "enabled" : "disabled"}. + + + The screen reader is {screenReaderEnabled ? "enabled" : "disabled"}. + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center" + }, + status: { + margin: 30 + } +}); +``` + + + +```SnackPlayer name=AccessibilityInfo%20Class%20Component%20Example + +import React from 'react'; +import { AccessibilityInfo, View, Text, StyleSheet } from 'react-native'; + +export default class AccessibilityStatusExample extends React.Component { + state = { + reduceMotionEnabled: false, + screenReaderEnabled: false, + }; + + componentDidMount() { + AccessibilityInfo.addEventListener( + 'reduceMotionChanged', + this._handleReduceMotionToggled + ); + AccessibilityInfo.addEventListener( + 'screenReaderChanged', + this._handleScreenReaderToggled + ); + + AccessibilityInfo.fetch().then(reduceMotionEnabled => { + this.setState({ reduceMotionEnabled }); + }); + AccessibilityInfo.fetch().then(screenReaderEnabled => { + this.setState({ screenReaderEnabled }); + }); + } + + componentWillUnmount() { + AccessibilityInfo.removeEventListener( + 'reduceMotionChanged', + this._handleReduceMotionToggled + ); + + AccessibilityInfo.removeEventListener( + 'screenReaderChanged', + this._handleScreenReaderToggled + ); + } + + _handleReduceMotionToggled = reduceMotionEnabled => { + this.setState({ reduceMotionEnabled }); + }; + + _handleScreenReaderToggled = screenReaderEnabled => { + this.setState({ screenReaderEnabled }); + }; + + render() { + return ( + + + The reduce motion is{' '} + {this.state.reduceMotionEnabled ? 'enabled' : 'disabled'}. + + + The screen reader is{' '} + {this.state.screenReaderEnabled ? 'enabled' : 'disabled'}. + + + ); + } + + styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + status: { + margin: 30, + }, + }); +} +``` + + + +--- + +# Reference + +## Methods + +### `isBoldTextEnabled()` + +```jsx +static isBoldTextEnabled() +``` + +**iOS-Only.** Query whether a bold text is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when bold text is enabled and `false` otherwise. + +### `isGrayscaleEnabled()` + +```jsx +static isGrayscaleEnabled() +``` + +**iOS-Only.** Query whether grayscale is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when grayscale is enabled and `false` otherwise. + +### `isInvertColorsEnabled()` + +```jsx +static isInvertColorsEnabled() +``` + +**iOS-Only.** Query whether invert colors is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when invert colors is enabled and `false` otherwise. + +### `isReduceMotionEnabled()` + +```jsx +static isReduceMotionEnabled() +``` + +Query whether reduce motion is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when reduce motion is enabled and `false` otherwise. + +### `isReduceTransparencyEnabled()` + +```jsx +static isReduceTransparencyEnabled() +``` + +**iOS-Only.** Query whether reduce transparency is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when a reduce transparency is enabled and `false` otherwise. + +### `isScreenReaderEnabled()` + +```jsx +static isScreenReaderEnabled() +``` + +Query whether a screen reader is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when a screen reader is enabled and `false` otherwise. + +--- + +### `addEventListener()` + +```jsx +static addEventListener(eventName, handler) +``` + +Add an event handler. Supported events: + +- `boldTextChanged`: iOS-only event. Fires when the state of the bold text toggle changes. The argument to the event handler is a boolean. The boolean is `true` when bold text is enabled and `false` otherwise. +- `grayscaleChanged`: iOS-only event. Fires when the state of the gray scale toggle changes. The argument to the event handler is a boolean. The boolean is `true` when a gray scale is enabled and `false` otherwise. +- `invertColorsChanged`: iOS-only event. Fires when the state of the invert colors toggle changes. The argument to the event handler is a boolean. The boolean is `true` when invert colors is enabled and `false` otherwise. +- `reduceMotionChanged`: Fires when the state of the reduce motion toggle changes. The argument to the event handler is a boolean. The boolean is `true` when a reduce motion is enabled (or when "Transition Animation Scale" in "Developer options" is "Animation off") and `false` otherwise. +- `screenReaderChanged`: Fires when the state of the screen reader changes. The argument to the event handler is a boolean. The boolean is `true` when a screen reader is enabled and `false` otherwise. +- `reduceTransparencyChanged`: iOS-only event. Fires when the state of the reduce transparency toggle changes. The argument to the event handler is a boolean. The boolean is `true` when reduce transparency is enabled and `false` otherwise. +- `announcementFinished`: iOS-only event. Fires when the screen reader has finished making an announcement. The argument to the event handler is a dictionary with these keys: + - `announcement`: The string announced by the screen reader. + - `success`: A boolean indicating whether the announcement was successfully made. + +--- + +### `setAccessibilityFocus()` + +```jsx +static setAccessibilityFocus(reactTag) +``` + +Set accessibility focus to a React component. On Android, this calls `UIManager.sendAccessibilityEvent(reactTag, UIManager.AccessibilityEventTypes.typeViewFocused);`. + +> **Note**: Make sure that any `View` you want to receive the accessibility focus has `accessible={true}`. + +--- + +### `announceForAccessibility()` + +```jsx +static announceForAccessibility(announcement) +``` + +Post a string to be announced by the screen reader. + +--- + +### `removeEventListener()` + +```jsx +static removeEventListener(eventName, handler) +``` + +Remove an event handler. diff --git a/website/versioned_docs/version-0.62/actionsheetios.md b/website/versioned_docs/version-0.62/actionsheetios.md new file mode 100644 index 00000000000..82fbb5bc526 --- /dev/null +++ b/website/versioned_docs/version-0.62/actionsheetios.md @@ -0,0 +1,117 @@ +--- +id: version-0.62-actionsheetios +title: ActionSheetIOS +original_id: actionsheetios +--- + +Displays native to iOS [Action Sheet](https://developer.apple.com/design/human-interface-guidelines/ios/views/action-sheets/) component. + +## Example + +```SnackPlayer name=ActionSheetIOS&supportedPlatforms=ios +import React, { useState } from "react"; +import { ActionSheetIOS, Button, StyleSheet, Text, View } from "react-native"; + +export default App = () => { + const [result, setResult] = useState("🔮"); + + const onPress = () => + ActionSheetIOS.showActionSheetWithOptions( + { + options: ["Cancel", "Generate number", "Reset"], + destructiveButtonIndex: 2, + cancelButtonIndex: 0 + }, + buttonIndex => { + if (buttonIndex === 0) { + // cancel action + } else if (buttonIndex === 1) { + setResult(Math.floor(Math.random() * 100) + 1); + } else if (buttonIndex === 2) { + setResult("🔮"); + } + } + ); + + return ( + + {result} + + + + + + + + +> The `Appearance` API is inspired by the [Media Queries draft](https://drafts.csswg.org/mediaqueries-5/) from the W3C. The color scheme preference is modeled after the [`prefers-color-scheme` CSS media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme). + + + +> The color scheme preference will map to the user's Light or [Dark theme](https://developer.android.com/guide/topics/ui/look-and-feel/darktheme) preference on Android 10 (API level 29) devices and higher. + + + +> The color scheme preference will map to the user's Light or [Dark Mode](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/dark-mode/) preference on iOS 13 devices and higher. + + + +## Example + +You can use the `Appearance` module to determine if the user prefers a dark color scheme: + +```jsx +const colorScheme = Appearance.getColorScheme(); +if (colorScheme === 'dark') { + // Use dark color scheme +} +``` + +Although the color scheme is available immediately, this may change (e.g. scheduled color scheme change at sunrise or sunset). Any rendering logic or styles that depend on the user preferred color scheme should try to call this function on every render, rather than caching the value. For example, you may use the [`useColorScheme`](usecolorscheme) React hook as it provides and subscribes to color scheme updates, or you may use inline styles rather than setting a value in a `StyleSheet`. + +# Reference + +## Methods + +### `getColorScheme()` + +```jsx +static getColorScheme() +``` + +Indicates the current user preferred color scheme. The value may be updated later, either through direct user action (e.g. theme selection in device settings) or on a schedule (e.g. light and dark themes that follow the day/night cycle). + +Supported color schemes: + +- `light`: The user prefers a light color theme. +- `dark`: The user prefers a dark color theme. +- null: The user has not indicated a preferred color theme. + +See also: `useColorScheme` hook. diff --git a/website/versioned_docs/version-0.62/appregistry.md b/website/versioned_docs/version-0.62/appregistry.md new file mode 100644 index 00000000000..7e58c77c265 --- /dev/null +++ b/website/versioned_docs/version-0.62/appregistry.md @@ -0,0 +1,324 @@ +--- +id: version-0.62-appregistry +title: AppRegistry +original_id: appregistry +--- + + + +`AppRegistry` is the JS entry point to running all React Native apps. App root components should register themselves with `AppRegistry.registerComponent`, then the native system can load the bundle for the app and then actually run the app when it's ready by invoking `AppRegistry.runApplication`. + +```jsx +import {Text, AppRegistry} from 'react-native'; + +const App = (props) => ( + + App1 + +); + +AppRegistry.registerComponent('Appname', () => App); +``` + +To "stop" an application when a view should be destroyed, call `AppRegistry.unmountApplicationComponentAtRootTag` with the tag that was passed into `runApplication`. These should always be used as a pair. + +`AppRegistry` should be required early in the `require` sequence to make sure the JS execution environment is setup before other modules are required. + +--- + +# Reference + +## Methods + +### `setWrapperComponentProvider()` + +```jsx +static setWrapperComponentProvider(provider) +``` + +**Parameters:** + +| Name | Type | Required | +| -------- | ----------------- | -------- | +| provider | ComponentProvider | yes | + +--- + +### `enableArchitectureIndicator()` + +```jsx +static enableArchitectureIndicator(enabled) +``` + +**Parameters:** + +| Name | Type | Required | +| ------- | ------- | -------- | +| enabled | boolean | yes | + +--- + +### `registerConfig()` + +```jsx +static registerConfig([config]) +``` + +**Parameters:** + +| Name | Type | Required | Description | +| ------ | --------- | -------- | ----------- | +| config | AppConfig | yes | See below. | + +Valid `AppConfig` keys are: + +- 'appKey' (string)- Required. +- 'component' (ComponentProvider) - Optional. +- 'run' (Function) - Optional. +- 'section' (boolean) - Optional. + +--- + +### `registerComponent()` + +```jsx +static registerComponent(appKey, componentProvider, section?) +``` + +**Parameters:** + +| Name | Type | Required | +| ----------------- | ----------------- | -------- | +| appKey | string | yes | +| componentProvider | ComponentProvider | yes | +| section | boolean | no | + +--- + +### `registerRunnable()` + +```jsx +static registerRunnable(appKey, run) +``` + +**Parameters:** + +| Name | Type | Required | +| ------ | -------- | -------- | +| appKey | string | yes | +| run | Function | yes | + +--- + +### `registerSection()` + +```jsx +static registerSection(appKey, component) +``` + +**Parameters:** + +| Name | Type | Required | +| --------- | ----------------- | -------- | +| appKey | string | yes | +| component | ComponentProvider | yes | + +--- + +### `getAppKeys()` + +```jsx +static getAppKeys() +``` + +Returns an Array of AppKeys + +### `getSectionKeys()` + +```jsx +static getSectionKeys() +``` + +Returns an Array of SectionKeys + +--- + +### `getSections()` + +```jsx +static getSections() +``` + +Returns all Runnables which is an object with key of `AppKeys` and value of type of `Runnable` which consist of: + +- 'component' (ComponentProvider). +- 'run' (Function). + +--- + +### `getRunnable()` + +```jsx +static getRunnable(appKey) +``` + +Returns a `Runnable` object which consist of: + +- 'component' (ComponentProvider). +- 'run' (Function). + +--- + +### `getRegistry()` + +```jsx +static getRegistry() +``` + +Returns a type `Registry` which consist of: + +- 'sections' (Array of strings). +- 'runnables' (Runnables). + +--- + +### `setComponentProviderInstrumentationHook()` + +```jsx +static setComponentProviderInstrumentationHook(hook) +``` + +**Parameters:** + +| Name | Type | Required | Description | +| ---- | -------- | -------- | ----------- | +| hook | Function | yes | See below. | + +A valid `hook` accepts the following as arguments: + +- 'component' (ComponentProvider)- Required. +- 'scopedPerformanceLogger' (IPerformanceLogger)- Required. + +The `hook` function returns a React Component + +--- + +### `runApplication()` + +```jsx +static runApplication(appKey, appParameters) +``` + +Loads the JavaScript bundle and runs the app. + +**Parameters:** + +| Name | Type | Required | +| ------------- | ------ | -------- | +| appKey | string | yes | +| appParameters | any | yes | + +--- + +### `unmountApplicationComponentAtRootTag()` + +```jsx +static unmountApplicationComponentAtRootTag(rootTag) +``` + +Stops an application when a view should be destroyed. + +**Parameters:** + +| Name | Type | Required | +| ------- | ------ | -------- | +| rootTag | number | yes | + +--- + +### `registerHeadlessTask()` + +```jsx +static registerHeadlessTask(taskKey, taskProvider) +``` + +Register a headless task. A headless task is a bit of code that runs without a UI. @param taskKey the key associated with this task @param taskProvider a promise returning function that takes some data passed from the native side as the only argument; when the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. + +This 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. + +**Parameters:** + +| Name | Type | Required | Description | +| ------------ | ------------ | -------- | ----------- | +| taskKey | String | yes | See below. | +| taskProvider | TaskProvider | yes | See below. | + +- A valid `TaskProvider` is a function that returns a `Task`. +- A `Task` is a function that accepts any data as argument and returns a Promise that resolves to undefined. + +--- + +### `registerCancellableHeadlessTask()` + +```jsx +static registerCancellableHeadlessTask(taskKey, taskProvider, taskCancelProvider) +``` + +Register a headless task which can be cancelled. A headless task is a bit of code that runs without a UI. @param taskKey the key associated with this task @param taskProvider a promise returning function that takes some data passed from the native side as the only argument; when the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. @param taskCancelProvider a void returning function that takes no arguments; when a cancellation is requested, the function being executed by taskProvider should wrap up and return ASAP. + +**Parameters:** + +| Name | Type | Required | Description | +| ------------------ | ------------------ | -------- | ----------- | +| taskKey | String | yes | See below. | +| taskProvider | TaskProvider | yes | See below. | +| taskCancelProvider | TaskCancelProvider | yes | See below. | + +- A valid `TaskProvider` is a function that returns a `Task`. +- A `Task` is a function that accepts any data as argument and returns a Promise that resolves to undefined. +- A valid `TaskCancelProvider` is a function that returns a `TaskCanceller`. +- A `TaskCanceller` is a function that accepts no argument and returns void. + +--- + +### `startHeadlessTask()` + +```jsx +static startHeadlessTask(taskId, taskKey, data) +``` + +Only called from native code. Starts a headless task. + +@param taskId the native id for this task instance to keep track of its execution @param taskKey the key for the task to start @param data the data to pass to the task + +**Parameters:** + +| Name | Type | Required | +| ------- | ------ | -------- | +| taskId | number | yes | +| taskKey | string | yes | +| data | any | yes | + +--- + +### `cancelHeadlessTask()` + +```jsx +static cancelHeadlessTask(taskId, taskKey) +``` + +Only called from native code. Cancels a headless task. + +@param taskId the native id for this task instance that was used when startHeadlessTask was called @param taskKey the key for the task that was used when startHeadlessTask was called + +**Parameters:** + +| Name | Type | Required | +| ------- | ------ | -------- | +| taskId | number | yes | +| taskKey | string | yes | diff --git a/website/versioned_docs/version-0.62/appstate.md b/website/versioned_docs/version-0.62/appstate.md new file mode 100644 index 00000000000..a72d1818c33 --- /dev/null +++ b/website/versioned_docs/version-0.62/appstate.md @@ -0,0 +1,180 @@ +--- +id: version-0.62-appstate +title: AppState +original_id: appstate +--- + +`AppState` can tell you if the app is in the foreground or background, and notify you when the state changes. + +AppState is frequently used to determine the intent and proper behavior when handling push notifications. + +### App States + +- `active` - The app is running in the foreground +- `background` - The app is running in the background. The user is either: + - in another app + - on the home screen + - [Android] on another `Activity` (even if it was launched by your app) +- [iOS] `inactive` - This is a state that occurs when transitioning between foreground & background, and during periods of inactivity such as entering the Multitasking view or in the event of an incoming call + +For more information, see [Apple's documentation](https://developer.apple.com/documentation/uikit/app_and_scenes/managing_your_app_s_life_cycle) + +## Basic Usage + +To see the current state, you can check `AppState.currentState`, which will be kept up-to-date. However, `currentState` will be null at launch while `AppState` retrieves it over the bridge. + +
+
    + + +
+
+ + + +```SnackPlayer name=AppState%20Function%20Component%20Example +import React, { useEffect, useState } from "react"; +import { AppState, StyleSheet, Text, View } from "react-native"; + +const AppStateExample = () => { + const [appState, setAppState] = useState(AppState.currentState); + + useEffect(() => { + AppState.addEventListener("change", _handleAppStateChange); + + return () => { + AppState.removeEventListener("change", _handleAppStateChange); + }; + }, []); + + const _handleAppStateChange = nextAppState => { + if (appState.match(/inactive|background/) && nextAppState === "active") { + console.log("App has come to the foreground!"); + } + setAppState(nextAppState); + }; + + return ( + + Current state is: {appState} + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: "center", + alignItems: "center" + } +}); + +export default AppStateExample; +``` + + + +```SnackPlayer name=AppState%20Class%20Component%20Example +import React, { Component } from "react"; +import { AppState, StyleSheet, Text, View } from "react-native"; + +export default class AppStateExample extends Component { + state = { + appState: AppState.currentState + }; + + componentDidMount() { + AppState.addEventListener("change", this._handleAppStateChange); + } + + componentWillUnmount() { + AppState.removeEventListener("change", this._handleAppStateChange); + } + + _handleAppStateChange = nextAppState => { + if ( + this.state.appState.match(/inactive|background/) && + nextAppState === "active" + ) { + console.log("App has come to the foreground!"); + } + this.setState({ appState: nextAppState }); + }; + + render() { + return ( + + Current state is: {this.state.appState} + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: "center", + alignItems: "center" + } +}); +``` + + + +This example will only ever appear to say "Current state is: active" because the app is only visible to the user when in the `active` state, and the null state will happen only momentarily. + +--- + +# Reference + +## Events + +### `change` + +This event is received when the app state has changed. The listener is called with one of [the current app state values](appstate#app-states). + +### `memoryWarning` + +This event is used in the need of throwing memory warning or releasing it. + +### `focus` + +[Android only] Received when the app gains focus (the user is interacting with the app). + +### `blur` + +[Android only] Received when the user is not actively interacting with the app. Useful in situations when the user pulls down the [notification drawer](https://developer.android.com/guide/topics/ui/notifiers/notifications#bar-and-drawer). `AppState` won't change but the `blur` event will get fired. + +## Methods + +### `addEventListener()` + +```jsx +addEventListener(type, handler); +``` + +Add a handler to AppState changes by listening to the `change` event type and providing the handler + +TODO: now that AppState is a subclass of NativeEventEmitter, we could deprecate `addEventListener` and `removeEventListener` and use `addListener` and `listener.remove()` directly. That will be a breaking change though, as both the method and event names are different (addListener events are currently required to be globally unique). + +--- + +### `removeEventListener()` + +```jsx +removeEventListener(type, handler); +``` + +Remove a handler by passing the `change` event type and the handler + +## Properties + +### `currentState` + +```jsx +AppState.currentState; +``` diff --git a/website/versioned_docs/version-0.62/asyncstorage.md b/website/versioned_docs/version-0.62/asyncstorage.md new file mode 100644 index 00000000000..d916ab1aaea --- /dev/null +++ b/website/versioned_docs/version-0.62/asyncstorage.md @@ -0,0 +1,355 @@ +--- +id: version-0.62-asyncstorage +title: 🚧 AsyncStorage +original_id: asyncstorage +--- + +> **Deprecated.** Use [@react-native-community/async-storage](https://github.com/react-native-community/react-native-async-storage) instead. + +`AsyncStorage` is an unencrypted, asynchronous, persistent, key-value storage system that is global to the app. It should be used instead of LocalStorage. + +It is recommended that you use an abstraction on top of `AsyncStorage` instead of `AsyncStorage` directly for anything more than light usage since it operates globally. + +On iOS, `AsyncStorage` is backed by native code that stores small values in a serialized dictionary and larger values in separate files. On Android, `AsyncStorage` will use either [RocksDB](http://rocksdb.org/) or SQLite based on what is available. + +The `AsyncStorage` JavaScript code is a facade that provides a clear JavaScript API, real `Error` objects, and non-multi functions. Each method in the API returns a `Promise` object. + +Importing the `AsyncStorage` library: + +```jsx +import {AsyncStorage} from 'react-native'; +``` + +Persisting data: + +```jsx +_storeData = async () => { + try { + await AsyncStorage.setItem('@MySuperStore:key', 'I like to save it.'); + } catch (error) { + // Error saving data + } +}; +``` + +Fetching data: + +```jsx +_retrieveData = async () => { + try { + const value = await AsyncStorage.getItem('TASKS'); + if (value !== null) { + // We have data!! + console.log(value); + } + } catch (error) { + // Error retrieving data + } +}; +``` + +--- + +# Reference + +## Methods + +### `getItem()` + +```jsx +static getItem(key: string, [callback]: ?(error: ?Error, result: ?string) => void) +``` + +Fetches an item for a `key` and invokes a callback upon completion. Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | ----------------------------------------- | -------- | ----------------------------------------------------------------- | +| key | string | Yes | Key of the item to fetch. | +| callback | ?(error: ?Error, result: ?string) => void | No | Function that will be called with a result if found or any error. | + +--- + +### `setItem()` + +```jsx +static setItem(key: string, value: string, [callback]: ?(error: ?Error) => void) +``` + +Sets the value for a `key` and invokes a callback upon completion. Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | ------------------------ | -------- | -------------------------------------------- | +| key | string | Yes | Key of the item to set. | +| value | string | Yes | Value to set for the `key`. | +| callback | ?(error: ?Error) => void | No | Function that will be called with any error. | + +--- + +### `removeItem()` + +```jsx +static removeItem(key: string, [callback]: ?(error: ?Error) => void) +``` + +Removes an item for a `key` and invokes a callback upon completion. Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | ------------------------ | -------- | -------------------------------------------- | +| key | string | Yes | Key of the item to remove. | +| callback | ?(error: ?Error) => void | No | Function that will be called with any error. | + +--- + +### `mergeItem()` + +```jsx +static mergeItem(key: string, value: string, [callback]: ?(error: ?Error) => void) +``` + +Merges an existing `key` value with an input value, assuming both values are stringified JSON. Returns a `Promise` object. + +**NOTE:** This is not supported by all native implementations. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | ------------------------ | -------- | -------------------------------------------- | +| key | string | Yes | Key of the item to modify. | +| value | string | Yes | New value to merge for the `key`. | +| callback | ?(error: ?Error) => void | No | Function that will be called with any error. | + +Example: + +```jsx +let UID123_object = { + name: 'Chris', + age: 30, + traits: {hair: 'brown', eyes: 'brown'}, +}; +// You only need to define what will be added or updated +let UID123_delta = { + age: 31, + traits: {eyes: 'blue', shoe_size: 10}, +}; + +AsyncStorage.setItem('UID123', JSON.stringify(UID123_object), () => { + AsyncStorage.mergeItem('UID123', JSON.stringify(UID123_delta), () => { + AsyncStorage.getItem('UID123', (err, result) => { + console.log(result); + }); + }); +}); + +// Console log result: +// => {'name':'Chris','age':31,'traits': +// {'shoe_size':10,'hair':'brown','eyes':'blue'}} +``` + +--- + +### `clear()` + +```jsx +static clear([callback]: ?(error: ?Error) => void) +``` + +Erases _all_ `AsyncStorage` for all clients, libraries, etc. You probably don't want to call this; use `removeItem` or `multiRemove` to clear only your app's keys. Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | ------------------------ | -------- | -------------------------------------------- | +| callback | ?(error: ?Error) => void | No | Function that will be called with any error. | + +--- + +### `getAllKeys()` + +```jsx +static getAllKeys([callback]: ?(error: ?Error, keys: ?Array) => void) +``` + +Gets _all_ keys known to your app; for all callers, libraries, etc. Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | ---------------------------------------------- | -------- | --------------------------------------------------------------- | +| callback | ?(error: ?Error, keys: ?Array) => void | No | Function that will be called with all keys found and any error. | + +--- + +### `flushGetRequests()` + +```jsx +static flushGetRequests(): [object Object] +``` + +Flushes any pending requests using a single batch call to get the data. + +--- + +### `multiGet()` + +```jsx +static multiGet(keys: Array, [callback]: ?(errors: ?Array, result: ?Array>) => void) +``` + +This allows you to batch the fetching of items given an array of `key` inputs. Your callback will be invoked with an array of corresponding key-value pairs found: + +``` +multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']]) +``` + +The method returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | --------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------- | +| keys | Array | Yes | Array of key for the items to get. | +| callback | ?(errors: ?Array, result: ?Array>) => void | No | Function that will be called with a key-value array of the results, plus an array of any key-specific errors found. | + +Example: + +```jsx +AsyncStorage.getAllKeys((err, keys) => { + AsyncStorage.multiGet(keys, (err, stores) => { + stores.map((result, i, store) => { + // get at each store's key/value so you can work with it + let key = store[i][0]; + let value = store[i][1]; + }); + }); +}); +``` + +--- + +### `multiSet()` + +```jsx +static multiSet(keyValuePairs: Array>, [callback]: ?(errors: ?Array) => void) +``` + +Use this as a batch operation for storing multiple key-value pairs. When the operation completes you'll get a single callback with any errors: + +``` +multiSet([['k1', 'val1'], ['k2', 'val2']], cb); +``` + +The method returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| ------------- | -------------------------------- | -------- | ---------------------------------------------------------------------------- | +| keyValuePairs | Array> | Yes | Array of key-value array for the items to set. | +| callback | ?(errors: ?Array) => void | No | Function that will be called with an array of any key-specific errors found. | + +--- + +### `multiRemove()` + +```jsx +static multiRemove(keys: Array, [callback]: ?(errors: ?Array) => void) +``` + +Call this to batch the deletion of all keys in the `keys` array. Returns a `Promise` object. + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | -------------------------------- | -------- | ----------------------------------------------------------------------- | +| keys | Array | Yes | Array of key for the items to delete. | +| callback | ?(errors: ?Array) => void | No | Function that will be called an array of any key-specific errors found. | + +Example: + +```jsx +let keys = ['k1', 'k2']; +AsyncStorage.multiRemove(keys, (err) => { + // keys k1 & k2 removed, if they existed + // do most stuff after removal (if you want) +}); +``` + +--- + +### `multiMerge()` + +```jsx +static multiMerge(keyValuePairs: Array>, [callback]: ?(errors: ?Array) => void) +``` + +Batch operation to merge in existing and new values for a given set of keys. This assumes that the values are stringified JSON. Returns a `Promise` object. + +**NOTE**: This is not supported by all native implementations. + +**Parameters:** + +| Name | Type | Required | Description | +| ------------- | -------------------------------- | -------- | ---------------------------------------------------------------------------- | +| keyValuePairs | Array> | Yes | Array of key-value array for the items to merge. | +| callback | ?(errors: ?Array) => void | No | Function that will be called with an array of any key-specific errors found. | + +Example: + +```jsx +// first user, initial values +let UID234_object = { + name: 'Chris', + age: 30, + traits: {hair: 'brown', eyes: 'brown'}, +}; + +// first user, delta values +let UID234_delta = { + age: 31, + traits: {eyes: 'blue', shoe_size: 10}, +}; + +// second user, initial values +let UID345_object = { + name: 'Marge', + age: 25, + traits: {hair: 'blonde', eyes: 'blue'}, +}; + +// second user, delta values +let UID345_delta = { + age: 26, + traits: {eyes: 'green', shoe_size: 6}, +}; + +let multi_set_pairs = [ + ['UID234', JSON.stringify(UID234_object)], + ['UID345', JSON.stringify(UID345_object)], +]; +let multi_merge_pairs = [ + ['UID234', JSON.stringify(UID234_delta)], + ['UID345', JSON.stringify(UID345_delta)], +]; + +AsyncStorage.multiSet(multi_set_pairs, (err) => { + AsyncStorage.multiMerge(multi_merge_pairs, (err) => { + AsyncStorage.multiGet(['UID234', 'UID345'], (err, stores) => { + stores.map((result, i, store) => { + let key = store[i][0]; + let val = store[i][1]; + console.log(key, val); + }); + }); + }); +}); + +// Console log results: +// => UID234 {"name":"Chris","age":31,"traits":{"shoe_size":10,"hair":"brown","eyes":"blue"}} +// => UID345 {"name":"Marge","age":26,"traits":{"shoe_size":6,"hair":"blonde","eyes":"green"}} +``` diff --git a/website/versioned_docs/version-0.62/backhandler.md b/website/versioned_docs/version-0.62/backhandler.md new file mode 100644 index 00000000000..b80e196d438 --- /dev/null +++ b/website/versioned_docs/version-0.62/backhandler.md @@ -0,0 +1,306 @@ +--- +id: version-0.62-backhandler +title: BackHandler +original_id: backhandler +--- + +The Backhandler API detects hardware button presses for back navigation, lets you register event listeners for the system's back action, and lets you control how your application responds. It is Android-only. + +The event subscriptions are called in reverse order (i.e. the last registered subscription is called first). + +- **If one subscription returns true,** then subscriptions registered earlier will not be called. +- **If no subscription returns true or none are registered,** it programmatically invokes the default back button functionality to exit the app. + +> **Warning for modal users:** If your app shows an opened `Modal`, `BackHandler` will not publish any events ([see `Modal` docs](modal#onrequestclose)). + +## Pattern + +```jsx +BackHandler.addEventListener('hardwareBackPress', function() { + /** + * this.onMainScreen and this.goBack are just examples, + * you need to use your own implementation here. + * + * Typically you would use the navigator here to go to the last state. + */ + + if (!this.onMainScreen()) { + this.goBack(); + /** + * When true is returned the event will not be bubbled up + * & no other back action will execute + */ + return true; + } + /** + * Returning false will let the event to bubble up & let other event listeners + * or the system's default back action to be executed. + */ + return false; +}); +``` + +## Example + +The following example implements a scenario where you confirm if the user wants to exit the app: + +
+
    + + +
+
+ + + +```SnackPlayer name=BackHandler&supportedPlatforms=android +import React, { useEffect } from "react"; +import { Text, View, StyleSheet, BackHandler, Alert } from "react-native"; + +export default function App() { + useEffect(() => { + const backAction = () => { + Alert.alert("Hold on!", "Are you sure you want to go back?", [ + { + text: "Cancel", + onPress: () => null, + style: "cancel" + }, + { text: "YES", onPress: () => BackHandler.exitApp() } + ]); + return true; + }; + + const backHandler = BackHandler.addEventListener( + "hardwareBackPress", + backAction + ); + + return () => backHandler.remove(); + }, []); + + return ( + + Click Back button! + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center" + }, + text: { + fontSize: 18, + fontWeight: "bold" + } +}); +``` + + + +```SnackPlayer name=BackHandler&supportedPlatforms=android +import React, { Component } from "react"; +import { Text, View, StyleSheet, BackHandler, Alert } from "react-native"; + +export default class App extends Component { + backAction = () => { + Alert.alert("Hold on!", "Are you sure you want to go back?", [ + { + text: "Cancel", + onPress: () => null, + style: "cancel" + }, + { text: "YES", onPress: () => BackHandler.exitApp() } + ]); + return true; + }; + + componentDidMount() { + this.backHandler = BackHandler.addEventListener( + "hardwareBackPress", + this.backAction + ); + } + + componentWillUnmount() { + this.backHandler.remove(); + } + + render() { + return ( + + Click Back button! + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center" + }, + text: { + fontSize: 18, + fontWeight: "bold" + } +}); +``` + + + +`BackHandler.addEventListener` creates an event listener & returns a `NativeEventSubscription` object which should be cleared using `NativeEventSubscription.remove` method. + +Additionally `BackHandler.removeEventListener` can also be used to clear the event listener. Ensure the callback has the reference to the same function used in the `addEventListener` call as shown the following example ﹣ + +
+
    + + +
+
+ + + +```SnackPlayer name=BackHandler&supportedPlatforms=android +import React, { useEffect } from "react"; +import { Text, View, StyleSheet, BackHandler, Alert } from "react-native"; + +export default function App() { + const backAction = () => { + Alert.alert("Hold on!", "Are you sure you want to go back?", [ + { + text: "Cancel", + onPress: () => null, + style: "cancel" + }, + { text: "YES", onPress: () => BackHandler.exitApp() } + ]); + return true; + }; + + useEffect(() => { + BackHandler.addEventListener("hardwareBackPress", backAction); + + return () => + BackHandler.removeEventListener("hardwareBackPress", backAction); + }, []); + + return ( + + Click Back button! + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center" + }, + text: { + fontSize: 18, + fontWeight: "bold" + } +}); +``` + + + +```SnackPlayer name=BackHandler&supportedPlatforms=android +import React, { Component } from "react"; +import { Text, View, StyleSheet, BackHandler, Alert } from "react-native"; + +export default class App extends Component { + backAction = () => { + Alert.alert("Hold on!", "Are you sure you want to go back?", [ + { + text: "Cancel", + onPress: () => null, + style: "cancel" + }, + { text: "YES", onPress: () => BackHandler.exitApp() } + ]); + return true; + }; + + componentDidMount() { + BackHandler.addEventListener("hardwareBackPress", this.backAction); + } + + componentWillUnmount() { + BackHandler.removeEventListener("hardwareBackPress", this.backAction); + } + + render() { + return ( + + Click Back button! + + ); + } +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: "center", + justifyContent: "center" + }, + text: { + fontSize: 18, + fontWeight: "bold" + } +}); +``` + + + +## Usage with React Navigation + +If you are using React Navigation to navigate across different screens, you can follow their guide on [Custom Android back button behaviour](https://reactnavigation.org/docs/custom-android-back-button-handling/) + +## Backhandler hook + +[React Native Hooks](https://github.com/react-native-community/hooks#usebackhandler) has a nice `useBackHandler` hook which will simplify the process of setting up event listeners. + +--- + +# Reference + +## Methods + +### `addEventListener()` + +```jsx +static addEventListener(eventName, handler) +``` + +--- + +### `exitApp()` + +```jsx +static exitApp() +``` + +--- + +### `removeEventListener()` + +```jsx +static removeEventListener(eventName, handler) +``` diff --git a/website/versioned_docs/version-0.62/building-for-apple-tv.md b/website/versioned_docs/version-0.62/building-for-apple-tv.md new file mode 100644 index 00000000000..85e557cb795 --- /dev/null +++ b/website/versioned_docs/version-0.62/building-for-apple-tv.md @@ -0,0 +1,167 @@ +--- +id: version-0.62-building-for-apple-tv +title: Building For TV Devices +original_id: building-for-apple-tv +--- + +TV devices support has been implemented with the intention of making existing React Native applications work on Apple TV and Android TV, with few or no changes needed in the JavaScript code for the applications. + +
+
    + + +
+
+ + + +The RNTester app supports Apple TV; use the `RNTester-tvOS` build target to build for tvOS. + +## Build changes + +- _Native layer_: React Native Xcode projects all now have Apple TV build targets, with names ending in the string '-tvOS'. + +- _react-native init_: New React Native projects created with `react-native init` will have Apple TV target automatically created in their XCode projects. + +- _JavaScript layer_: Support for Apple TV has been added to `Platform.ios.js`. You can check whether code is running on AppleTV by doing + +```jsx +var Platform = require('Platform'); +var running_on_tv = Platform.isTV; + +// If you want to be more specific and only detect devices running tvOS +// (but no Android TV devices) you can use: +var running_on_apple_tv = Platform.isTVOS; +``` + + + +## Build changes + +- _Native layer_: To run React Native project on Android TV make sure to make the following changes to `AndroidManifest.xml` + +```xml + + + ... + + ... + + + + ... + +``` + +- _JavaScript layer_: Support for Android TV has been added to `Platform.android.js`. You can check whether code is running on Android TV by doing + +```js +var Platform = require('Platform'); +var running_on_android_tv = Platform.isTV; +``` + + + +## Code changes + + + +- _General support for tvOS_: Apple TV specific changes in native code are all wrapped by the TARGET_OS_TV define. These include changes to suppress APIs that are not supported on tvOS (e.g. web views, sliders, switches, status bar, etc.), and changes to support user input from the TV remote or keyboard. + +- _Common codebase_: Since tvOS and iOS share most Objective-C and JavaScript code in common, most documentation for iOS applies equally to tvOS. + +- _Access to touchable controls_: When running on Apple TV, the native view class is `RCTTVView`, which has additional methods to make use of the tvOS focus engine. The `Touchable` mixin has code added to detect focus changes and use existing methods to style the components properly and initiate the proper actions when the view is selected using the TV remote, so `TouchableWithoutFeedback`, `TouchableHighlight` and `TouchableOpacity` will work as expected. In particular: + + - `onFocus` will be executed when the touchable view goes into focus + - `onBlur` will be executed when the touchable view goes out of focus + - `onPress` will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote. + + + +- _Access to touchable controls_: When running on Android TV the Android framework will automatically apply a directional navigation scheme based on relative position of focusable elements in your views. The `Touchable` mixin has code added to detect focus changes and use existing methods to style the components properly and initiate the proper actions when the view is selected using the TV remote, so `TouchableWithoutFeedback`, `TouchableHighlight`, `TouchableOpacity` and `TouchableNativeFeedback` will work as expected. In particular: + + - `onFocus` will be executed when the touchable view goes into focus + - `onBlur` will be executed when the touchable view goes out of focus + - `onPress` will be executed when the touchable view is actually selected by pressing the "select" button on the TV remote. + + + +- _TV remote/keyboard input_: A new native class, `RCTTVRemoteHandler`, sets up gesture recognizers for TV remote events. When TV remote events occur, this class fires notifications that are picked up by `RCTTVNavigationEventEmitter` (a subclass of `RCTEventEmitter`), that fires a JS event. This event will be picked up by instances of the `TVEventHandler` JavaScript object. Application code that needs to implement custom handling of TV remote events can create an instance of `TVEventHandler` and listen for these events, as in the following code: + + + +- _TV remote/keyboard input_: A new native class, `ReactAndroidTVRootViewHelper`, sets up key events handlers for TV remote events. When TV remote events occur, this class fires a JS event. This event will be picked up by instances of the `TVEventHandler` JavaScript object. Application code that needs to implement custom handling of TV remote events can create an instance of `TVEventHandler` and listen for these events, as in the following code: + + + +```jsx +var TVEventHandler = require('TVEventHandler'); + +class Game2048 extends React.Component { + _tvEventHandler: any; + + _enableTVEventHandler() { + this._tvEventHandler = new TVEventHandler(); + this._tvEventHandler.enable(this, function(cmp, evt) { + if (evt && evt.eventType === 'right') { + cmp.setState({board: cmp.state.board.move(2)}); + } else if(evt && evt.eventType === 'up') { + cmp.setState({board: cmp.state.board.move(1)}); + } else if(evt && evt.eventType === 'left') { + cmp.setState({board: cmp.state.board.move(0)}); + } else if(evt && evt.eventType === 'down') { + cmp.setState({board: cmp.state.board.move(3)}); + } else if(evt && evt.eventType === 'playPause') { + cmp.restartGame(); + } + }); + } + + _disableTVEventHandler() { + if (this._tvEventHandler) { + this._tvEventHandler.disable(); + delete this._tvEventHandler; + } + } + + componentDidMount() { + this._enableTVEventHandler(); + } + + componentWillUnmount() { + this._disableTVEventHandler(); + } +``` + + + +- _Dev Menu support_: On the simulator, cmd-D will bring up the developer menu, similar to iOS. To bring it up on a real Apple TV device, make a long press on the play/pause button on the remote. (Please do not shake the Apple TV device, that will not work :) ) + +- _TV remote animations_: `RCTTVView` native code implements Apple-recommended parallax animations to help guide the eye as the user navigates through views. The animations can be disabled or adjusted with new optional view properties. + +- _Back navigation with the TV remote menu button_: The `BackHandler` component, originally written to support the Android back button, now also supports back navigation on the Apple TV using the menu button on the TV remote. + +- _TabBarIOS behavior_: The `TabBarIOS` component wraps the native `UITabBar` API, which works differently on Apple TV. To avoid jittery re-rendering of the tab bar in tvOS (see [this issue](https://github.com/facebook/react-native/issues/15081)), the selected tab bar item can only be set from Javascript on initial render, and is controlled after that by the user through native code. + + + +- _Dev Menu support_: On the simulator, cmd-M will bring up the developer menu, similar to Android. To bring it up on a real Android TV device, press the menu button or long press the fast-forward button on the remote. (Please do not shake the Android TV device, that will not work :) ) + + + +- _Known issues_: + + - [ListView scrolling](https://github.com/facebook/react-native/issues/12793). The issue can be worked around by setting `removeClippedSubviews` to false in ListView and similar components. For more discussion of this issue, see [this PR](https://github.com/facebook/react-native/pull/12944). + + + +- _Known issues_: + + - `InputText` components do not work for now (i.e. they cannot receive focus). diff --git a/website/versioned_docs/version-0.62/button.md b/website/versioned_docs/version-0.62/button.md new file mode 100644 index 00000000000..912ea3bf0f4 --- /dev/null +++ b/website/versioned_docs/version-0.62/button.md @@ -0,0 +1,240 @@ +--- +id: version-0.62-button +title: Button +original_id: button +--- + +A basic button component that should render nicely on any platform. Supports a minimal level of customization. + +If this button doesn't look right for your app, you can build your own button using [TouchableOpacity](touchableopacity) or [TouchableNativeFeedback](touchablenativefeedback). For inspiration, look at the [source code for this button component](https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js). Or, take a look at the [wide variety of button components built by the community](https://js.coach/react-native?search=button). + +```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

+ +We recommend installing Node and Watchman using [Homebrew](http://brew.sh/). Run the following commands in a Terminal after installing Homebrew: + +```sh +brew install node +brew install watchman +``` + +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. + + + +

Java Development Kit

+ +We recommend installing JDK using [Homebrew](http://brew.sh/). Run the following commands in a Terminal after installing Homebrew: + +```sh +brew cask install adoptopenjdk/openjdk/adoptopenjdk8 +``` + +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/). + + + +

Xcode & CocoaPods

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

Installing an iOS Simulator in Xcode

+ +To install a simulator, open Xcode > Preferences... and select the Components tab. Select a simulator with the corresponding version of iOS you wish to use. + +

CocoaPods

+ +[CocoaPods](https://cocoapods.org/) is built with Ruby and it will be installable with the default Ruby available on macOS. You can use a Ruby Version manager, however we recommend that you use the standard Ruby available on macOS unless you know what you're doing. + +Using the default Ruby install will require you to use `sudo` when installing gems. (This is only an issue for the duration of the gem installation, though.) + +```sh +sudo gem install cocoapods +``` + +For more information, please visit [CocoaPods Getting Started guide](https://guides.cocoapods.org/using/getting-started.html). + + + +

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](/docs/assets/GettingStartedAndroidStudioWelcomeMacOS.png) + + + +![Android Studio Welcome](/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: + + + +```sh +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 +``` + + + +```sh +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](/docs/assets/GettingStartedAndroidEnvironmentVariableANDROID_HOME.png) + +The SDK is installed, by default, at the following location: + +```powershell +c:\Android\tools\bin +``` + +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:\Android\tools\bin\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). + + + +

React Native Command Line Interface

+ +React Native has a built-in command line interface. Rather than install and manage a specific version of the CLI globally, we recommend you access the current version at runtime using `npx`, which ships with Node.js. With `npx react-native `, the current stable version of the CLI will be downloaded and executed at the time the command is run. + + + +

Creating a new application

+ +> If you previously installed a global `react-native-cli` package, please remove it as it may cause unexpected issues. + +You can use React Native's built-in command line interface to generate a new project. Let's create a new React Native project called "AwesomeProject": + +```sh +npx react-native init AwesomeProject +``` + +This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Expo, 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 or template

+ +If you want to start a new project with a specific React Native version, you can use the `--version` argument: + +```sh +npx react-native init AwesomeProject --version X.XX.X +``` + +You can also start a project with a custom React Native template, like TypeScript, with `--template` argument: + +```sh +npx react-native init AwesomeTSProject --template react-native-template-typescript +``` + +> **Note** If the above command is failing, you may have old version of `react-native` or `react-native-cli` installed globally on your pc. Try uninstalling the cli and run the cli using `npx`. + + + +

Creating a new application

+ +> If you previously installed a global `react-native-cli` package, please remove it as it may cause unexpected issues. + +React Native has a built-in command line interface, which you can use to generate a new project. You can access it without installing anything globally using `npx`, which ships with Node.js. Let's create a new React Native project called "AwesomeProject": + +```sh +npx react-native init AwesomeProject +``` + +This is not necessary if you are integrating React Native into an existing application, if you "ejected" from Expo, 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 or template

+ +If you want to start a new project with a specific React Native version, you can use the `--version` argument: + +```sh +npx react-native init AwesomeProject --version X.XX.X +``` + +You can also start a project with a custom React Native template, like TypeScript, with `--template` argument: + +```sh +npx react-native init AwesomeTSProject --template react-native-template-typescript +``` + + + +

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](/docs/assets/GettingStartedAndroidStudioAVD.png) + +If you have recently 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 start` inside your React Native project folder: + +```sh +cd AwesomeProject +npx react-native start +``` + +> If you use the Yarn package manager, you can use `yarn` instead of `npx` when running React Native commands inside an existing project. + +`react-native start` starts Metro Bundler, which you can read more about [here](https://facebook.github.io/metro/). + +Run `react-native run-ios` inside your React Native project folder: + +```sh +npx react-native run-ios +``` + +You should see your new app running in the iOS Simulator shortly. + +![AwesomeProject on iOS](/docs/assets/GettingStartediOSSuccess.png) + +`npx react-native run-ios` is 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 start` inside your React Native project folder: + +```sh +cd AwesomeProject +npx react-native start +``` + +> If you use the Yarn package manager, you can use `yarn` instead of `npx` when running React Native commands inside an existing project. + +On another terminal, run `npx react-native run-android`: + +```sh +cd AwesomeProject +npx react-native start +``` + +`react-native start` starts Metro Bundler, which you can read more about [here](https://facebook.github.io/metro/). + +Run `react-native run-android` inside your React Native project folder: + +```sh +npx 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](/docs/assets/GettingStartedAndroidSuccessMacOS.png) + + + +![AwesomeProject on Android](/docs/assets/GettingStartedAndroidSuccessWindows.png) + + + +`npx react-native run-android` is 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?

+ +- 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, check out the [Introduction to React Native](getting-started.md). + + + +

Now what?

+ +- 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, check out the [Introduction to React Native](getting-started.md). diff --git a/website/versioned_docs/version-0.62/handling-text-input.md b/website/versioned_docs/version-0.62/handling-text-input.md new file mode 100644 index 00000000000..3dd66fc8ccb --- /dev/null +++ b/website/versioned_docs/version-0.62/handling-text-input.md @@ -0,0 +1,37 @@ +--- +id: version-0.62-handling-text-input +title: Handling Text Input +original_id: handling-text-input +--- + +[`TextInput`](textinput#content) is a [Core Component](intro-react-native-components) 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, useState } from 'react'; +import { Text, TextInput, View } from 'react-native'; + +export default function PizzaTranslator() { + const [text, setText] = useState(''); + return ( + + setText(text)} + defaultValue={text} + /> + + {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.62/handling-touches.md b/website/versioned_docs/version-0.62/handling-touches.md new file mode 100644 index 00000000000..bf36046655e --- /dev/null +++ b/website/versioned_docs/version-0.62/handling-touches.md @@ -0,0 +1,175 @@ +--- +id: version-0.62-handling-touches +title: Handling Touches +original_id: handling-touches +--- + +Users interact with mobile apps mainly through touch. They can use a combination of gestures, such as tapping on a button, scrolling a list, or zooming on a map. React Native provides components to handle all sorts of common gestures, as well as a comprehensive [gesture responder system](gesture-responder-system.md) to allow for more advanced gesture recognition, but the one component you will most likely be interested in is the basic Button. + +## Displaying a basic button + +[Button](button.md) provides a basic button component that is rendered nicely on all platforms. The minimal example to display a button looks like this: + +```jsx + + + + + + + +> If you’re familiar with web development, `` and `` might remind you of HTML! You can think of them as the `
` and `

` tags of application development. + + + +> On Android, you usually put your views inside `LinearLayout`, `FrameLayout`, `RelativeLayout`, etc. to define how the view’s children will be arranged on the screen. In React Native, `View` uses Flexbox for its children’s layout. You can learn more in [our guide to layout with Flexbox](flexbox). + + + +You can render this component multiple times and multiple places without repeating your code by using ``: + +```SnackPlayer name=Multiple%20Components +import React from 'react'; +import { Text, TextInput, View } from 'react-native'; + +function Cat() { + return ( + + I am a also cat! + + ); +} + +export default function Cafe() { + return ( + + Welcome! + + + + + ); +} +``` + +Any component that renders other components is a **parent component.** Here, `Cafe` is the parent component and each `Cat` is a **child component.** + +You can put as many cats in your cafe as you like. Each `` renders a unique element—which you can customize with props. + +## Props + +**Props** is short for “properties.” Props let you customize React components. For example, here you pass each `` a different `name` for `Cat` to render: + +```SnackPlayer name=Multiple%20Props +import React from 'react'; +import { Text, View } from 'react-native'; + +function Cat(props) { + return ( + + Hello, I am {props.name}! + + ); +} + +export default function Cafe() { + return ( + + + + + + ); +} +``` + +Most of React Native’s Core Components can be customized with props, too. For example, when using [`Image`](image), you pass it a prop named [`source`](image#source) to define what image it shows: + +```SnackPlayer name=Props +import React from 'react'; +import { Text, View, Image } from 'react-native'; + +export default function CatApp() { + return ( + + + Hello, I am your cat! + + ); +} +``` + +`Image` has [many different props](image#props), including [`style`](image#style), which accepts a JS object of design and layout related property-value pairs. + +> Notice the double curly braces `{{ }}` surrounding `style`‘s width and height. In JSX, JavaScript values are referenced with `{}`. This is handy if you are passing something other than a string as props, like an array or number: ` age={2}`. However, JS objects are **_also_** denoted with curly braces: `{width: 200, height: 200}`. Therefore, to pass a JS object in JSX, you must wrap the object in **another pair** of curly braces: `{{width: 200, height: 200}}` + +You can build many things with props and the Core Components [`Text`](text), [`Image`](image), and [`View`](view)! But to build something interactive, you’ll need state. + +## State + +While you can think of props as arguments you use to configure how components render, **state** is like a component’s personal data storage. Sate is useful for handling data that changes over time or that comes from user interaction. State gives your components memory! + +> As a general rule, use props to configure a component when it renders. Use state to keep track of any component data that you expect to change over time. + +The following example takes place in a cat cafe where two hungry cats are waiting to be fed. Their hunger, which we expect to change over time (unlike their names), is stored as state. To feed the cats, press their buttons—which will update their state. + +

+
    + + +
+
+ + + +You can add state to a component by calling [React’s `useState` Hook](https://reactjs.org/docs/hooks-state.html). A Hook is a kind of function that lets you “hook into” React features. For example, `useState` is a Hook that lets you add state to function components. You can learn more about [other kinds of Hooks in the React documentation.](https://reactjs.org/docs/hooks-intro.html) + +```SnackPlayer name=State +import React, { useState } from "react"; +import { Button, Text, View } from "react-native"; + +function Cat(props) { + const [isHungry, setIsHungry] = useState(true); + + return ( + + + I am {props.name}, and I am {isHungry ? "hungry" : "full"}! + + +``` + +> Do not change your component's state directly by assigning it a new value with `this.state.hunger = false`. Calling `this.setState()` allows React to track changes made to state that trigger rerendering. Setting state directly can break your app's reactivity! + +When `this.state.isHungry` is false, the `Button`’s `disabled` prop is set to `false` and its `title` also changes: + +```jsx + + + + +
+ + + +> Web developers may be familiar with this concept. + + + +> Android developers may be familiar with this concept. + + + +> iOS developers may be familiar with this concept. + + + +## Formatting + +Menu paths are written in bold and use carets to navigate submenus. Example: **Android Studio > Preferences** + +--- + +Now that you know how this guide works, it's time to get to know the foundation of React Native: [Native Components](intro-react-native-components.md). diff --git a/website/versioned_docs/version-0.62/javascript-environment.md b/website/versioned_docs/version-0.62/javascript-environment.md new file mode 100644 index 00000000000..c07acd4a9c5 --- /dev/null +++ b/website/versioned_docs/version-0.62/javascript-environment.md @@ -0,0 +1,90 @@ +--- +id: version-0.62-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://www.typescriptlang.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.62/keyboard.md b/website/versioned_docs/version-0.62/keyboard.md new file mode 100644 index 00000000000..ed293294afb --- /dev/null +++ b/website/versioned_docs/version-0.62/keyboard.md @@ -0,0 +1,203 @@ +--- +id: version-0.62-keyboard +title: Keyboard +original_id: keyboard +--- + +`Keyboard` module to control keyboard events. + +### Usage + +The Keyboard module allows you to listen for native events and react to them, as well as make changes to the keyboard, like dismissing it. + +
+
    + + +
+
+ + + +```SnackPlayer name=Keyboard%20Function%20Component%20Example + +import React, { useEffect } from "react"; +import { Keyboard, TextInput, StyleSheet } from "react-native"; + +export default function Example() { + + useEffect(() => { + Keyboard.addListener("keyboardDidShow", _keyboardDidShow); + Keyboard.addListener("keyboardDidHide", _keyboardDidHide); + + // cleanup function + return () => { + Keyboard.removeListener("keyboardDidShow", _keyboardDidShow); + Keyboard.removeListener("keyboardDidHide", _keyboardDidHide); + }; + }, []); + + const _keyboardDidShow = () => { + alert("Keyboard Shown"); + }; + + const _keyboardDidHide = () => { + alert("Keyboard Hidden"); + }; + + return ; +} + +const s = StyleSheet.create({ + input:{ + margin:60, + padding: 10, + borderWidth: 0.5, + borderRadius: 4, + backgroundColor: "#fff" + } +}) + +``` + + + +```SnackPlayer name=Keyboard%20Class%20Component%20Example +import React, {Component} from 'react'; +import {Keyboard, TextInput , StyleSheet} from 'react-native'; + +export default class Example extends Component { + componentDidMount() { + this.keyboardDidShowListener = Keyboard.addListener( + 'keyboardDidShow', + this._keyboardDidShow, + ); + this.keyboardDidHideListener = Keyboard.addListener( + 'keyboardDidHide', + this._keyboardDidHide, + ); + } + + componentWillUnmount() { + this.keyboardDidShowListener.remove(); + this.keyboardDidHideListener.remove(); + } + + _keyboardDidShow() { + alert('Keyboard Shown'); + } + + _keyboardDidHide() { + alert('Keyboard Hidden'); + } + + render() { + return ; + } +} + +const s = StyleSheet.create({ + input:{ + margin:60, + padding: 10, + borderWidth: 0.5, + borderRadius: 4, + backgroundColor: "#fff" + } +}) +``` + + + +--- + +# Reference + +## Methods + +### `addListener()` + +```jsx +static addListener(eventName, callback) +``` + +The `addListener` function connects a JavaScript function to an identified native keyboard notification event. + +This function then returns the reference to the listener. + +**Parameters:** + +| Name | Type | Required | Description | +| --------- | -------- | -------- | ----------------------------------------------------------------------------------------- | +| eventName | string | Yes | The `nativeEvent` is the string that identifies the event you're listening for. See below | +| callback | function | Yes | The function to be called when the event fires | + +**nativeEvent** + +This can be any of the following + +- `keyboardWillShow` +- `keyboardDidShow` +- `keyboardWillHide` +- `keyboardDidHide` +- `keyboardWillChangeFrame` +- `keyboardDidChangeFrame` + +Note that if you set `android:windowSoftInputMode` to `adjustResize` or `adjustPan`, only `keyboardDidShow` and `keyboardDidHide` events will be available on Android. If you set `android:windowSoftInputMode` to `adjustNothing`, no events will be available on Android. `keyboardWillShow` as well as `keyboardWillHide` are generally not available on Android since there is no native corresponding event. + +--- + +### `removeListener()` + +```jsx +static removeListener(eventName, callback) +``` + +Removes a specific listener. + +**Parameters:** + +| Name | Type | Required | Description | +| --------- | -------- | -------- | ------------------------------------------------------------------------------ | +| eventName | string | Yes | The `nativeEvent` is the string that identifies the event you're listening for | +| callback | function | Yes | The function to be called when the event fires | + +--- + +### `removeAllListeners()` + +```jsx +static removeAllListeners(eventName) +``` + +Removes all listeners for a specific event type. + +**Parameters:** + +| Name | Type | Required | Description | +| --------- | ------ | -------- | -------------------------------------------------------------------- | +| eventType | string | Yes | The native event string listeners are watching which will be removed | + +--- + +### `dismiss()` + +```jsx +static dismiss() +``` + +Dismisses the active keyboard and removes focus. + +--- + +### `scheduleLayoutAnimation` + +```jsx +static scheduleLayoutAnimation(event) +``` + +Useful for syncing TextInput (or other keyboard accessory view) size of position changes with keyboard movements. diff --git a/website/versioned_docs/version-0.62/keyboardavoidingview.md b/website/versioned_docs/version-0.62/keyboardavoidingview.md new file mode 100644 index 00000000000..ae43214605e --- /dev/null +++ b/website/versioned_docs/version-0.62/keyboardavoidingview.md @@ -0,0 +1,108 @@ +--- +id: version-0.62-keyboardavoidingview +title: KeyboardAvoidingView +original_id: keyboardavoidingview +--- + +It is a component to solve the common problem of views that need to move out of the way of the virtual keyboard. It can automatically adjust either its height, position, or bottom padding based on the position of the keyboard. + +## Example + +```SnackPlayer name=KeyboardAvoidingView&supportedPlatforms=android,ios +import React, { Component } from 'react'; +import { View, KeyboardAvoidingView, TextInput, StyleSheet, Text, Platform, TouchableWithoutFeedback, Button, Keyboard } from 'react-native'; + +const keyBoardAvoidingComponent = () => { + return ( + + + + Header + + + + + + + + +> Async Storage is the React Native equivalent of Local Storage from the web + + + +### Secure Storage + +React Native does not come bundled with any way of storing sensitive data. However, there are pre-existing solutions for Android and iOS platforms. + +#### iOS - Keychain Services + +[Keychain Services](https://developer.apple.com/documentation/security/keychain_services) allows you to securely store small chunks of sensitive info for the user. This is an ideal place to store certificates, tokens, passwords, and any other sensitive information that doesn’t belong in Async Storage. + +#### Android - Secure Shared Preferences + +[Shared Preferences](https://developer.android.com/reference/android/content/SharedPreferences) is the Android equivalent for a persistent key-value data store. **Data in Shared Preferences is not encrypted by default**, but [Encrypted Shared Preferences](https://developer.android.com/topic/security/data) wraps the Shared Preferences class for Android, and automatically encrypts keys and values. + +#### Android - Keystore + +The [Android Keystore](https://developer.android.com/training/articles/keystore) system lets you store cryptographic keys in a container to make it more difficult to extract from the device. + +In order to use iOS Keychain services or Android Secure Shared Preferences, you can either write a bridge yourself or use a library which wraps them for you and provides a unified API at your own risk. Some libraries to consider: + +- [react-native-keychain](https://github.com/oblador/react-native-keychain) +- [react-native-sensitive-info](https://github.com/mCodex/react-native-sensitive-info) - secure for iOS, but uses Android Shared Preferences for Android (which is not secure by default). There is however a [fork](https://github.com/mCodex/react-native-sensitive-info/tree/keystore)) that uses Android Keystore +- [redux-persist-sensitive-storage](https://github.com/CodingZeal/redux-persist-sensitive-storage) - wraps react-native-sensitive-info + +> **Be mindful of unintentionally storing or exposing sensitive info.** This could happen accidentally, for example saving sensitive form data in redux state and persisting the whole state tree in Async Storage. Or sending user tokens and personal info to an application monitoring service such as Sentry or Crashlytics. + +## Authentication and Deep Linking + +Mobile apps have a unique vulnerability that is non-existent in the web: **deep linking**. Deep linking is a way of sending data directly to a native application from an outside source. A deep link looks like `app://` where `app` is your app scheme and anything following the // could be used internally to handle the request. + +For example, if you were building an ecommerce app, you could use `app://products/1` to deep link to your app and open the product detail page for a product with id 1. You can think of these kind of like URLs on the web, but with one crucial distinction: + +Deep links are not secure and you should never send any sensitive information in them. + +The reason deep links are not secure is because there is no centralized method of registering URL schemes. As an application developer, you can use almost any url scheme you choose by [configuring it in Xcode](https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app) for iOS or [adding an intent on Android](https://developer.android.com/training/app-links/deep-linking). + +There is nothing stopping a malicious application from hijacking your deep link by also registering to the same scheme and then obtaining access to the data your link contains. Sending something like `app://products/1` is not harmful, but sending tokens is a security concern. + +When the operating system has two or more applications to choose from when opening a link, Android will show the user a modal and ask them to choose which application to use to open the link. On iOS however, the operating system will make the choice for you, so the user will be blissfully unaware. Apple has made steps to address this issue in later iOS versions (iOS 11) where the instituted a first-come-first-served principle, although this vulnerability could still be exploited in different ways which you can read more about [here](https://blog.trendmicro.com/trendlabs-security-intelligence/ios-url-scheme-susceptible-to-hijacking/). Using [universal links](https://developer.apple.com/ios/universal-links/) will allow linking to content within your app securely in iOS. + +### OAuth2 and Redirects + +The OAuth2 authentication protocol is incredibly popular nowadays, prided as the most complete and secure protocol around. The OpenID Connect protocol is also based on this. In OAuth2, the user is asked to authenticate via a third party. On successful completion, this third party redirects back to the requesting application with a verification code which can be exchanged for a JWT — a [JSON Web Token](https://jwt.io/introduction/). JWT is an open standard for securely transmitting information between parties on the web. + +On the web, this redirect step is secure, because URLs on the web are guaranteed to be unique. This is not true for apps because, as mentioned earlier, there is no centralized method of registering URL schemes! In order to address this security concern, an additional check must be added in the form of PKCE. + +[PKCE](https://oauth.net/2/pkce/), pronounced “Pixy” stands for Proof of Key Code Exchange, and is an extension to the OAuth 2 spec. This involves adding an additional layer of security which verifies that the authentication and token exchange requests come from the same client. PKCE uses the [SHA 265](https://www.movable-type.co.uk/scripts/sha256.html) Cryptographic Hash Algorithm. SHA 265 creates a unique “signature” for a text or file of any size, but it is: + +- Always the same length regardless of the input file +- Guaranteed to be always produce the same result for the same input +- One way (that is, you can’t reverse engineer it to reveal the original input) + +Now you have two values: + +- **code_verifier** - a large random string generated by the client +- **code_challenge** - the SHA 265 of the code_verifier + +During the initial `/authorize` request, the client also sends the `code_challenge` for the `code_verifier` it keeps in memory. After the authorize request has returned correctly, the client also sends the `code_verifier` that was used to generate the `code_challenge`. The IDP will then calculate the `code_challenge`, see if it matches what was set on the very first `/authorize` request, and only send the access token if the values match. + +This guarantees that only the application that triggered the initial authorization flow would be able to successfully exchange the verification code for a JWT. So even if a malicious application gets access to the verification code, it will be useless on its own. To see this in action, check out [this example](https://aaronparecki.com/oauth-2-simplified/#mobile-apps). + +A library to consider for native OAuth is [react-native-app-auth](https://github.com/FormidableLabs/react-native-app-auth). React-native-app-auth is an SDK for communicating with OAuth2 providers. It wraps the native [AppAuth-iOS](https://github.com/openid/AppAuth-iOS) and [AppAuth-Android](https://github.com/openid/AppAuth-Android) libraries and can support PKCE. + +> React-native-app-auth can support PKCE only if your Identity Provider supports it. + +![OAuth2 with PKCE](/docs/assets/diagram_pkce.svg) + +## Network Security + +Your APIs should always use [SSL encryption](https://www.ssl.com/faqs/faq-what-is-ssl/). SSL encryption protects against the requested data being read in plain text between when it leaves the server and before it reaches the client. You’ll know the endpoint is secure, because it starts with `https://` instead of `http://`. + +### SSL Pinning + +Using https endpoints could still leave your data vulnerable to interception. With https, the client will only trust the server if it can provide a valid certificate that is signed by a trusted Certificate Authority that is pre-installed on the client. An attacker could take advantage of this by installing a malicious root CA certificate to the user’s device, so the client would trust all certificates that are signed by the attacker. Thus, relying on certificates alone could still leave you vulnerable to a [man-in-the-middle attack](https://en.wikipedia.org/wiki/Man-in-the-middle_attack). + +**SSL pinning** is a technique that can be used on the client side to avoid this attack. It works by embedding (or pinning) a list of trusted certificates to the client during development, so that only the requests signed with one of the trusted certificates will be accepted, and any self-signed certificates will not be. + +> When using SSL pinning, you should be mindful of certificate expiry. Certificates expire every 1-2 years and when one does, it’ll need to be updated in the app as well as on the server. As soon as the certificate on the server has been updated, any apps with the old certificate embedded in them will cease to work. + +## Summary + +There is no bulletproof way to handle security, but with conscious effort and diligence, it is possible to significantly reduce the likelihood of a security breach in your application. Invest in security proportional to the sensitivity of the data stored in your application, the number of users, and the damage a hacker could do when gaining access to their account. And remember: it’s significantly harder to access information that was never requested in the first place. diff --git a/website/versioned_docs/version-0.62/settings.md b/website/versioned_docs/version-0.62/settings.md new file mode 100644 index 00000000000..3d15549178f --- /dev/null +++ b/website/versioned_docs/version-0.62/settings.md @@ -0,0 +1,94 @@ +--- +id: version-0.62-settings +title: Settings +original_id: settings +--- + +`Settings` serves as a wrapper for [`NSUserDefaults`](https://developer.apple.com/documentation/foundation/nsuserdefaults), a persistent key-value store available only on iOS. + +## Example + +```SnackPlayer name=Settings%20Example&supportedPlatforms=ios +import React, { useState } from "react"; +import { Button, Settings, StyleSheet, Text, View } from "react-native"; + +export default App = () => { + const [data, setData] = useState(Settings.get("data")); + + const storeData = data => { + Settings.set(data); + setData(Settings.get("data")); + }; + + return ( + + Stored value: + {data} +