this repo has no description
at main 423 kB view raw
1# react-native 2 3Welcome to your initial steps into React Native! If you're seeking instructions on getting started, they have been relocated to a dedicated section. Continue reading for an introduction covering documentation, Native Components, React, and more. 4 5React Native is utilized by a diverse group of individuals, ranging from seasoned iOS developers to those new to React, as well as newcomers to programming in their careers. These documents are crafted to cater to learners at all levels of experience and backgrounds. 6 7### How to Use These Docs 8 9You have the flexibility to read through these documents sequentially like a book or focus on specific sections that interest you. If you're already familiar with React, feel free to skip that section—or revisit it for a quick refresher. 10 11### Prerequisites 12 13To work effectively with React Native, an understanding of JavaScript fundamentals is essential. For those new to JavaScript or in need of a refresher, the Mozilla Developer Network offers comprehensive resources. 14 15> While we strive to assume no prior knowledge of React, Android, or iOS development, these areas are beneficial for aspiring React Native developers. Where appropriate, we have included links to additional resources and articles that delve deeper into these topics. 16 17### Interactive Examples 18 19This introduction allows you to begin immediately in your browser with interactive examples like the following: 20 21The above example is a Snack Player—a tool developed by Expo designed to embed and run React Native projects, showcasing their rendering on platforms such as Android and iOS. The code is live and editable, enabling direct interaction within your browser. Feel free to modify the "Try editing me!" text above to "Hello, world!" 22 23> Optionally, if you prefer setting up a local development environment, follow our guide for configuring it on your machine and integrate the code examples into your project. (Web developers might already have a local setup suitable for mobile browser testing!) 24 25### Developer Notes 26 27React Native attracts learners from various development backgrounds, including web, Android, and iOS technologies. We aim to address developers across these diverse fields. Occasionally, we provide platform-specific explanations as follows: 28 29- **Android** 30- **iOS** 31- **Web** 32 33> Android developers might recognize this concept. 34 35> iOS developers might recognize this concept. 36 37> Web developers might recognize this concept. 38 39### Formatting 40 41Menu paths are presented in bold and utilize carets for navigating submenus. Example: **Android Studio > Preferences** 42 43*** 44 45With an understanding of how to navigate these guides, it's time to explore the foundation of React Native: Native Components. 46 47## Animated 48 49The `Animated` library is designed for creating fluid, powerful animations that are easy to build and maintain. It emphasizes declarative relationships between inputs and outputs, configurable transforms, and control over animation execution through `start`/`stop` methods. 50 51### Core Workflow 52 53To create an animation: 54 551. Create an `Animated.Value`. 561. Connect it to style attributes of an animated component. 571. Drive updates using animations like `Animated.timing()`. 58 59> **Note:** Avoid modifying the animated value directly. Use the `useRef` Hook for a mutable ref object that persists throughout the component lifecycle. 60 61### Example 62 63Consider a `View` that fades in and out based on the animated value `fadeAnim`. 64 65For more examples, refer to the Animations guide. 66 67### Overview of Value Types 68 69- **`Animated.Value()`**: For single values. 70- **`Animated.ValueXY()`**: For vectors. 71 72A single `Animated.Value` can drive multiple properties and bind to style or other props. It can also be interpolated. 73 74#### Configuring Animations 75 76Three types of animations are provided: 77 78- **`Animated.decay()`**: Starts with an initial velocity, gradually slowing to a stop. 79- **`Animated.spring()`**: Implements a basic spring physics model. 80- **`Animated.timing()`**: Animates values over time using easing functions. Defaults to a symmetric easeInOut curve. 81 82#### Working with Animations 83 84Animations are controlled by calling `start()`, which accepts a completion callback: 85 86```typescript 87Animated.timing({}).start(({ finished }) => { 88 /* completion callback */ 89}) 90``` 91 92#### Using the Native Driver 93 94Enable native driver for smoother animations by specifying `useNativeDriver: true` in your animation configuration. 95 96#### Animatable Components 97 98Only animatable components can be animated. These components handle binding of animated values and perform targeted native updates: 99 100- `Animated.Image` 101- `Animated.ScrollView` 102- `Animated.Text` 103- `Animated.View` 104- `Animated.FlatList` 105- `Animated.SectionList` 106 107Use `createAnimatedComponent()` to make a component animatable. 108 109#### Composing Animations 110 111Animations can be combined using composition functions: 112 113- **`Animated.delay()`**: Starts an animation after a delay. 114- **`Animated.parallel()`**: Runs animations simultaneously. 115- **`Animated.sequence()`**: Executes animations in order. 116- **`Animated.stagger()`**: Starts animations with successive delays. 117 118By default, stopping one animation stops all others in the group. 119 120#### Combining Animated Values 121 122Combine animated values using operations like addition, subtraction, multiplication, division, or modulo: 123 124- `Animated.add()` 125- `Animated.subtract()` 126- `Animated.divide()` 127- `Animated.modulo()` 128- `Animated.multiply()` 129 130#### Interpolation 131 132The `interpolate()` function maps input ranges to output ranges. More details are available on the separate page. 133 134#### Advanced APIs 135 136- **`forkEvent()`**: Adds a listener to an existing animated event. 137- **`unforkEvent()`**: Removes a listener from an animated event. 138 139#### Starting and Stopping Animations 140 141- **`start(callback?: (result: {finished: boolean}) => void)`**: Begins the animation, optionally with a completion callback. 142 143 ```typescript 144 Animated.timing({}).start(({ finished }) => { 145 /* completion callback */ 146 }) 147 ``` 148 149- **`stop()`**: Halts any running animation. 150 151#### Resetting Animations 152 153- **`reset()`**: Stops and resets the value to its original state. 154 155### Properties 156 157- **`Value`**: Standard class for driving animations. 158- **`ValueXY`**: For 2D animations, like pan gestures. 159- **`Interpolation`**: Type used in flow for interpolation. 160- **`Node`**: Base class for animated values. 161- **`createAnimatedComponent`**: Makes any React component animatable. 162- **`attachNativeEvent`**: Attaches an animated value to a view event. Prefer `Animated.event` with `useNativeDriver: true`. 163 164## Linking 165 166Linking provides a unified interface for managing both incoming and outgoing app links. Each link (URL) is associated with a URL scheme, such as `https://` or `http://`, which serves as the scheme identifier. 167 168### Built-in URL Schemes 169 170Certain URL schemes are universally recognized across platforms: 171 172|Scheme|Description|iOS|Android| 173|-|-|-|-| 174|`mailto`|Opens mail app, e.g., `mailto:support@expo.io`|✅|✅| 175|`tel`|Opens phone app, e.g., `tel:+123456789`|✅|✅| 176|`sms`|Opens SMS app, e.g., `sms:+123456789`|✅|✅| 177|`https` / `http`|Opens web browser app, e.g., `https://expo.io`|✅|✅| 178 179### Enabling Deep Links 180 181#### Projects with Native Code Only 182 183This section applies to projects with native code. For managed Expo workflow users, refer to the Expo documentation for Linking. 184 185##### Android 186 187To enable deep links: 188 189- Add intent filters in `AndroidManifest.xml`. 190- Set `launchMode` of `MainActivity` to `singleTask`. 191 192```xml 193<activity 194 android:name=".MainActivity" 195 android:launchMode="singleTask"> 196``` 197 198> **Note:** For iOS, include the `LinkingIOS` folder in your header search paths. To handle incoming app links during execution, add the following to `*AppDelegate.m`: 199 200###### Objective-C 201 202```objc 203// iOS 9.x or newer 204#import <React/RCTLinkingManager.h> 205 206- (BOOL)application:(UIApplication *)application 207 openURL:(NSURL *)url 208 options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { 209 return [RCTLinkingManager application:application openURL:url options:options]; 210} 211``` 212 213###### Swift 214 215```swift 216func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { 217 return RCTLinkingManager.application(app, open: url, options: options) 218} 219``` 220 221For Universal Links: 222 223###### Objective-C 224 225```objc 226- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler { 227 return [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; 228} 229``` 230 231###### Swift 232 233```swift 234func application( 235 _ application: UIApplication, 236 continue userActivity: NSUserActivity, 237 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { 238 return RCTLinkingManager.application( 239 application, 240 continue: userActivity, 241 restorationHandler: restorationHandler 242 ) 243} 244``` 245 246### Handling Deep Links 247 248There are two methods to handle URLs that open your app: 249 2501. **Foreground App with Event**: If the app is already open, it foregrounds and fires a Linking 'url' event. Use `Linking.addEventListener('url', callback)` to handle these events. 251 2521. **App Launch with URL**: If the app isn't open, it launches with the URL passed as `initialURL`. Handle this using `Linking.getInitialURL()`, which returns a Promise resolving to the URL if present. 253 254### Reference 255 256#### Methods 257 258##### `addEventListener()` 259 260```typescript 261static addEventListener( 262 type: 'url', 263 handler: (event: { url: string }) => void, 264): EmitterSubscription; 265``` 266 267Adds an event listener for Linking changes by listening to the `url` event type and providing a handler. 268 269##### `canOpenURL()` 270 271```typescript 272static canOpenURL(url: string): Promise<boolean>; 273``` 274 275Determines if an installed app can handle a given URL. Returns a Promise resolving to a boolean indicating whether the URL can be opened. 276 277**Parameters:** 278 279- **urlRequired**: The URL to check. 280 281> For web URLs, ensure the protocol (`"http://"`, `"https://"`). 282 283##### `getInitialURL()` 284 285```typescript 286static getInitialURL(): Promise<string | null>; 287``` 288 289Returns the app launch URL if triggered by an app link; otherwise, returns `null`. 290 291##### `openSettings()` 292 293```typescript 294static openSettings(): Promise<void>; 295``` 296 297Opens the Settings app to display the app’s custom settings. 298 299##### `openURL()` 300 301```typescript 302static openURL(url: string): Promise<any>; 303``` 304 305Attempts to open a given URL with any installed apps. Returns a Promise resolving if successful or rejecting otherwise. 306 307**Parameters:** 308 309- **urlRequired**: The URL to open. 310 311> Ensure the protocol is set for web URLs (`"http://"`, `"https://"`). 312 313##### `sendIntent()` (Android) 314 315```typescript 316static sendIntent( 317 action: string, 318 extras?: Array<{ key: string; value: string | number | boolean }>, 319): Promise<void>; 320``` 321 322Launches an Android intent with optional extras. 323 324**Parameters:** 325 326- **actionRequired**: The action to perform. 327- **extras**: Optional array of key-value pairs for additional data. 328 329## ActionSheetIOS 330 331Displays native to iOS Action Sheet component. 332 333### Example 334 335### Reference 336 337### Methods 338 339#### `showActionSheetWithOptions()` 340 341```typescript 342static showActionSheetWithOptions: ( 343 options: ActionSheetIOSOptions, 344 callback: (buttonIndex: number) => void, 345); 346``` 347 348Display an iOS action sheet. The `options` object must contain one or more of: 349 350- `options`: Array of strings - a list of button titles (required) 351- `cancelButtonIndex`: Integer - index of cancel button in `options` 352- `cancelButtonTintColor`: String - the color used for changing the text color of the cancel button 353- `destructiveButtonIndex`: Integer or array of integers - indices of destructive buttons in `options` 354- `title`: String - a title to show above the action sheet 355- `message`: String - a message to show below the title 356- `anchor`: Number - the node to which the action sheet should be anchored (used for iPad) 357- `tintColor`: String - the color used for non-destructive button titles 358- `disabledButtonIndices`: Array of numbers - a list of button indices which should be disabled 359- `userInterfaceStyle`: String - the interface style used for the action sheet, can be set to `light` or `dark`, otherwise the default system style will be used 360 361The 'callback' function takes one parameter, the zero-based index of the selected item. 362 363Minimal example: 364 365```typescript 366ActionSheetIOS.showActionSheetWithOptions( 367 { 368 options: ["Cancel", "Remove"], 369 destructiveButtonIndex: 1, 370 cancelButtonIndex: 0, 371 }, 372 (buttonIndex) => { 373 if (buttonIndex === 1) { 374 /* destructive action */ 375 } 376 } 377) 378``` 379 380#### `dismissActionSheet()` 381 382```typescript 383static dismissActionSheet(); 384``` 385 386Dismisses the most upper iOS action sheet presented. If no action sheet is present, a warning is displayed. 387 388#### `showShareActionSheetWithOptions()` 389 390```typescript 391static showShareActionSheetWithOptions: ( 392 options: ShareActionSheetIOSOptions, 393 failureCallback: (error: Error) => void, 394 successCallback: (success: boolean, method: string) => void, 395); 396``` 397 398Display the iOS share sheet. The `options` object should contain one or both of `message` and `url`, and can additionally have a `subject` or `excludedActivityTypes`: 399 400- `url`: String - a URL to share 401- `message`: String - a message to share 402- `subject`: String - a subject for the message 403- `excludedActivityTypes`: Array - the activities to exclude from the ActionSheet 404 405> **Note:** If `url` points to a local file, or is a base64-encoded URI, the file it points to will be loaded and shared directly. In this way, you can share images, videos, PDF files, etc. If `url` points to a remote file or address, it must conform to URL format as described in RFC 2396. For example, a web URL without a proper protocol (HTTP/HTTPS) will not be shared. 406 407The 'failureCallback' function takes one parameter, an error object. The only property defined on this object is an optional `stack` property of type `string`. 408 409The 'successCallback' function takes two parameters: 410 411- A boolean value signifying success or failure 412- A string that, in the case of success, indicates the method of sharing 413 414## Cross-Language Communication in React Native 415 416React Native allows integration with existing apps by embedding it within native components and vice versa. This guide summarizes techniques to facilitate communication between native and React Native components. 417 418### Introduction 419 420Inspired by React, React Native follows a one-directional information flow where data is passed from parent to child components using properties. When integrating React Native with native components, specific cross-language mechanisms are required for effective communication. 421 422#### Properties 423 424Properties serve as the primary method of cross-component communication, allowing data transfer between native and React Native components in both directions. 425 426##### Passing Properties from Native to React Native 427 428To pass properties from a native component to React Native, implement `ReactActivityDelegate` in your main activity. Override `getLaunchOptions` to return a `Bundle` with the desired properties. 429 430**Java Example:** 431 432```java 433public class MainActivity extends ReactActivity { 434 @Override 435 protected ReactActivityDelegate createReactActivityDelegate() { 436 return new ReactActivityDelegate(this, getMainComponentName()) { 437 @Override 438 protected Bundle getLaunchOptions() { 439 Bundle initialProperties = new Bundle(); 440 ArrayList<String> imageList = new ArrayList<>(Arrays.asList( 441 "https://dummyimage.com/600x400/ffffff/000000.png", 442 "https://dummyimage.com/600x400/000000/ffffff.png" 443 )); 444 initialProperties.putStringArrayList("images", imageList); 445 return initialProperties; 446 } 447 }; 448 } 449} 450``` 451 452**Kotlin Example:** 453 454```kotlin 455class MainActivity : ReactActivity() { 456 override fun createReactActivityDelegate(): ReactActivityDelegate { 457 return object : ReactActivityDelegate(this, mainComponentName) { 458 override fun getLaunchOptions(): Bundle { 459 val imageList = arrayListOf( 460 "https://dummyimage.com/600x400/ffffff/000000.png", 461 "https://dummyimage.com/600x400/000000/ffffff.png" 462 ) 463 return Bundle().apply { putStringArrayList("images", imageList) } 464 } 465 } 466 } 467} 468``` 469 470**React Native Example:** 471 472```javascript 473import React from "react" 474import { View, Image } from "react-native" 475 476export default class ImageBrowserApp extends React.Component { 477 renderImage(imgURI) { 478 return <Image source={{ uri: imgURI }} /> 479 } 480 481 render() { 482 return <View>{this.props.images.map(this.renderImage)}</View> 483 } 484} 485``` 486 487`ReactRootView` provides a `appProperties` property that can be updated to re-render the React Native app with new properties. Ensure updates occur on the main thread. 488 489**Java Update Example:** 490 491```java 492Bundle updatedProps = mReactRootView.getAppProperties(); 493ArrayList<String> imageList = new ArrayList<>(Arrays.asList( 494 "https://dummyimage.com/600x400/ff0000/000000.png", 495 "https://dummyimage.com/600x400/ffffff/ff0000.png" 496)); 497updatedProps.putStringArrayList("images", imageList); 498mReactRootView.setAppProperties(updatedProps); 499``` 500 501**Kotlin Update Example:** 502 503```kotlin 504var updatedProps: Bundle = reactRootView.getAppProperties() 505val imageList = arrayListOf( 506 "https://dummyimage.com/600x400/ff0000/000000.png", 507 "https://dummyimage.com/600x400/ffffff/ff0000.png" 508) 509``` 510 511> **Note:** The `componentWillUpdateProps` function is not called after a prop update. Access new props in the `componentDidMount` function. 512 513##### Passing Properties from React Native to Native 514 515Expose native component properties using setter methods annotated with `@ReactProp`. These can be used as if they were regular React Native components. 516 517#### Limits of Properties 518 519Properties do not support callbacks for bottom-up data bindings, limiting their use in scenarios where a JS action should trigger changes in the native parent view. Cross-language callbacks exist but are not intended to be passed as properties; instead, they allow triggering native actions from JS and handling results within JS. 520 521### Other Ways of Cross-Language Interaction (Events and Native Modules) 522 523For more flexible communication beyond properties, React Native offers events and native modules for both internal and external interactions. 524 525#### Calling React Native Functions from Native (Events) 526 527Events enable executing handlers in JS without needing component references. However, they can introduce dependencies, potential name collisions, and require identifiers to distinguish between multiple instances of the same component. 528 529#### Calling Native Functions from React Native (Native Modules) 530 531Native modules are Java/Kotlin classes accessible in JS, allowing arbitrary functions and constants to be exported. Each module instance is created per JS bridge, but all share the same namespace, necessitating caution against name collisions. 532 533> **Warning:** Be mindful of shared namespaces when creating new native modules. 534 535## Cross-Language Communication in React Native 536 537React Native allows for seamless integration with native components. This guide explores techniques to facilitate communication between React Native and native code. 538 539### Introduction 540 541Inspired by React, React Native follows a unidirectional data flow where components depend on their parent's properties or internal state. When integrating native components, specific mechanisms are required to enable cross-language communication. 542 543#### Properties 544 545Properties serve as the primary method for passing information between native and React Native components. 546 547##### Passing Properties from Native to React Native 548 549To embed a React Native view within a native component, use `RCTRootView`, which acts as an interface. You can pass properties using its initializer: 550 551```objective-c 552NSArray *imageList = @[@"https://dummyimage.com/600x400/ffffff/000000.png", 553 @"https://dummyimage.com/600x400/000000/ffffff.png"]; 554 555NSDictionary *props = @{@"images" : imageList}; 556 557RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 558 moduleName:@"ImageBrowserApp" 559 initialProperties:props]; 560``` 561 562In React Native, these properties can be accessed as follows: 563 564```typescript 565import React from 'react'; 566import { View, Image } from 'react-native'; 567 568export default class ImageBrowserApp extends React.Component { 569 renderImage(imgURI) { 570 return <Image source={{ uri: imgURI }} />; 571 } 572 573 render() { 574 return ( 575 <View> 576 {this.props.images.map(this.renderImage)} 577 </View> 578 ); 579 } 580} 581``` 582 583`RCTRootView` also supports updating properties via `appProperties`, which triggers a re-render when changes occur. Ensure updates are performed on the main thread. 584 585##### Passing Properties from React Native to Native 586 587Expose native component properties using the `RCT_CUSTOM_VIEW_PROPERTY` macro, allowing them to be used in React Native as standard components. 588 589#### Limits of Properties 590 591Properties lack support for callbacks, limiting bottom-up data binding. For instance, removing a React Native view based on JS actions requires alternative mechanisms. 592 593### Other Ways of Cross-Language Interaction (Events and Native Modules) 594 595For more complex interactions, consider using events or native modules: 596 597#### Calling React Native Functions from Native (Events) 598 599Events allow triggering JavaScript functions without direct references to components. However, they can introduce dependencies and potential name collisions. Use the `reactTag` as an identifier for distinguishing between multiple instances. 600 601#### Calling Native Functions from React Native (Native Modules) 602 603Native modules expose Objective-C classes in JavaScript, allowing function calls across languages. They are singletons per JS bridge, requiring identifiers to manage multiple native views. 604 605### Layout Computation Flow 606 607Integrating different layout systems requires careful management: 608 609#### Layout of a Native Component Embedded in React Native 610 611Most style and size attributes work as expected since native react views subclass `UIView`. 612 613#### Layout of a React Native Component Embedded in Native 614 615##### Fixed Size Content 616 617For fixed-size content, set the frame explicitly. Use Flexbox to ensure content fits within bounds. 618 619```objective-c 620- (void)viewDidLoad { 621 RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 622 moduleName:appName 623 initialProperties:props]; 624 rootView.frame = CGRectMake(0, 0, self.view.width, 200); 625 [self.view addSubview:rootView]; 626} 627``` 628 629##### Flexible Size Content 630 631For dynamic sizes, use `ScrollView` or `RCTRootView`'s flexibility modes to adjust layout based on content size. 632 633```objective-c 634- (instancetype)initWithFrame:(CGRect)frame { 635 _rootView = [[RCTRootView alloc] initWithBridge:bridge 636 moduleName:@"FlexibilityExampleApp" 637 initialProperties:@{}]; 638 _rootView.delegate = self; 639 _rootView.sizeFlexibility = RCTRootViewSizeFlexibilityHeight; 640 _rootView.frame = CGRectMake(0, 0, self.frame.size.width, 0); 641} 642 643#pragma mark - RCTRootViewDelegate 644- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView { 645 CGRect newFrame = rootView.frame; 646 newFrame.size = rootView.intrinsicContentSize; 647 rootView.frame = newFrame; 648} 649``` 650 651#### Notes 652 653React Native's layout calculations occur on a separate thread, potentially causing temporary UI inconsistencies. Synchronize updates to maintain consistency. 654 655By understanding these techniques, you can effectively manage communication and layout between React Native and native components. 656 657## Color Reference 658 659In React Native, components are styled using JavaScript. The color properties generally align with how CSS functions on the web. Below are general guidelines for color usage across different platforms: 660 661- Android 662- iOS 663 664### Color APIs 665 666React Native offers several color APIs to leverage platform-specific design and user preferences: 667 668- `PlatformColor` allows referencing the platform's color system. 669- `DynamicColorIOS`, specific to iOS, enables specifying colors for Light or Dark Mode. 670 671### Color Representations 672 673#### Red Green Blue (RGB) 674 675React Native supports both hexadecimal and functional notation for `rgb()` and `rgba()`: 676 677- Hexadecimal: `#f0f` (#rgb), `#ff00ff` (#rrggbb), `#f0ff` (#rgba), `#ff00ff00` (#rrggbbaa) 678- Functional: `'rgb(255, 0, 255)'`, `'rgb(255 0 255)'`, `'rgba(255, 0, 255, 1.0)'`, `'rgba(255 0 255 / 1.0)'` 679 680#### Hue Saturation Lightness (HSL) 681 682React Native supports `hsl()` and `hsla()` in functional notation: 683 684- Functional: `'hsl(360, 100%, 100%)'`, `'hsl(360 100% 100%)'`, `'hsla(360, 100%, 100%, 1.0)'`, `'hsla(360 100% 100% / 1.0)'` 685 686#### Hue Whiteness Blackness (HWB) 687 688React Native supports `hwb()` in functional notation: 689 690- Functional: `'hwb(0, 0%, 100%)'`, `'hwb(360, 100%, 100%)'`, `'hwb(0 0% 0%)'`, `'hwb(70 50% 0%)'` 691 692#### Color Integers 693 694React Native also supports colors as integer values in RGB color mode: 695 696- Integer: `0xff00ff00` (0xrrggbbaa) 697 698> **Caution:** This is similar to Android's Color integers but differs as Android uses SRGB color mode (0xaarrggbb). 699 700#### Named Colors 701 702React Native allows using lowercase string names for colors. Uppercase names are not supported. 703 704##### `transparent` 705 706This acts as a shortcut for `rgba(0,0,0,0)`, similar to CSS3. 707 708##### Color Keywords 709 710Named colors in React Native follow the CSS3/SVG specification: 711 712- aliceblue (`#f0f8ff`) 713- antiquewhite (`#faebd7`) 714- aqua (`#00ffff`) 715- aquamarine (`#7fffd4`) 716- azure (`#f0ffff`) 717- beige (`#f5f5dc`) 718- bisque (`#ffe4c4`) 719- black (`#000000`) 720- blanchedalmond (`#ffebcd`) 721- blue (`#0000ff`) 722- blueviolet (`#8a2be2`) 723- brown (`#a52a2a`) 724- burlywood (`#deb887`) 725- cadetblue (`#5f9ea0`) 726- chartreuse (`#7fff00`) 727- chocolate (`#d2691e`) 728- coral (`#ff7f50`) 729- cornflowerblue (`#6495ed`) 730- cornsilk (`#fff8dc`) 731- crimson (`#dc143c`) 732- cyan (`#00ffff`) 733- darkblue (`#00008b`) 734- darkcyan (`#008b8b`) 735- darkgoldenrod (`#b8860b`) 736- darkgray (`#a9a9a9`) 737- darkgreen (`#006400`) 738- darkgrey (`#a9a9a9`) 739- darkkhaki (`#bdb76b`) 740- darkmagenta (`#8b008b`) 741- darkolivegreen (`#556b2f`) 742- darkorange (`#ff8c00`) 743- darkorchid (`#9932cc`) 744- darkred (`#8b0000`) 745- darksalmon (`#e9967a`) 746- darkseagreen (`#8fbc8f`) 747- darkslateblue (`#483d8b`) 748- darkslategrey (`#2f4f4f`) 749- darkturquoise (`#00ced1`) 750- darkviolet (`#9400d3`) 751- deeppink (`#ff1493`) 752- deepskyblue (`#00bfff`) 753- dimgray (`#696969`) 754- dimgrey (`#696969`) 755- dodgerblue (`#1e90ff`) 756- firebrick (`#b22222`) 757- floralwhite (`#fffaf0`) 758- forestgreen (`#228b22`) 759- fuchsia (`#ff00ff`) 760- gainsboro (`#dcdcdc`) 761- ghostwhite (`#f8f8ff`) 762- gold (`#ffd700`) 763- goldenrod (`#daa520`) 764- gray (`#808080`) 765- green (`#008000`) 766- greenyellow (`#adff2f`) 767- grey (`#808080`) 768- honeydew (`#f0fff0`) 769- hotpink (`#ff69b4`) 770- indianred (`#cd5c5c`) 771- indigo (`#4b0082`) 772- ivory (`#fffff0`) 773- khaki (`#f0e68c`) 774- lavender (`#e6e6fa`) 775- lavenderblush (`#fff0f5`) 776- lawngreen (`#7cfc00`) 777- lemonchiffon (`#fffacd`) 778- lightblue (`#add8e6`) 779- lightcoral (`#f08080`) 780- lightcyan (`#e0ffff`) 781- lightgoldenrodyellow (`#fafad2`) 782- lightgray (`#d3d3d3`) 783- lightgreen (`#90ee90`) 784- lightgrey (`#d3d3d3`) 785- lightpink (`#ffb6c1`) 786- lightsalmon (`#ffa07a`) 787- lightseagreen (`#20b2aa`) 788- lightskyblue (`#87cefa`) 789- lightslategrey (`#778899`) 790- lightsteelblue (`#b0c4de`) 791- lightyellow (`#ffffe0`) 792- lime (`#00ff00`) 793- limegreen (`#32cd32`) 794- linen (`#faf0e6`) 795- magenta (`#ff00ff`) 796- maroon (`#800000`) 797- mediumaquamarine (`#66cdaa`) 798- mediumblue (`#0000cd`) 799- mediumorchid (`#ba55d3`) 800- mediumpurple (`#9370db`) 801- mediumseagreen (`#3cb371`) 802- mediumslateblue (`#7b68ee`) 803- mediumspringgreen (`#00fa9a`) 804- mediumturquoise (`#48d1cc`) 805- mediumvioletred (`#c71585`) 806- midnightblue (`#191970`) 807- mintcream (`#f5fffa`) 808- mistyrose (`#ffe4e1`) 809- moccasin (`#ffe4b5`) 810- navajowhite (`#ffdead`) 811- navy (`#000080`) 812- oldlace (`#fdf5e6`) 813- olive (`#808000`) 814- olivedrab (`#6b8e23`) 815- orange (`#ffa500`) 816- orangered (`#ff4500`) 817- orchid (`#da70d6`) 818- palegoldenrod (`#eee8aa`) 819- palegreen (`#98fb98`) 820- paleturquoise (`#afeeee`) 821- palevioletred (`#db7093`) 822- papayawhip (`#ffefd5`) 823- peachpuff (`#ffdab9`) 824- peru (`#cd853f`) 825- pink (`#ffc0cb`) 826- plum (`#dda0dd`) 827- powderblue (`#b0e0e6`) 828- purple (`#800080`) 829- rebeccapurple (`#663399`) 830- red (`#ff0000`) 831- rosybrown (`#bc8f8f`) 832- royalblue (`#4169e1`) 833- saddlebrown (`#8b4513`) 834- salmon (`#fa8072`) 835- sandybrown (`#f4a460`) 836- seagreen (`#2e8b57`) 837- seashell (`#fff5ee`) 838- sienna (`#a0522d`) 839- silver (`#c0c0c0`) 840- skyblue (`#87ceeb`) 841- slateblue (`#6a5acd`) 842- slategray (`#708090`) 843- snow (`#fffafa`) 844- springgreen (`#00ff7f`) 845- steelblue (`#4682b4`) 846- tan (`#d2b48c`) 847- teal (`#008080`) 848- thistle (`#d8bfd8`) 849- tomato (`#ff6347`) 850- turquoise (`#40e0d0`) 851- violet (`#ee82ee`) 852- wheat (`#f5deb3`) 853- white (`#ffffff`) 854- whitesmoke (`#f5f5f5`) 855- yellow (`#ffff00`) 856- yellowgreen (`#9acd32`) 857 858## ActivityIndicator 859 860Displays a circular loading indicator. 861 862### Example 863 864### Reference 865 866### Properties 867 868#### Inherited from View 869 870The `ActivityIndicator` inherits properties from the `View`. 871 872#### `animating` 873 874Determines if the indicator is visible (`true`) or hidden (`false`). 875 876- **Type**: `bool` 877- **Default**: `true` 878 879#### `color` 880 881Sets the color of the spinner. 882 883- **Type**: `color` 884- **Default**: 885 - General: `null` (system accent default) 886 - Android: `'#999999'` 887 - iOS: Inherits system accent default 888 889#### `hidesWhenStopped` (iOS Only) 890 891Controls whether the indicator is hidden when not animating. 892 893- **Type**: `bool` 894- **Default**: `true` 895 896#### `size` 897 898Specifies the size of the indicator. 899 900- **Type**: 901 - Enum: `'small'`, `'large'` for iOS 902 - Number for Android 903- **Default**: `'small'` 904 905### Example 906 907```typescript 908// Example usage of ActivityIndicator with props 909<ActivityIndicator 910 animating={true} 911 color={'#FF0000'} 912 hidesWhenStopped={false} 913 size={'large'} 914/> 915``` 916 917### Props Summary 918 919- Inherited from View 920- `animating` 921- `color` 922- `hidesWhenStopped` (iOS) 923- `size` 924 925## Button 926 927The Button component is designed to render consistently across different platforms, offering a basic level of customization. If the default appearance does not meet your needs, consider creating a custom button using Pressable. For guidance, refer to the source code of the Button component. 928 929```typescript 930<Button 931 onPress={onPressLearnMore} 932 title="Learn More" 933 color="#841584" 934 accessibilityLabel="Learn more about this purple button" 935/> 936``` 937 938### Example 939 940### Reference 941 942### Props 943 944|Prop Name|Description|Type|Required| 945|-|-|-|-| 946|**`onPress`**|Handler called when the user taps the button.|`({nativeEvent: PressEvent})`|Yes| 947|**`title`**|Text displayed inside the button. On Android, this title is converted to uppercase.|string|Yes| 948|`accessibilityLabel`|Text for blindness accessibility features.|string|No| 949|`accessibilityLanguage`|Language used by screen readers on iOS, following BCP 47 specification.|string|No| 950|`accessibilityActions`|List of actions for assistive technologies to invoke programmatically.|array|No| 951|`onAccessibilityAction`|Invoked when an accessibility action is performed by the user.|function|No| 952|`color`|Text color on iOS, background color on Android.|color|No| 953||Default:||| 954||- Android: `'#2196F3'`||| 955||- iOS: `'#007AFF'`||| 956|`disabled`|Disables all interactions if set to true.|bool|No| 957||Default:||| 958||- false||| 959|`hasTVPreferredFocus`|Indicates TV preferred focus.|bool|No| 960||Default:||| 961||- false||| 962|`nextFocusDown`|Next view to receive focus when navigating down on Android TV.|number|No| 963|`nextFocusForward`|Next view to receive focus when navigating forward on Android TV.|number|No| 964|`nextFocusLeft`|Next view to receive focus when navigating left on Android TV.|number|No| 965|`nextFocusRight`|Next view to receive focus when navigating right on Android TV.|number|No| 966|`nextFocusUp`|Next view to receive focus when navigating up on Android TV.|number|No| 967|`testID`|Identifier for locating this view in end-to-end tests.|string|No| 968|`touchSoundDisabled`|Disables system sound on touch if set to true (Android only).|boolean|No| 969||Default:||| 970||- false||| 971 972This table summarizes the properties available for the Button component, detailing their purpose and default values where applicable. 973 974## Image 975 976To integrate image handling capabilities in your React Native application, you can utilize the `<Image />` component along with various methods and properties provided for efficient image management. Below is an overview of how to use these features effectively: 977 978#### Adding Image Support 979 9801. **Install Required Libraries:** 981 982 - For GIF support on Android, ensure you have `react-native-gesture-handler`. 983 - For WebP support on iOS, bundle the JavaScript code with your app. 984 9851. **Configure Build Files:** 986 987 - Add dependencies in `android/build.gradle` and `android/app/build.gradle`. 988 9891. **Modify Native Code:** 990 - Update `MainApplication.java` to include necessary packages. 991 - Modify `settings.gradle` to include new modules like `react-native-gesture-handler`. 992 993#### Using the `<Image />` Component 994 995The `<Image />` component in React Native allows you to display images from various sources. Here’s how you can use it: 996 997```jsx 998import React from "react" 999import { Image, StyleSheet } from "react-native" 1000 1001const MyComponent = () => ( 1002 <Image 1003 source={{ uri: "https://example.com/image.png" }} 1004 style={styles.image} 1005 resizeMode="contain" 1006 /> 1007) 1008 1009const styles = StyleSheet.create({ 1010 image: { 1011 width: 200, 1012 height: 100, 1013 }, 1014}) 1015 1016export default MyComponent 1017``` 1018 1019#### Key Properties 1020 1021- **`source`**: Can be a URI, local file path, or static resource. Supports multiple formats like PNG, JPEG, GIF, and WebP. 1022- **`style`**: Apply styles such as width, height, and transformations. 1023- **`resizeMode`**: Controls how the image should resize to fit its container (e.g., `contain`, `cover`). 1024- **`tintColor`**: Changes the color of non-transparent pixels. 1025 1026#### Methods for Image Management 1027 10281. **Prefetching Images:** 1029 1030 ```javascript 1031 import { Image } from "react-native" 1032 1033 const prefetchImage = async () => { 1034 try { 1035 await Image.prefetch("https://example.com/image.png") 1036 console.log("Image prefetched successfully!") 1037 } catch (error) { 1038 console.error("Error prefetching image:", error) 1039 } 1040 } 1041 ``` 1042 10431. **Querying Cache:** 1044 1045 ```javascript 1046 const checkCache = async () => { 1047 try { 1048 const cacheStatus = await Image.queryCache([ 1049 "https://example.com/image.png", 1050 ]) 1051 console.log(cacheStatus) 1052 } catch (error) { 1053 console.error("Error querying cache:", error) 1054 } 1055 } 1056 ``` 1057 10581. **Getting Image Size:** 1059 ```javascript 1060 const getImageSize = async () => { 1061 try { 1062 const { width, height } = await Image.getSize( 1063 "https://example.com/image.png", 1064 (width, height) => console.log(`Image size is ${width}x${height}`) 1065 ) 1066 } catch (error) { 1067 console.error("Error getting image size:", error) 1068 } 1069 } 1070 ``` 1071 1072#### Advanced Features 1073 1074- **`srcSet`**: Allows specifying multiple image sources for different resolutions. 1075- **Cache Control**: Use `cache` property in `source` to manage caching behavior. 1076 1077By leveraging these features, you can efficiently handle images in your React Native application, ensuring optimal performance and user experience. 1078 1079## PanResponder 1080 1081The `PanResponder` component in React Native helps manage touch gestures by consolidating multiple touches into a single gesture. It ensures that single-touch gestures remain unaffected by additional touches and can recognize basic multi-touch gestures. 1082 1083By default, `PanResponder` uses an `InteractionManager` to prevent long-running JavaScript events from interrupting active gestures. It provides a consistent interface for responder handlers within the gesture responder system. Each handler receives a new `gestureState` object along with the native event: 1084 1085```typescript 1086onPanResponderMove: (event, gestureState) => {} 1087``` 1088 1089A native event is a synthetic touch event of type `PressEvent`. 1090 1091The `gestureState` object includes: 1092 1093- `stateID`: ID of the gesture state, which persists as long as there's at least one touch on screen. 1094- `moveX`: Latest X coordinate of the recently moved touch. 1095- `moveY`: Latest Y coordinate of the recently moved touch. 1096- `x0`: Initial X coordinate when the responder was granted. 1097- `y0`: Initial Y coordinate when the responder was granted. 1098- `dx`: Accumulated distance in the X direction since the gesture started. 1099- `dy`: Accumulated distance in the Y direction since the gesture started. 1100- `vx`: Current velocity of the gesture in the X direction. 1101- `vy`: Current velocity of the gesture in the Y direction. 1102- `numberActiveTouches`: Number of touches currently on screen. 1103 1104### Usage Pattern 1105 1106```typescript 1107const ExampleComponent = () => { 1108 const panResponder = React.useRef( 1109 PanResponder.create({ 1110 // Ask to be the responder: 1111 onStartShouldSetPanResponder: (evt, gestureState) => true, 1112 onStartShouldSetPanResponderCapture: (evt, gestureState) => true, 1113 onMoveShouldSetPanResponder: (evt, gestureState) => true, 1114 onMoveShouldSetPanResponderCapture: (evt, gestureState) => true, 1115 1116 onPanResponderGrant: (evt, gestureState) => { 1117 // The gesture has started. Show visual feedback to the user. 1118 // gestureState.dx and gestureState.dy will be set to zero now 1119 }, 1120 onPanResponderMove: (evt, gestureState) => { 1121 // Use gestureState.moveX and gestureState.moveY for recent move distance 1122 // Use gestureState.dx and gestureState.dy for accumulated gesture distance 1123 }, 1124 onPanResponderTerminationRequest: (evt, gestureState) => true, 1125 onPanResponderRelease: (evt, gestureState) => { 1126 // The user has released all touches while this view is the responder. 1127 // This typically means a gesture has succeeded 1128 }, 1129 onPanResponderTerminate: (evt, gestureState) => { 1130 // Another component has become the responder; cancel this gesture 1131 }, 1132 onShouldBlockNativeResponder: (evt, gestureState) => true, 1133 }) 1134 ).current; 1135 1136 return <View {...panResponder.panHandlers} />; 1137}; 1138``` 1139 1140### Example 1141 1142`PanResponder` can be used with the `Animated` API to create complex gestures in the UI. For instance, an animated `View` component can be dragged freely across the screen. 1143 1144Try the PanResponder example in RNTester. 1145 1146### Reference 1147 1148#### Methods 1149 1150##### `create()` 1151 1152```typescript 1153static create(config: PanResponderCallbacks): PanResponderInstance; 1154``` 1155 1156**Parameters:** 1157 1158|Name|Type|Description| 1159|-|-|-| 1160|configRequired|object|Refer below| 1161 1162The `config` object provides enhanced versions of all responder callbacks, including the `PanResponder` gesture state. Replace `onResponder*` with `onPanResponder*`. For example: 1163 1164- `onMoveShouldSetPanResponder: (e, gestureState) => {...}` 1165- `onMoveShouldSetPanResponderCapture: (e, gestureState) => {...}` 1166- `onStartShouldSetPanResponder: (e, gestureState) => {...}` 1167- `onStartShouldSetPanResponderCapture: (e, gestureState) => {...}` 1168- `onPanResponderReject: (e, gestureState) => {...}` 1169- `onPanResponderGrant: (e, gestureState) => {...}` 1170- `onPanResponderStart: (e, gestureState) => {...}` 1171- `onPanResponderEnd: (e, gestureState) => {...}` 1172- `onPanResponderRelease: (e, gestureState) => {...}` 1173- `onPanResponderMove: (e, gestureState) => {...}` 1174- `onPanResponderTerminate: (e, gestureState) => {...}` 1175- `onPanResponderTerminationRequest: (e, gestureState) => {...}` 1176- `onShouldBlockNativeResponder: (e, gestureState) => {...}` 1177 1178For events with capture equivalents, the gesture state is updated once in the capture phase and can be used in the bubble phase. Be cautious with `onStartShould*` callbacks; they only reflect updated `gestureState` for start/end events that bubble/capture to the Node. Once a node becomes the responder, every start/end event updates the `gestureState`. Note that `numberActiveTouches` may not always be accurate unless you are the responder. 1179 1180## Installing dependencies 1181 1182To develop a React Native app, ensure you have Node, Watchman, the React Native CLI, a JDK, and Android Studio installed. While any editor can be used for development, Android Studio is necessary for setting up the Android build environment. 1183 1184### Node & Watchman 1185 1186Install Node and Watchman using Homebrew with these commands: 1187 1188```shell 1189brew install node 1190brew install watchman 1191``` 1192 1193Ensure your Node version is 18.18 or newer if already installed. Watchman, a filesystem monitoring tool by Facebook, enhances performance and is recommended for installation. 1194 1195### Java Development Kit (JDK) 1196 1197Install the OpenJDK distribution Azul Zulu using Homebrew: 1198 1199```shell 1200brew install --cask zulu@17 1201 1202# Find the JDK installer path 1203brew info --cask zulu@17 1204``` 1205 1206After locating the package, double-click `Double-Click to Install Azul Zulu JDK 17.pkg` in Finder. Set or update your `JAVA_HOME` environment variable: 1207 1208```shell 1209export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home 1210``` 1211 1212Zulu OpenJDK supports both Intel and M1 Macs, optimizing build speeds on M1 devices. If a JDK is already installed, use version 17 to avoid compatibility issues. 1213 1214### Android Development Environment 1215 1216Setting up the Android development environment can be complex for newcomers but straightforward if familiar with Android development. Follow these steps: 1217 1218#### 1. Install Android Studio 1219 1220Download and install Android Studio, ensuring you select `Android SDK`, `Android SDK Platform`, and `Android Virtual Device` during installation. If checkboxes are unavailable, they will appear later. 1221 1222After setup, proceed to the next step upon reaching the Welcome screen. 1223 1224#### 2. Install the Android SDK 1225 1226By default, Android Studio installs the latest Android SDK. For React Native apps with native code, install the `Android 15 (VanillaIceCream)` SDK via the SDK Manager in Android Studio: 1227 1228- Open Android Studio and select "More Actions" > "SDK Manager". 1229 1230- In the "SDK Platforms" tab, enable "Show Package Details", then expand `Android 15 (VanillaIceCream)`. Ensure these are checked: 1231 1232 - `Android SDK Platform 35` 1233 - `Intel x86 Atom_64 System Image` or `Google APIs Intel x86 Atom System Image` or for M1 Silicon: `Google APIs ARM 64 v8a System Image` 1234 1235- In the "SDK Tools" tab, enable "Show Package Details", expand "Android SDK Build-Tools", and select version `35.0.0`. 1236 1237- Click "Apply" to install. 1238 1239#### 3. Configure the ANDROID\_HOME Environment Variable 1240 1241Set up necessary environment variables for React Native tools: 1242 1243```shell 1244export ANDROID_HOME=$HOME/Library/Android/sdk 1245export PATH=$PATH:$ANDROID_HOME/emulator 1246export PATH=$PATH:$ANDROID_HOME/platform-tools 1247``` 1248 1249Load these settings with `source ~/.zprofile` (or `source ~/.bash_profile` for bash). Verify by running `echo $ANDROID_HOME` and `echo $PATH`. 1250 1251Ensure the correct Android SDK path is used, which can be found in Android Studio under **Languages & Frameworks** → **Android SDK**. 1252 1253### Preparing the Android Device 1254 1255To run your React Native app on Android, use either a physical device or an Android Virtual Device (AVD). 1256 1257#### Using a Physical Device 1258 1259Connect your Android device via USB and follow setup instructions for development. 1260 1261#### Using a Virtual Device 1262 1263Open `./AwesomeProject/android` in Android Studio to access AVDs. If needed, create a new AVD by selecting "Create Virtual Device...", choosing any Phone model, then the **VanillaIceCream** API Level 35 image. Launch your AVD with the green triangle button. 1264 1265### Congratulations! 1266 1267You've successfully set up your development environment for React Native on Android. 1268 1269#### Next Steps 1270 1271- For integrating React Native into an existing app, refer to the Integration guide. 1272- To learn more about React Native, explore the Introduction to React Native. 1273 1274## Installing Dependencies (iOS) 1275 1276For iOS development with React Native, ensure you have Node, Watchman, Xcode, and CocoaPods installed. While any editor can be used for coding, Xcode is essential for building your app. 1277 1278### Node & Watchman 1279 1280Install Node and Watchman using Homebrew: 1281 1282```shell 1283brew install node 1284brew install watchman 1285``` 1286 1287Ensure Node version 18.18 or newer if already installed. Watchman improves performance by monitoring filesystem changes. 1288 1289### Xcode 1290 1291Use the latest version of Xcode, available via the Mac App Store. This installs the iOS Simulator and necessary tools for building your app. 1292 1293#### Command Line Tools 1294 1295Install Xcode Command Line Tools from **Xcode > Settings...** under the Locations panel. 1296 1297#### Installing an iOS Simulator in Xcode 1298 1299Access simulators through **Xcode > Settings... > Platforms (or Components)** tab, selecting a simulator with the desired iOS version. For Xcode 14.0 or newer, use the "+" icon and select "iOS…". 1300 1301### CocoaPods 1302 1303CocoaPods is a dependency management system for iOS, installable via Ruby gem using macOS's default Ruby. 1304 1305For more details, visit the CocoaPods Getting Started guide. 1306 1307#### Optional: Configuring Your Environment 1308 1309From React Native 0.69 onwards, configure Xcode with the `.xcode.env` file provided by the template. Set the `NODE_BINARY` variable to your Node executable path for decoupling from system Node versions. Add other environment variables as needed and source `.xcode.env` in build script phases. 1310 1311If using NVM (Node Version Manager) with zsh, move NVM initialization code from `~/.zshrc` to `~/.zshenv`: 1312 1313```shell 1314export NVM_DIR="$HOME/.nvm" 1315[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 1316``` 1317 1318Ensure all "shell script build phase" in Xcode uses `/bin/zsh`. 1319 1320### Congratulations! 1321 1322You've successfully set up your iOS development environment for React Native. 1323 1324#### Next Steps 1325 1326- For integrating React Native into an existing app, refer to the Integration guide. 1327- To learn more about React Native, explore the Introduction to React Native. 1328 1329## ImageBackground 1330 1331The `<ImageBackground>` component is designed for developers who are accustomed to using `background-image` in web development. It functions similarly to the `<Image>` component, allowing you to layer additional content on top of an image. 1332 1333### Considerations 1334 1335While `<ImageBackground>` provides basic functionality, it may not be suitable for all use cases. Developers are encouraged to review its source code and consider creating a custom component if necessary. 1336 1337**Note:** It is essential to define width and height style attributes when using this component. 1338 1339### Example Usage 1340 1341*Example section would typically include a demonstration of how to implement the `<ImageBackground>` component.* 1342 1343### Reference 1344 1345*Reference section would provide additional resources or links for further information about the `<ImageBackground>` component.* 1346 1347### Props 1348 1349#### Image Props 1350 1351The `<ImageBackground>` inherits all props from the `<Image>` component. 1352 1353#### `imageStyle` 1354 1355- **Type:** Image Style 1356- Description: Customizes the style of the image within the background. 1357 1358#### `imageRef` 1359 1360- **Type:** Ref 1361- Description: Allows setting a reference to the inner `Image` component for direct manipulation or access. 1362 1363#### `style` 1364 1365- **Type:** View Style 1366- Description: Applies styling to the view that contains the `<ImageBackground>`. 1367 1368## KeyboardAvoidingView 1369 1370The `KeyboardAvoidingView` component automatically adjusts its height, position, or bottom padding based on the keyboard's height to ensure it remains visible when the virtual keyboard is displayed. 1371 1372### Example 1373 1374*** 1375 1376### Reference 1377 1378### Props 1379 1380#### View Props 1381 1382Inherits properties from the View component. 1383 1384*** 1385 1386#### `behavior` 1387 1388Defines how the view should respond to the presence of the keyboard. Note that Android and iOS handle this prop differently, but setting `behavior` is recommended for both platforms. 1389 1390|Type| 1391|-| 1392|enum(`'height'`, `'position'`, `'padding'`)| 1393 1394*** 1395 1396#### `contentContainerStyle` 1397 1398Specifies the style applied to the content container (View) when the behavior is set to `'position'`. 1399 1400|Type| 1401|-| 1402|View Style| 1403 1404*** 1405 1406#### `enabled` 1407 1408Determines whether the `KeyboardAvoidingView` is active or inactive. 1409 1410|Type|Default| 1411|-|-| 1412|boolean|`true`| 1413 1414*** 1415 1416#### `keyboardVerticalOffset` 1417 1418Represents the distance between the top of the user's screen and the React Native view. This value may be non-zero in certain scenarios. 1419 1420|Type|Default| 1421|-|-| 1422|number|`0`| 1423 1424## Modal 1425 1426The Modal component provides a straightforward method to display content above an enclosing view. 1427 1428### Example 1429 1430*** 1431 1432### Reference 1433 1434### Props 1435 1436#### View Props 1437 1438Inherits properties from the View component. 1439 1440*** 1441 1442#### `animationType` 1443 1444Controls the animation style of the modal. 1445 1446Possible values: 1447 1448- `slide`: Slides in from the bottom. 1449- `fade`: Fades into view. 1450- `none`: Appears without any animation. 1451 1452|Type|Default| 1453|-|-| 1454|enum(`'none'`, `'slide'`, `'fade'`)|`none`| 1455 1456*** 1457 1458#### `backdropColor` 1459 1460Sets the background color of the modal's container. Defaults to `white` unless `transparent` is set to `true`. 1461 1462|Type|Default| 1463|-|-| 1464|color|white| 1465 1466*** 1467 1468#### `hardwareAccelerated` (Android) 1469 1470Determines if hardware acceleration should be forced for the underlying window. 1471 1472|Type|Default| 1473|-|-| 1474|bool|`false`| 1475 1476*** 1477 1478#### `navigationBarTranslucent` (Android) 1479 1480Decides whether the modal appears under the system navigation bar. Requires `statusBarTranslucent` to also be `true`. 1481 1482|Type|Default| 1483|-|-| 1484|bool|`false`| 1485 1486*** 1487 1488#### `onDismiss` (iOS) 1489 1490Allows a function to be called when the modal is dismissed. 1491 1492|Type| 1493|-| 1494|function| 1495 1496*** 1497 1498#### `onOrientationChange` (iOS) 1499 1500Triggered when the orientation changes while the modal is displayed. The callback provides 'portrait' or 'landscape'. It also fires on initial render, regardless of current orientation. 1501 1502|Type| 1503|-| 1504|function| 1505 1506*** 1507 1508#### `onRequestClose` 1509 1510Invoked when the user presses the hardware back button on Android or the menu button on Apple TV. Note that `BackHandler` events are suppressed while the modal is open. On iOS, it's called during a drag gesture dismissal with `presentationStyle` set to `pageSheet` or `formSheet`. 1511 1512|Type| 1513|-| 1514|functionRequiredAndroidTV\*\*\*functioniOS| 1515 1516*** 1517 1518#### `onShow` 1519 1520Allows a function to be executed once the modal is displayed. 1521 1522|Type| 1523|-| 1524|function| 1525 1526*** 1527 1528#### `presentationStyle` (iOS) 1529 1530Determines how the modal appears on larger devices like iPads or plus-sized iPhones. Refer to [UIModalPresentationStyle](https://developer.apple.com/reference/uikit/uimodalpresentationstyle) for more details. 1531 1532Possible values: 1533 1534- `fullScreen`: Covers the entire screen. 1535- `pageSheet`: Centers a portrait-width view (on larger devices). 1536- `formSheet`: Centers a narrow-width view (on larger devices). 1537- `overFullScreen`: Covers the screen completely but allows transparency. 1538 1539|Type|Default| 1540|-|-| 1541|enum(`'fullScreen'`, `'pageSheet'`, `'formSheet'`, `'overFullScreen'`)|`fullScreen` if `transparent={false}`\*\*\*`overFullScreen` if `transparent={true}`| 1542 1543*** 1544 1545#### `statusBarTranslucent` (Android) 1546 1547Determines whether the modal appears under the system status bar. 1548 1549|Type|Default| 1550|-|-| 1551|bool|`false`| 1552 1553*** 1554 1555#### `supportedOrientations` (iOS) 1556 1557Allows rotation of the modal to specified orientations. On iOS, it's limited by the app's Info.plist settings for UISupportedInterfaceOrientations. 1558 1559> Ignored when using `presentationStyle` of `pageSheet` or `formSheet`. 1560 1561|Type|Default| 1562|-|-| 1563|array of enums(`'portrait'`, `'portrait-upside-down'`, `'landscape'`, `'landscape-left'`, `'landscape-right'`)|`['portrait']`| 1564 1565*** 1566 1567#### `transparent` 1568 1569Determines if the modal will cover the entire view with a transparent background. 1570 1571|Type|Default| 1572|-|-| 1573|bool|`false`| 1574 1575*** 1576 1577#### `visible` 1578 1579Controls whether the modal is visible or not. 1580 1581|Type|Default| 1582|-|-| 1583|bool|`true`| 1584 1585## Key Concepts 1586 1587To integrate React Native into an existing iOS application, follow these steps carefully. This guide assumes you have a basic understanding of both iOS development using Xcode and JavaScript/React Native. 1588 1589#### Prerequisites 1590 15911. **Node.js**: Ensure Node.js is installed on your machine. You can download it from [nodejs.org](https://nodejs.org/). 15921. **Xcode**: Make sure you have the latest version of Xcode installed. 15931. **CocoaPods**: Install CocoaPods if not already installed, using `sudo gem install cocoapods`. 1594 1595#### Step-by-Step Integration 1596 1597##### 1. Set Up React Native Environment 1598 1599First, initialize a new React Native project in your existing iOS app directory: 1600 1601```bash 1602npx react-native init MyReactNativeApp --template react-native-template-typescript 1603``` 1604 1605This command creates a new React Native project using TypeScript. 1606 1607##### 2. Configure CocoaPods 1608 1609Navigate to the `ios` directory of your React Native project and open the `Podfile`. Add the following lines: 1610 1611```ruby 1612platform :ios, '11.0' 1613 1614require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 1615``` 1616 1617Then run: 1618 1619```bash 1620pod install 1621``` 1622 1623This installs necessary dependencies for React Native. 1624 1625##### 3. Modify Xcode Project 1626 1627Open your `.xcworkspace` file in Xcode. Ensure that the `User Script Sandboxing` is set to `NO` under Build Settings > Scripting. 1628 1629Add a new Run Script Phase in Xcode: 1630 16311. Select your application target. 16321. Go to `Build Phases`. 16331. Click on the `+` button and select `New Run Script Phase`. 16341. Rename it to `Bundle React Native code and images`. 16351. Add the following script: 1636 1637```bash 1638set -e 1639 1640WITH_ENVIRONMENT="$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh" 1641REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh" 1642 1643/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE" 1644``` 1645 1646Drag this script above `[CP] Embed Pods Frameworks`. 1647 1648##### 4. Create Metro Configuration 1649 1650In the root of your project, create a `metro.config.js` file: 1651 1652```javascript 1653const { getDefaultConfig } = require("@react-native/metro-config") 1654module.exports = getDefaultConfig(__dirname) 1655``` 1656 1657Create a `.watchmanconfig` file with an empty JSON object: 1658 1659```bash 1660echo {} > .watchmanconfig 1661``` 1662 1663##### 5. Start Metro Bundler 1664 1665Run the following command in your project root to start the Metro bundler: 1666 1667```bash 1668npx react-native start 1669``` 1670 1671##### 6. Build and Run Your iOS App 1672 1673In Xcode, build and run your app as usual. Ensure that you have a button or some mechanism to present the React Native view. 1674 1675##### 7. Passing Initial Props 1676 1677To pass initial properties from native code to JavaScript: 1678 1679**Objective-C:** 1680 1681Modify `ReactViewController.mm`: 1682 1683```objective-c 1684self.view = [_factory.rootViewFactory viewWithModuleName:@"HelloWorld" initialProperties:@{ 1685 @"userID": @"12345678", 1686 @"token": @"secretToken" 1687}]; 1688``` 1689 1690**Swift:** 1691 1692Modify `ReactViewController.swift`: 1693 1694```swift 1695view = reactNativeFactory!.rootViewFactory.view(withModuleName: "HelloWorld", initialProperties: [ 1696 "userID": "12345678", 1697 "token": "secretToken" 1698]) 1699``` 1700 1701Update your `App.tsx` to read these properties: 1702 1703```tsx 1704function App(props): React.JSX.Element { 1705 const isDarkMode = useColorScheme() === "dark" 1706 1707 return ( 1708 <SafeAreaView 1709 style={{ backgroundColor: isDarkMode ? Colors.darker : Colors.lighter }} 1710 > 1711 <StatusBar barStyle={isDarkMode ? "light-content" : "dark-content"} /> 1712 <ScrollView contentInsetAdjustmentBehavior="automatic"> 1713 <Header /> 1714 <View> 1715 <Text style={styles.title}>UserID: {props.userID}</Text> 1716 <Text style={styles.title}>Token: {props.token}</Text> 1717 </View> 1718 </ScrollView> 1719 </SafeAreaView> 1720 ) 1721} 1722``` 1723 1724#### Testing and Debugging 1725 1726- Ensure your app is running in development mode to see changes reflected immediately. 1727- Use React Native Debugger or Chrome DevTools for debugging JavaScript code. 1728 1729#### Deployment 1730 1731For release builds, ensure the script phase for bundling JS and images is correctly configured. Test thoroughly on both simulators and real devices. 1732 1733By following these steps, you should be able to integrate React Native into your existing iOS application successfully. Continue developing using React Native's extensive documentation for further guidance. 1734 1735## Pressable 1736 1737Pressable is a Core Component wrapper designed to detect various stages of press interactions on any defined children elements. 1738 1739```typescript 1740<Pressable onPress={onPressFunction}> 1741 <Text>I'm pressable!</Text> 1742</Pressable> 1743``` 1744 1745### How it Works 1746 1747When an element is wrapped by `Pressable`: 1748 1749- `onPressIn` is triggered when a press interaction begins. 1750- `onPressOut` occurs when the press gesture ends. 1751 1752Following `onPressIn`, one of two scenarios may unfold: 1753 17541. The user lifts their finger, triggering `onPressOut` followed by `onPress`. 17551. If the finger remains for more than 500 milliseconds before lifting, `onLongPress` is activated. `onPressOut` will still occur upon finger removal. 1756 1757To accommodate imprecise touch interactions and accidental activations, `Pressable` offers an optional `HitRect`. This defines how far a touch can register from the wrapped element, allowing presses to start anywhere within this area. 1758 1759Additionally, `PressRect` is set using `pressRetentionOffset`, enabling touches to move beyond the element and its `HitRect` while still maintaining activation. This feature allows for actions like sliding a finger away from a button that's being pressed. 1760 1761> Note: The touch area does not extend past parent view bounds, and sibling views with higher Z-index take precedence if a touch hits overlapping views. 1762 1763For more details on the state machine flow of Pressability, refer to React Native's `Pressability` API documentation. 1764 1765### Example 1766 1767### Props 1768 1769#### `android_disableSound` 1770 1771- **Type**: boolean 1772- **Default**: `false` 1773- If true, prevents Android system sound from playing on press. 1774 1775#### `android_ripple` 1776 1777- **Type**: RippleConfig 1778- Enables the Android ripple effect and configures its properties. 1779 1780#### `children` 1781 1782- **Type**: React Node 1783- Accepts children or a function that receives a boolean indicating if the component is currently pressed. 1784 1785#### `unstable_pressDelay` 1786 1787- **Type**: number 1788- Duration (in milliseconds) to wait after press down before calling `onPressIn`. 1789 1790#### `delayLongPress` 1791 1792- **Type**: number 1793- **Default**: `500` 1794- Duration (in milliseconds) from `onPressIn` before `onLongPress` is triggered. 1795 1796#### `disabled` 1797 1798- **Type**: boolean 1799- **Default**: `false` 1800- Determines if the press behavior is disabled. 1801 1802#### `hitSlop` 1803 1804- **Type**: Rect or number 1805- Sets additional distance outside of the element where a press can be detected. 1806 1807#### `onHoverIn` 1808 1809- **Type**: `({ nativeEvent: MouseEvent }) => void` 1810- Called when hover is activated to provide visual feedback. 1811 1812#### `onHoverOut` 1813 1814- **Type**: `({ nativeEvent: MouseEvent }) => void` 1815- Called when hover is deactivated to remove visual feedback. 1816 1817#### `onLongPress` 1818 1819- **Type**: `({nativeEvent: PressEvent}) => void` 1820- Triggered if the time after `onPressIn` exceeds 500 milliseconds. This duration can be customized with `delayLongPress`. 1821 1822#### `onPress` 1823 1824- **Type**: `({nativeEvent: PressEvent}) => void` 1825- Called after `onPressOut`. 1826 1827#### `onPressIn` 1828 1829- **Type**: `({nativeEvent: PressEvent}) => void` 1830- Triggered immediately when a touch is engaged, before `onPressOut` and `onPress`. 1831 1832#### `onPressOut` 1833 1834- **Type**: `({nativeEvent: PressEvent}) => void` 1835- Called when a touch is released. 1836 1837#### `pressRetentionOffset` 1838 1839- **Type**: Rect or number 1840- **Default**: `{bottom: 30, left: 20, right: 20, top: 20}` 1841- Sets additional distance outside of this view where a touch is considered a press before triggering `onPressOut`. 1842 1843#### `style` 1844 1845- **Type**: View Style or `({ pressed: boolean }) => View Style` 1846- Accepts view styles or a function that receives a boolean indicating if the component is currently pressed and returns view styles. 1847 1848#### `testOnly_pressed` 1849 1850- **Type**: boolean 1851- **Default**: `false` 1852- Used only for documentation or testing purposes (e.g., snapshot testing). 1853 1854### Type Definitions 1855 1856#### RippleConfig 1857 1858Configuration object for the `android_ripple` property. 1859 1860|Name|Type|Required|Description| 1861|-|-|-|-| 1862|color|color|No|Defines the color of the ripple effect.| 1863|borderless|boolean|No|Determines if the ripple effect should exclude borders.| 1864|radius|number|No|Sets the radius of the ripple effect.| 1865|foreground|boolean|No|If true, adds the ripple effect to the view's foreground instead of the background. Useful when child views have their own backgrounds or images are displayed, preventing the ripple from being obscured.| 1866 1867## RefreshControl 1868 1869The `RefreshControl` component is designed to be used within a ScrollView or ListView, providing pull-to-refresh functionality. When the scroll position (`scrollY`) reaches zero and the user swipes down, an `onRefresh` event is triggered. 1870 1871### Example Usage 1872 1873> **Note:** The `refreshing` prop is controlled, meaning it must be set to `true` during the `onRefresh` function execution; otherwise, the refresh indicator will cease immediately. 1874 1875### Reference Guide 1876 1877#### Props Overview 1878 1879##### Inherited View Props 1880 1881- Inherits all properties from the View component. 1882 1883##### Required Prop: `refreshing` 1884 1885- **Type:** boolean\ 1886 Indicates whether the view is currently showing an active refresh state. 1887 1888##### Android-Specific Props 1889 1890- **`colors`:** 1891 1892 - **Type:** array of colors\ 1893 Specifies the colors used to draw the refresh indicator. At least one color must be provided. 1894 1895- **`enabled`:** 1896 1897 - **Type:** boolean 1898 - **Default:** `true`\ 1899 Determines if pull-to-refresh functionality is enabled. 1900 1901- **`onRefresh`:** 1902 1903 - **Type:** function\ 1904 Triggered when the view begins refreshing. 1905 1906- **`progressBackgroundColor`:** 1907 1908 - **Type:** color\ 1909 Sets the background color of the refresh indicator. 1910 1911- **`progressViewOffset`:** 1912 1913 - **Type:** number 1914 - **Default:** `0`\ 1915 Defines the top offset for the progress view. 1916 1917- **`size`:** 1918 - **Type:** enum(`'default'`, `'large'`) 1919 - **Default:** `'default'`\ 1920 Specifies the size of the refresh indicator. 1921 1922##### iOS-Specific Props 1923 1924- **`tintColor`:** 1925 1926 - **Type:** color\ 1927 Sets the color of the refresh indicator. 1928 1929- **`title`:** 1930 1931 - **Type:** string\ 1932 The title displayed beneath the refresh indicator. 1933 1934- **`titleColor`:** 1935 - **Type:** color\ 1936 Defines the color of the refresh indicator's title. 1937 1938## Integration with Existing Apps 1939 1940This guide details how to integrate a full-screen React Native app into an existing Android app as an **Activity**. To use React Native components within **Fragments** in an existing app, additional setup is required. 1941 1942### 1. Add React Native to Your App 1943 1944Follow the guide for Integration with Existing Apps until the end to ensure your React Native app can run safely in a full-screen Activity. 1945 1946### 2. Add a FrameLayout for the React Native Fragment 1947 1948To integrate a React Native Fragment into an Activity, use a `FrameLayout`. This method is adaptable for other layouts like Bottom Sheets or Tab Layouts. 1949 1950Add a `<FrameLayout>` with an id, width, and height to your Activity's layout (e.g., `main_activity.xml` in the `res/layouts` folder). This layout will render your React Native Fragment. 1951 1952```xml 1953<FrameLayout 1954 android:id="@+id/react_native_fragment" 1955 android:layout_width="match_parent" 1956 android:layout_height="match_parent" /> 1957``` 1958 1959### 3. Implement `DefaultHardwareBackBtnHandler` 1960 1961Since the host activity is not a `ReactActivity`, implement the `DefaultHardwareBackBtnHandler` interface to handle back button press events, as required by React Native. 1962 1963Ensure your host activity implements this interface: 1964 1965#### Java 1966 1967```java 1968package <your-package-here>; 1969 1970import android.os.Bundle; 1971import androidx.appcompat.app.AppCompatActivity; 1972import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; 1973 1974public class MainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler { 1975 1976 @Override 1977 protected void onCreate(Bundle savedInstanceState) { 1978 super.onCreate(savedInstanceState); 1979 setContentView(R.layout.main_activity); 1980 1981 findViewById(R.id.sample_button).setOnClickListener(button -> { 1982 // Handle button click 1983 }); 1984 } 1985 1986 @Override 1987 public void invokeDefaultOnBackPressed() { 1988 super.onBackPressed(); 1989 } 1990} 1991``` 1992 1993#### Kotlin 1994 1995```kotlin 1996package <your-package-here> 1997 1998import android.os.Bundle 1999import androidx.appcompat.app.AppCompatActivity 2000import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler 2001 2002class MainActivity : AppCompatActivity(), DefaultHardwareBackBtnHandler { 2003 2004 override fun onCreate(savedInstanceState: Bundle?) { 2005 super.onCreate(savedInstanceState) 2006 setContentView(R.layout.main_activity) 2007 2008 findViewById<Button>(R.id.sample_button).setOnClickListener { 2009 // Handle button click 2010 } 2011 } 2012 2013 override fun invokeDefaultOnBackPressed() { 2014 super.onBackPressed() 2015 } 2016} 2017``` 2018 2019### 4. Add a React Native Fragment to the FrameLayout 2020 2021Update your Activity to add a React Native Fragment to the `FrameLayout`. Assume your Activity has a button with id `sample_button` that, when clicked, renders a React Native Fragment into the `FrameLayout`. 2022 2023#### Java 2024 2025```java 2026package <your-package-here>; 2027 2028import android.os.Bundle; 2029import androidx.appcompat.app.AppCompatActivity; 2030import com.facebook.react.ReactFragment; 2031import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; 2032 2033public class MainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler { 2034 2035 @Override 2036 protected void onCreate(Bundle savedInstanceState) { 2037 super.onCreate(savedInstanceState); 2038 setContentView(R.layout.main_activity); 2039 2040 findViewById(R.id.sample_button).setOnClickListener(button -> { 2041 Bundle launchOptions = new Bundle(); 2042 launchOptions.putString("message", "my value"); 2043 2044 ReactFragment fragment = new ReactFragment.Builder() 2045 .setComponentName("HelloWorld") 2046 .setLaunchOptions(launchOptions) 2047 .build(); 2048 getSupportFragmentManager() 2049 .beginTransaction() 2050 .add(R.id.react_native_fragment, fragment) 2051 .commit(); 2052 }); 2053 } 2054 2055 @Override 2056 public void invokeDefaultOnBackPressed() { 2057 super.onBackPressed(); 2058 } 2059} 2060``` 2061 2062#### Kotlin 2063 2064```kotlin 2065package <your-package-here> 2066 2067import android.os.Bundle 2068import androidx.appcompat.app.AppCompatActivity 2069import com.facebook.react.ReactFragment 2070import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler 2071 2072class MainActivity : AppCompatActivity(), DefaultHardwareBackBtnHandler { 2073 2074 override fun onCreate(savedInstanceState: Bundle?) { 2075 super.onCreate(savedInstanceState) 2076 setContentView(R.layout.main_activity) 2077 2078 findViewById<Button>(R.id.sample_button).setOnClickListener { 2079 val reactNativeFragment = ReactFragment.Builder() 2080 .setComponentName("HelloWorld") 2081 .setLaunchOptions(Bundle().apply { putString("message", "my value") }) 2082 .build() 2083 supportFragmentManager 2084 .beginTransaction() 2085 .add(R.id.react_native_fragment, reactNativeFragment) 2086 .commit() 2087 } 2088 } 2089 2090 override fun invokeDefaultOnBackPressed() { 2091 super.onBackPressed() 2092 } 2093} 2094``` 2095 2096#### Explanation 2097 2098- Use `ReactFragment.Builder()` to create a new `ReactFragment`. 2099- Add the Fragment to the `FrameLayout` using `supportFragmentManager`. 2100- Customize the fragment creation with: 2101 - `setComponentName`: Name of the component to render, specified in your `index.js` inside the `registerComponent` method. 2102 - `setLaunchOptions`: Optional method to pass initial props to your component. 2103 2104### 5. Test Your Integration 2105 2106Run `yarn start` to launch the bundler and then run your Android app in Android Studio. The app should load JavaScript/TypeScript code from the development server and display it in your React Native Fragment within the Activity. 2107 2108## Building For TV Devices 2109 2110Support for TV devices, specifically Apple TV and Android TV, was integrated into React Native applications with the goal of enabling these apps to function on such platforms with minimal modifications required in their JavaScript code. 2111 2112> **Deprecated Notice:** The support for TV devices has been transitioned to a separate repository named "React Native for TV." For detailed guidance on projects targeting Apple TV or Android TV, please refer to the *README* file within that repository. 2113 2114## ScrollView 2115 2116The provided documentation outlines various properties and methods associated with a ScrollView component, likely from a mobile development framework such as React Native. Below is a summary of the key features: 2117 2118#### Properties 2119 21201. **Automatic Scrolling**: 2121 2122 - Automatically scrolls to the top when the status bar is tapped (`scrollsToTop`). 2123 - Programmatically scroll beyond content size (`scrollToOverflowEnabled`). 2124 21251. **Scroll Indicators**: 2126 2127 - Control visibility of horizontal and vertical indicators. 2128 - Customize insets for scroll view indicators. 2129 21301. **Performance Enhancements**: 2131 2132 - Remove offscreen child views to improve performance (`removeClippedSubviews`). 2133 - Log scroll performance with a custom tag (`scrollPerfTag`). 2134 21351. **Scroll Behavior**: 2136 2137 - Enable or disable scrolling via touch interaction (`scrollEnabled`). 2138 - Throttle frequency of scroll events (`scrollEventThrottle`). 2139 - Control over-scroll behavior (`overScrollMode`). 2140 21411. **Refresh Control**: 2142 2143 - Implement pull-to-refresh functionality with `refreshControl`. 2144 21451. **Snap and Paging**: 2146 2147 - Snap to specific intervals or offsets for pagination (`snapToInterval`, `snapToOffsets`). 2148 - Align snapping positions (`snapToAlignment`). 2149 - Enable paging behavior (`pagingEnabled`). 2150 21511. **Nested Scrolling**: 2152 2153 - Support nested scrolling on Android API level 21+ (`nestedScrollEnabled`). 2154 21551. **Zooming**: 2156 2157 - Control zoom scale and enable pinch gestures for zooming. 2158 21591. **Sticky Headers**: 2160 2161 - Fix certain headers to the top during scroll (`stickyHeaderIndices`, `stickyHeaderHiddenOnScroll`). 2162 21631. **Event Handling**: 2164 - Callbacks for various scroll events (e.g., `onScroll`, `onMomentumScrollBegin`). 2165 2166#### Methods 2167 21681. **Flash Scroll Indicators**: 2169 2170 - Temporarily display scroll indicators (`flashScrollIndicators`). 2171 21721. **Programmatic Scrolling**: 2173 - Scroll to specific coordinates with optional animation (`scrollTo`). 2174 - Automatically scroll to the end of content (`scrollToEnd`). 2175 2176These properties and methods provide extensive control over scrolling behavior, performance optimization, and user interaction within a ScrollView component. 2177 2178## Out-of-Tree Platforms 2179 2180React Native extends beyond Android and iOS devices. Various partners and community projects have developed React Native for additional platforms: 2181 2182**From Partners** 2183 2184- **React Native macOS**: Supports macOS and Cocoa applications. 2185- **React Native Windows**: Targets Microsoft's Universal Windows Platform (UWP). 2186- **React Native visionOS**: Designed for Apple's visionOS. 2187 2188**From Community** 2189 2190- **React Native tvOS**: Compatible with Apple TV and Android TV devices. 2191- **React Native Web**: Enables React Native on the web using React DOM. 2192- **React Native Skia**: Utilizes Skia as a renderer, supporting Linux and macOS. 2193 2194### Creating Your Own React Native Platform 2195 2196Currently, creating a new React Native platform from scratch lacks comprehensive documentation. The upcoming re-architecture (Fabric) aims to simplify this process. 2197 2198#### Bundling 2199 2200Starting with React Native 0.57, you can register your custom platform with the JavaScript bundler, Metro. This allows using `--platform example` with `npx react-native bundle`, which will search for JavaScript files ending in `.example.js`. 2201 2202To integrate your module with RNPM, its name should follow these patterns: 2203 2204- **`react-native-example`**: Searches all top-level modules starting with `react-native-`. 2205- **`@org/react-native-example`**: Looks for modules under any scope that start with `react-native-`. 2206- **`@react-native-example/module`**: Searches within scopes beginning with `@react-native-`. 2207 2208Your `package.json` must include an entry like this: 2209 2210```json 2211{ 2212 "rnpm": { 2213 "haste": { 2214 "providesModuleNodeModules": ["react-native-example"], 2215 "platforms": ["example"] 2216 } 2217 } 2218} 2219``` 2220 2221Here, `"providesModuleNodeModules"` is a list of modules added to the Haste module search path, and `"platforms"` specifies valid platform suffixes. 2222 2223## StatusBar 2224 2225The `StatusBar` component manages the app's status bar, which is typically located at the top of the screen. It displays information such as time, network status, battery level, and other status icons. 2226 2227### Usage with Navigator 2228 2229Multiple `StatusBar` components can be mounted simultaneously. The properties of these components are merged in the order they were mounted. 2230 2231- **TypeScript** 2232- **JavaScript** 2233 2234#### Imperative API 2235 2236For scenarios where using a component is not ideal, an imperative API is available through static functions on the component. However, it's not recommended to use both the static API and the component for the same property simultaneously, as values set by the static API will be overridden by those set by the component in subsequent renders. 2237 2238### Reference 2239 2240#### Constants 2241 2242- **`currentHeight` (Android):** Represents the height of the status bar, including any notch height if present. 2243 2244### Props 2245 2246|Prop Name|Type|Required|Default|Description| 2247|-|-|-|-|-| 2248|`animated`|boolean|No|`false`|Determines if transitions between status bar property changes should be animated. Supported for `backgroundColor`, `barStyle`, and `hidden`.| 2249|`backgroundColor` (Android)|color|No|Default system StatusBar background color or `'black'` if not defined|The background color of the status bar. **Warning:** Deprecated in API level 35 due to edge-to-edge enforcement introduced in Android 15.| 2250|`barStyle`|StatusBarStyle|No|`'default'`|Sets the color of the status bar text. On Android, this affects only API versions 23 and above.| 2251|`hidden`|boolean|No|`false`|Determines if the status bar is hidden.| 2252|`networkActivityIndicatorVisible` (iOS)|boolean|No|`false`|Controls visibility of the network activity indicator.| 2253|`showHideTransition` (iOS)|StatusBarAnimation|No|`'fade'`|The transition effect when showing or hiding the status bar using the `hidden` prop.| 2254|`translucent` (Android)|boolean|No|`false`|Determines if the status bar is translucent, allowing the app to draw under it. Useful with a semi-transparent status bar color.| 2255 2256### Methods 2257 2258#### `popStackEntry()` 2259 2260```typescript 2261static popStackEntry(entry: StatusBarProps): void; 2262``` 2263 2264Get and remove the last `StatusBar` entry from the stack. 2265 2266**Parameters:** 2267 2268- **entry (Required)**: Entry returned from `pushStackEntry`. 2269 2270#### `pushStackEntry()` 2271 2272```typescript 2273static pushStackEntry(props: StatusBarProps): StatusBarProps; 2274``` 2275 2276Push a `StatusBar` entry onto the stack. The return value should be passed to `popStackEntry` when complete. 2277 2278**Parameters:** 2279 2280- **props (Required)**: Object containing the `StatusBar` props for the stack entry. 2281 2282#### `replaceStackEntry()` 2283 2284```typescript 2285static replaceStackEntry( 2286 entry: StatusBarProps, 2287 props: StatusBarProps 2288): StatusBarProps; 2289``` 2290 2291Replace an existing `StatusBar` stack entry with new properties. 2292 2293**Parameters:** 2294 2295|Name|Type|Description| 2296|-|-|-| 2297|**entry (Required)**|any|Entry returned from `pushStackEntry` to replace.| 2298|**props (Required)**|any|Object containing the `StatusBar` props for the replacement stack entry.| 2299 2300#### `setBackgroundColor()` (Android) 2301 2302```typescript 2303static setBackgroundColor(color: ColorValue, animated?: boolean): void; 2304``` 2305 2306Set the background color of the status bar. 2307 2308**Warning:** Deprecated in API level 35 due to edge-to-edge enforcement introduced in Android 15. 2309 2310**Parameters:** 2311 2312|Name|Type|Description| 2313|-|-|-| 2314|**color (Required)**|string|Background color.| 2315|animated|boolean|Animate the style change.| 2316 2317#### `setBarStyle()` 2318 2319```typescript 2320static setBarStyle(style: StatusBarStyle, animated?: boolean): void; 2321``` 2322 2323Set the status bar style. 2324 2325**Parameters:** 2326 2327|Name|Type|Description| 2328|-|-|-| 2329|**style (Required)**|StatusBarStyle|Status bar style to set.| 2330|animated|boolean|Animate the style change.| 2331 2332#### `setHidden()` 2333 2334```typescript 2335static setHidden(hidden: boolean, animation?: StatusBarAnimation): void; 2336``` 2337 2338Show or hide the status bar. 2339 2340**Parameters:** 2341 2342|Name|Type|Description| 2343|-|-|-| 2344|**hidden (Required)**|boolean|Hide the status bar.| 2345|animation (iOS)|StatusBarAnimation|Animation when changing the hidden property of the status bar.| 2346 2347#### `setNetworkActivityIndicatorVisible()` (iOS) 2348 2349```typescript 2350static setNetworkActivityIndicatorVisible(visible: boolean): void; 2351``` 2352 2353Control the visibility of the network activity indicator. 2354 2355**Parameters:** 2356 2357- **visible (Required)**: Show the indicator. 2358 2359#### `setTranslucent()` (Android) 2360 2361```typescript 2362static setTranslucent(translucent: boolean): void; 2363``` 2364 2365Control the translucency of the status bar. 2366 2367**Parameters:** 2368 2369- **translucent (Required)**: Set as translucent. 2370 2371### Type Definitions 2372 2373#### StatusBarAnimation 2374 2375Enum representing the status bar animation type for transitions on iOS. 2376 2377|Value|Type|Description| 2378|-|-|-| 2379|`'fade'`|string|Fade animation.| 2380|`'slide'`|string|Slide animation.| 2381|`'none'`|string|No animation.| 2382 2383#### StatusBarStyle 2384 2385Enum representing the status bar style type. 2386 2387|Value|Type|Description| 2388|-|-|-| 2389|`'default'`|string|Default status bar style (dark for iOS, light for Android).| 2390|`'light-content'`|string|White texts and icons.| 2391|`'dark-content'`|string|Dark texts and icons (requires API>=23 on Android).| 2392 2393## 1. Enable Debugging over USB 2394 2395Most Android devices restrict app installations to those downloaded from Google Play by default. To install apps during development, enable USB Debugging on your device. 2396 2397### Steps to Enable USB Debugging: 2398 23991. **Access Developer Options:** 2400 2401 - Navigate to **Settings** → **About phone** → **Software information**. 2402 - Tap the `Build number` row seven times to unlock "Developer options". 2403 24041. **Enable USB Debugging:** 2405 - Go back to **Settings** → **Developer options**. 2406 - Turn on "USB debugging". 2407 2408## Setting Up an Android Device for React Native Development 2409 2410### 1. Connect Your Device via USB 2411 2412- Plug your device into your development machine using a USB cable. 2413 2414#### Verify Connection with ADB: 2415 2416Run the following command to ensure your device is connected: 2417 2418```shell 2419$ adb devices 2420``` 2421 2422Output example: 2423 2424``` 2425List of devices attached 2426emulator-5554 offline # Google emulator 242714ed2fcc device # Physical device 2428``` 2429 2430A `device` status indicates a successful connection. Ensure only one device is connected at a time. 2431 2432#### Troubleshooting: 2433 2434If you see `unauthorized`, execute the following command and allow USB debugging on your device: 2435 2436```shell 2437adb reverse tcp:8081 tcp:8081 2438``` 2439 2440### 2. Running Your App 2441 2442From your project's root directory, use either npm or Yarn to install and launch your app: 2443 2444#### Using npm: 2445 2446```shell 2447npm run android 2448``` 2449 2450#### Using Yarn: 2451 2452```shell 2453yarn android 2454``` 2455 2456> **Note:** For a release build, use: `yarn android --mode release`. 2457 2458## Connecting to the Development Server 2459 2460Iterate quickly on a device by connecting it to your development server. Choose between USB or Wi-Fi methods. 2461 2462### Method 1: Using adb reverse (Recommended) 2463 2464This method is suitable for devices running Android 5.0 (Lollipop) or newer with USB debugging enabled and connected via USB. 2465 2466Execute the following command: 2467 2468```shell 2469$ adb -s <device name> reverse tcp:8081 tcp:8081 2470``` 2471 2472To find your device name, run: 2473 2474```shell 2475$ adb devices 2476``` 2477 2478Enable Fast Refresh from the Dev Menu to reload your app upon JavaScript code changes. 2479 2480### Method 2: Connect via Wi-Fi 2481 2482Connect over Wi-Fi after initially installing the app with a USB cable. Ensure both your laptop and phone are on the same network. 2483 2484#### Steps: 2485 24861. Open your React Native app; expect an initial error screen. 24871. Access the in-app Dev Menu. 24881. Navigate to **Dev Settings** → **Debug server host & port for device**. 24891. Enter your machine's IP address and local dev server port (e.g., `10.0.1.1:8081`). 24901. Select **Reload JS** from the Dev Menu. 2491 2492Enable Fast Refresh to automatically reload your app when JavaScript code changes. 2493 2494## Building Your App for Production 2495 2496To release your React Native app on the Play Store, follow standard native Android app production processes with additional considerations. Refer to the guide for generating a signed APK for detailed instructions. 2497 2498### Additional Setup for Linux Users: 2499 2500#### Identify USB Device ID: 2501 25021. Use `lsusb` to list connected USB devices: 2503 2504 ```bash 2505 $ lsusb 2506 ``` 2507 25081. Identify your phone's line and extract the first four digits of its device ID (e.g., `22b8`). 2509 25101. Update udev rules with the following command, replacing `22b8` with your device ID: 2511 2512 ```shell 2513 echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="22b8", MODE="0666", GROUP="plugdev"' | sudo tee /etc/udev/rules.d/51-android-usb.rules 2514 ``` 2515 2516#### Verify ADB Connection Again: 2517 2518Run `adb devices` to confirm your device is connected. 2519 2520## Summary 2521 2522This guide covers enabling USB debugging, setting up an Android device for React Native development, connecting to the development server via USB or Wi-Fi, and preparing your app for production release. Follow these steps to streamline your development workflow. 2523 2524## Switch 2525 2526The `Switch` component renders a boolean input and functions as a controlled component. It necessitates an `onValueChange` callback to update its `value` prop, ensuring that user interactions are accurately reflected in the UI. Without updating the `value` prop, the component will persistently display the initially supplied value. 2527 2528### Example 2529 2530*Example usage of the Switch component is not provided here.* 2531 2532### Reference 2533 2534*Reference details for the Switch component are not included here.* 2535 2536### Props 2537 2538#### View Props 2539 2540The `Switch` inherits all View Props. 2541 2542#### `disabled` 2543 2544- **Description**: Disables user interaction with the switch. 2545- **Type**: `bool` 2546- **Default**: `false` 2547 2548#### `ios_backgroundColor` 2549 2550- **Description**: On iOS, this sets a custom background color for the switch. This color is visible when the switch value is `false` or if the switch is disabled and translucent. 2551- **Type**: `color` 2552 2553#### `onChange` 2554 2555- **Description**: Triggered when there's an attempt to change the switch's value. It receives the change event as its argument. For receiving only the new value, use `onValueChange`. 2556- **Type**: `function` 2557 2558#### `onValueChange` 2559 2560- **Description**: Called upon attempts to alter the switch's value. This prop receives the new value directly. To receive an event instead, utilize `onChange`. 2561- **Type**: `function` 2562 2563#### `thumbColor` 2564 2565- **Description**: Sets the color of the switch's foreground grip. On iOS, setting this will remove the drop shadow from the switch grip. 2566- **Type**: `color` 2567 2568#### `trackColor` 2569 2570- **Description**: Defines custom colors for the switch track. 2571 - *iOS*: When the switch is off (`false`), the track contracts into its border. To modify the color of the background revealed by this contracted track, use `ios_backgroundColor`. 2572- **Type**: `object: { false: color, true: color }` 2573 2574#### `value` 2575 2576- **Description**: Determines the state of the switch. If set to `true`, the switch is on; otherwise, it's off. The default value is `false`. 2577- **Type**: `bool` 2578 2579## Fast Refresh 2580 2581Fast Refresh is a feature in React Native that provides near-instant feedback when changes are made to your React components. By default, this feature is enabled and can be toggled through the "Enable Fast Refresh" option in the React Native Dev Menu. With it activated, most edits should become visible within seconds. 2582 2583### How It Works 2584 2585- **React Component Exports**: If you modify a module that exclusively exports React components, Fast Refresh will update only that specific module and re-render your component. This includes changes to styles, rendering logic, event handlers, or effects. 2586 2587- **Non-Component Exports**: When editing a module with non-component exports, Fast Refresh triggers a re-run of both the edited module and any other modules importing it. For instance, if `Button.js` and `Modal.js` both import `Theme.js`, changes to `Theme.js` will update both components. 2588 2589- **Non-React Imports**: If you edit a file imported by non-React tree modules, Fast Refresh defaults to a full reload. This often occurs when a component exports values used by non-React utilities. To maintain Fast Refresh functionality, consider moving such constants to separate files and importing them where needed. 2590 2591### Error Resilience 2592 2593Fast Refresh is designed to handle errors gracefully: 2594 2595- **Syntax Errors**: Fixing syntax errors during a session will remove the redbox error message without requiring an app reload. 2596 2597- **Runtime Initialization Errors**: Errors occurring during module initialization (e.g., `Style.create` instead of `StyleSheet.create`) allow the session to continue once corrected, with the redbox disappearing and the module updating. 2598 2599- **Component Runtime Errors**: Even if a runtime error occurs within your component, Fast Refresh continues after fixing it. React will remount the application using the updated code. 2600 2601Error boundaries in your app can help manage errors gracefully by retrying rendering on subsequent edits, preventing constant fallback to the root screen. However, they should not be overly granular and must be used intentionally. 2602 2603### Limitations 2604 2605While Fast Refresh aims to preserve local React state during edits, there are scenarios where it may reset: 2606 2607- **Class Components**: State is not preserved for class components; only function components and Hooks maintain state. 2608 2609- **Multiple Exports**: Modules with additional exports besides a React component might see their state reset. 2610 2611- **Higher-Order Component Results**: If a module exports the result of a higher-order component like `createNavigationContainer(MyScreen)` and returns a class, its state will be reset. 2612 2613As more code transitions to function components and Hooks, state preservation is expected to improve. 2614 2615### Tips 2616 2617- Fast Refresh inherently preserves local React state in function components (and Hooks). 2618 2619- To force a component remount on every edit—useful for animations that occur on mount—you can add `// @refresh reset` within the file being edited. This directive instructs Fast Refresh to remount components defined in that file with each edit. 2620 2621### Fast Refresh and Hooks 2622 2623Fast Refresh attempts to maintain your component's state between edits, particularly for `useState` and `useRef`, as long as their arguments or Hook call order remain unchanged. 2624 2625Hooks with dependencies (e.g., `useEffect`, `useMemo`, `useCallback`) will always update during Fast Refresh, ignoring dependency lists. For instance, changing `useMemo(() => x * 2, [x])` to `useMemo(() => x * 10, [x])` triggers a re-run even if the dependency `x` hasn't changed. This ensures your edits are reflected on screen. 2626 2627This behavior can lead to unexpected results, such as an empty-array `useEffect` running once during Fast Refresh. Writing resilient code for occasional `useEffect` re-runs is beneficial and aligns with best practices, facilitating future dependency additions. 2628 2629## Metro 2630 2631React Native utilizes Metro to compile JavaScript code and manage assets. Below are guidelines for configuring Metro within your project. 2632 2633### Configuring Metro 2634 2635To customize Metro's configuration, modify the `metro.config.js` file in your project directory. This file can export: 2636 2637- **An Object**: Recommended approach that merges with Metro's internal default configurations. 2638- **A Function**: Called with Metro's defaults and should return a final configuration object. 2639 2640For comprehensive documentation on all available configuration options, refer to the "Configuring Metro" section on the Metro website. 2641 2642In React Native projects, it is advisable to extend either `@react-native/metro-config` or `@expo/metro-config`. These packages provide essential default settings required for building and running React Native applications. 2643 2644#### Default Configuration Example 2645 2646Here's a typical `metro.config.js` file found in a React Native template project: 2647 2648```typescript 2649const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config") 2650 2651/** 2652 * Metro configuration 2653 * https://metrobundler.dev/docs/configuration 2654 * 2655 * @type {import('metro-config').MetroConfig} 2656 */ 2657const config = {} 2658 2659module.exports = mergeConfig(getDefaultConfig(__dirname), config) 2660``` 2661 2662Customize Metro options by modifying the `config` object. 2663 2664#### Advanced Configuration: Using a Config Function 2665 2666Exporting a configuration function allows you to manage the final configuration manually. **Note**: Metro will not apply any internal defaults in this case. This approach is useful for accessing the base default config from Metro or setting options dynamically. 2667 2668**Important Update**: From version `@react-native/metro-config` 0.72.1, it's no longer necessary to use a config function to access the complete default configuration. Refer to the "Tip" section below for simpler methods. 2669 2670```typescript 2671const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config") 2672 2673module.exports = function (baseConfig) { 2674 const defaultConfig = mergeConfig(baseConfig, getDefaultConfig(__dirname)) 2675 const { 2676 resolver: { assetExts, sourceExts }, 2677 } = defaultConfig 2678 2679 return mergeConfig(defaultConfig, { 2680 resolver: { 2681 assetExts: assetExts.filter((ext) => ext !== "svg"), 2682 sourceExts: [...sourceExts, "svg"], 2683 }, 2684 }) 2685} 2686``` 2687 2688#### Simpler Alternative 2689 2690For simpler customizations like modifying `sourceExts`, you can directly read these defaults from `@react-native/metro-config`. 2691 2692```typescript 2693const defaultConfig = getDefaultConfig(__dirname) 2694 2695const config = { 2696 resolver: { 2697 sourceExts: [...defaultConfig.resolver.sourceExts, "svg"], 2698 }, 2699} 2700 2701module.exports = mergeConfig(defaultConfig, config) 2702``` 2703 2704**Recommendation**: It's best to copy and edit configuration values directly in your `metro.config.js` file. This ensures that the source of truth for these settings resides within your project. 2705 2706✅ **Recommended Approach** 2707 2708```typescript 2709const config = { 2710 resolver: { 2711 sourceExts: ["js", "ts", "tsx", "svg"], 2712 }, 2713} 2714``` 2715 2716### Further Learning 2717 2718- Visit the [Metro website](https://metrobundler.dev/docs/configuration) for more information. 2719- Watch the "Metro & React Native DevX" talk at App.js 2023 for insights into Metro's role in React Native development. 2720 2721## Using Libraries 2722 2723React Native offers built-in Core Components and APIs, but you can also leverage a vast community of developers to find additional libraries that extend your app's functionality. 2724 2725### Selecting a Package Manager 2726 2727Libraries for React Native are typically installed from the npm registry using package managers like npm CLI or Yarn Classic. If Node.js is already installed on your machine, npm CLI comes pre-installed. Some developers prefer Yarn Classic due to its faster install times and advanced features such as Workspaces. Both tools integrate well with React Native. For simplicity, this guide will use npm. 2728 2729> 💡 In the JavaScript community, "library" and "package" are often used interchangeably. 2730 2731### Installing a Library 2732 2733To add a library to your project, navigate to your project directory in the terminal and execute the installation command. Here's how you can install `react-native-webview`: 2734 2735- **Using npm:** 2736 2737 ```shell 2738 npm install react-native-webview 2739 ``` 2740 2741- **Using Yarn:** 2742 2743 ```shell 2744 yarn add react-native-webview 2745 ``` 2746 2747Libraries with native code require linking to your app before use. 2748 2749### Linking Native Code on iOS 2750 2751React Native uses CocoaPods for managing iOS project dependencies. Most libraries follow this convention, but if not, refer to their README for instructions. Typically: 2752 27531. Run `pod install` in the `ios` directory or use a shortcut with `npx pod-install`. 2754 2755 ```bash 2756 npx pod-install 2757 ``` 2758 27591. Rebuild your app binary to start using the new library: 2760 2761 - **Using npm:** 2762 2763 ```shell 2764 npm run ios 2765 ``` 2766 2767 - **Using Yarn:** 2768 2769 ```shell 2770 yarn ios 2771 ``` 2772 2773### Linking Native Code on Android 2774 2775React Native uses Gradle for managing Android project dependencies. After installing a library with native code, rebuild the app binary: 2776 2777- **Using npm:** 2778 2779 ```shell 2780 npm run android 2781 ``` 2782 2783- **Using Yarn:** 2784 2785 ```shell 2786 yarn android 2787 ``` 2788 2789### Finding Libraries 2790 2791The React Native Directory is a searchable database of libraries specifically for React Native. It's an excellent starting point for finding libraries. 2792 2793Many libraries originate from the React Native Community or Expo: 2794 2795- **React Native Community**: Driven by volunteers and companies reliant on React Native, these libraries often support iOS, tvOS, Android, Windows, though this varies. 2796 2797- **Expo Libraries**: Written in TypeScript, they aim to support iOS, Android, and `react-native-web` where possible. 2798 2799If a library isn't listed in the directory, check the npm registry. While it's a comprehensive source for JavaScript libraries, not all are compatible with React Native. 2800 2801### Determining Library Compatibility 2802 2803#### Does it work with React Native? 2804 2805Libraries built for other platforms may not be compatible with React Native. For instance: 2806 2807- `react-select` targets `react-dom` and is web-specific. 2808- `rimraf` interacts with the file system, making it Node.js-specific. 2809 2810Conversely, libraries like `lodash`, which use only JavaScript features, are generally cross-platform. Testing is often necessary to determine compatibility. If a library doesn't work, remove it using `npm uninstall`. 2811 2812#### Does it work for my app's platforms? 2813 2814React Native Directory allows filtering by platform compatibility (iOS, Android, Web, Windows). If your desired library isn't listed, consult its README. 2815 2816#### Does it work with my React Native version? 2817 2818The latest library versions usually support the latest React Native releases. For older React Native versions, check the library's README for compatible versions. Install a specific version using: 2819 2820```shell 2821npm install <library-name>@<version-number> 2822``` 2823 2824For example: 2825 2826```shell 2827npm install @react-native-community/netinfo@^2.0.0 2828``` 2829 2830## Text 2831 2832Here's a structured overview and explanation of the `Text` component in React Native, focusing on its properties and usage: 2833 2834#### Overview 2835 2836The `Text` component is used to display text within a React Native application. It supports various styling options and accessibility features, making it versatile for different use cases. 2837 2838#### Key Properties 2839 28401. **Accessibility Features** 2841 2842 - `accessibilityRole`: Defines the role of the component (e.g., button, link). 2843 - `accessibilityState`: Provides additional state information. 2844 - `accessibilityActions`: Specifies actions available to accessibility services. 2845 - `accessible`: Determines if the component is accessible. 2846 28471. **Styling** 2848 2849 - `style`: Applies text and view styles using a combination of Text Style and View Style Props. 2850 - `numberOfLines` & `ellipsizeMode`: Controls text truncation with ellipses. 2851 - `selectable`: Enables text selection for copy-paste functionality. 2852 28531. **Layout and Measurement** 2854 2855 - `onTextLayout`: Callback invoked on layout changes, providing detailed measurement data. 2856 - `lineBreakStrategyIOS` & `textBreakStrategy`: Configures line break strategies for iOS and Android respectively. 2857 28581. **Touch Handling** 2859 2860 - `onPress`, `onLongPress`, `onPressIn`, `onPressOut`: Handle various touch events. 2861 - `onResponder*` series: Manage responder system interactions, crucial for handling touches across multiple views. 2862 28631. **Identification and Testing** 2864 2865 - `id`, `nativeID`, `testID`: Used for locating the component in native code or tests. 2866 28671. **Dynamic Text Scaling** 2868 2869 - `adjustsFontSizeToFit`, `minimumFontScale`, `maxFontSizeMultiplier`: Control font scaling based on user settings or constraints. 2870 28711. **Highlighting and Selection** 2872 - `suppressHighlighting`: Controls visual feedback on text press. 2873 - `selectionColor` (Android): Sets the highlight color for selected text. 2874 2875#### Type Definitions 2876 2877- **TextLayout**: Contains measurement data for each line of text, including dimensions and positions. 2878 2879- **TextLayoutEvent**: Provides layout change information, including an array of `TextLayout` objects for rendered lines. 2880 2881#### Example Usage 2882 2883```jsx 2884import React from "react" 2885import { Text } from "react-native" 2886 2887const MyComponent = () => ( 2888 <Text 2889 style={{ fontSize: 16, color: "blue" }} 2890 numberOfLines={2} 2891 ellipsizeMode="tail" 2892 onPress={() => console.log("Text pressed")} 2893 > 2894 This is a sample text that will be truncated with an ellipsis if it exceeds 2895 two lines. 2896 </Text> 2897) 2898 2899export default MyComponent 2900``` 2901 2902#### Conclusion 2903 2904The `Text` component in React Native is highly customizable, supporting various styling and accessibility options. Understanding its properties allows developers to create rich, interactive text elements tailored to specific application needs. 2905 2906## TextInput 2907 2908Here is a structured overview of the properties, methods, and known issues related to the `TextInput` component in React Native: 2909 2910#### Properties 2911 2912##### General Properties 2913 2914- **editable**: If `false`, prevents user input. Default: `true`. 2915- **maxLength**: Limits text length. Default: No limit. 2916- **multiline**: Enables multiple lines. Default: `false`. 2917- **numberOfLines**: Sets line count for multiline inputs. Default: 1. 2918- **onChangeText**: Callback on text change. 2919- **onSubmitEditing**: Callback when submit button is pressed. 2920- **placeholder**: Placeholder text when empty. 2921- **value**: Controlled component value. 2922 2923##### Platform-Specific Properties 2924 2925###### Android 2926 2927- **disableFullscreenUI**: Hides fullscreen keyboard UI. Default: `false`. 2928- **enablesReturnKeyAutomatically**: Enables return key based on content. Default: `true`. 2929- **keyboardAppearance**: Sets keyboard appearance (`light` or `dark`). Default: `default`. 2930- **maxLength**: Limits text length. 2931- **numberOfLines**: Sets line count for multiline inputs. 2932- **returnKeyType**: Defines return key label. Options include `done`, `go`, `next`, etc. 2933- **scrollEnabled**: Enables scrolling in multiline mode. Default: `true`. 2934- **selectTextOnFocus**: Selects all text on focus. Default: `false`. 2935- **showSoftInputOnFocus**: Shows keyboard on focus. Default: `true`. 2936 2937###### iOS 2938 2939- **autoCapitalize**: Capitalization style (`none`, `sentences`, etc.). Default: `sentences`. 2940- **autoCorrect**: Enables autocorrection. Default: `true`. 2941- **keyboardType**: Sets keyboard type (`default`, `email-address`, etc.). 2942- **returnKeyType**: Defines return key label. 2943- **spellCheck**: Enables spell check. Default: Inherits from `autoCorrect`. 2944 2945##### Common Properties 2946 2947- **allowFontScaling**: Scales font size with user settings. Default: `true`. 2948- **blurOnSubmit**: Blurs on submit. Default: `false`. 2949- **caretHidden**: Hides caret in multiline mode. Default: `false`. 2950- **caretColor**: Sets caret color. 2951- **clearButtonMode**: Controls clear button visibility (`never`, `while-editing`, etc.). Default: `never`. 2952- **contextMenuHidden**: Hides context menu. Default: `false`. 2953- **disableFullscreenUI**: Hides fullscreen keyboard UI. Default: `false`. 2954- **enablesReturnKeyAutomatically**: Enables return key based on content. Default: `true`. 2955- **focusable**: Controls focusability. Default: `true`. 2956- **maxLength**: Limits text length. 2957- **multiline**: Enables multiple lines. Default: `false`. 2958- **numberOfLines**: Sets line count for multiline inputs. Default: 1. 2959- **onContentSizeChange**: Callback on content size change. 2960- **onChangeText**: Callback on text change. 2961- **onSubmitEditing**: Callback when submit button is pressed. 2962- **placeholder**: Placeholder text when empty. 2963- **returnKeyType**: Defines return key label. 2964- **secureTextEntry**: Obscures text for sensitive input. Default: `false`. 2965- **selection**: Sets text selection range. 2966- **selectionColor**: Sets highlight, handle, and cursor color. 2967- **style**: Applies styles to the text input. 2968 2969#### Methods 2970 2971- **focus()**: Requests focus on the native input. 2972- **blur()**: Removes focus from the native input. 2973- **clear()**: Clears all text from the `TextInput`. 2974- **isFocused()**: Returns `true` if the input is focused; otherwise, `false`. 2975 2976#### Known Issues 2977 2978- **react-native#19096**: Doesn't support Android's `onKeyPreIme`. 2979- **react-native#19366**: `.focus()` doesn't bring up the keyboard after closing it via back button on Android. 2980- **react-native#26799**: `secureTextEntry` doesn't work with `keyboardType="email-address"` or `keyboardType="phone-pad"` on Android. 2981 2982This overview provides a comprehensive guide to using and understanding the `TextInput` component in React Native, including its properties, methods, and known issues. 2983 2984## TouchableHighlight 2985 2986> For a more robust and future-proof approach to handling touch-based input, consider using the Pressable API. 2987 2988TouchableHighlight is designed to make views respond appropriately to touch interactions. When pressed, it reduces the opacity of the wrapped view, allowing an underlay color to become visible, which can darken or tint the view. 2989 2990The underlay effect is achieved by wrapping the child component in a new View. This can impact layout and may introduce visual artifacts if not used correctly, such as when the `backgroundColor` of the wrapped view isn't set to an opaque color explicitly. 2991 2992TouchableHighlight requires exactly one child element. If multiple child components are needed, they should be enclosed within a single View. 2993 2994#### Example Usage 2995 2996```typescript 2997function MyComponent(props: MyComponentProps) { 2998 return ( 2999 <View {...props} style={{flex: 1, backgroundColor: '#fff'}}> 3000 <Text>My Component</Text> 3001 </View> 3002 ); 3003} 3004 3005<TouchableHighlight 3006 activeOpacity={0.6} 3007 underlayColor="#DDDDDD" 3008 onPress={() => alert('Pressed!')}> 3009 <MyComponent /> 3010</TouchableHighlight>; 3011``` 3012 3013### Reference 3014 3015#### Props 3016 3017##### Inherited from TouchableWithoutFeedback 3018 3019- Inherits all props from `TouchableWithoutFeedback`. 3020 3021##### Specific to TouchableHighlight 3022 3023|Prop Name|Description|Type| 3024|-|-|-| 3025|`activeOpacity`|Sets the opacity of the wrapped view during touch interaction. Must be between 0 and 1. Defaults to 0.85. Requires `underlayColor`.|number| 3026|`onHideUnderlay`|Called immediately after the underlay is hidden.|function| 3027|`onShowUnderlay`|Called immediately after the underlay is shown.|function| 3028|`style`|Style properties for the view.|View\.style| 3029|`underlayColor`|The color of the underlay that appears when touch is active.|color| 3030 3031##### iOS Specific Props 3032 3033- **hasTVPreferredFocus**: *(Apple TV only)* Indicates TV preferred focus (refer to the View component documentation). 3034 - Type: bool 3035 3036##### Android Specific Props 3037 3038- **nextFocusDown**: TV next focus down (see View component documentation). 3039 - Type: number 3040- **nextFocusForward**: TV next focus forward (see View component documentation). 3041 - Type: number 3042- **nextFocusLeft**: TV next focus left (see View component documentation). 3043 - Type: number 3044- **nextFocusRight**: TV next focus right (see View component documentation). 3045 - Type: number 3046- **nextFocusUp**: TV next focus up (see View component documentation). 3047 - Type: number 3048 3049##### Testing Prop 3050 3051- **testOnly\_pressed**: Useful for snapshot tests. 3052 - Type: bool 3053 3054## TouchableOpacity 3055 3056> For a more comprehensive and future-proof approach to handling touch-based input, consider using the Pressable API. 3057 3058The `TouchableOpacity` is a wrapper that ensures views respond appropriately to touch interactions. When pressed, it reduces the opacity of the wrapped view, creating a dimming effect. 3059 3060This behavior is achieved by enclosing the children in an `Animated.View`, which is then added to the view hierarchy. Note that this can influence layout. 3061 3062### Example 3063 3064### Reference 3065 3066### Properties 3067 3068#### Inherited from TouchableWithoutFeedback Props 3069 3070`TouchableOpacity` inherits properties from `TouchableWithoutFeedback`. 3071 3072#### `style` 3073 3074- **Type**: View\.style 3075- Description: Defines the style of the component. 3076 3077#### `activeOpacity` 3078 3079- **Type**: number 3080- **Default**: 0.2 3081- Description: Specifies the opacity level of the wrapped view during an active touch event. 3082 3083#### `hasTVPreferredFocus` (iOS) 3084 3085- **Type**: bool 3086- **Platform**: Apple TV only 3087- Description: Determines if the component should have preferred focus on Apple TV, as detailed in the View component documentation. 3088 3089#### `nextFocusDown` (Android) 3090 3091- **Type**: number 3092- **Platform**: Android 3093- Description: Specifies the next focusable view when navigating down using a TV remote, as described in the View component documentation. 3094 3095#### `nextFocusForward` (Android) 3096 3097- **Type**: number 3098- **Platform**: Android 3099- Description: Identifies the next focusable view when navigating forward with a TV remote, according to the View component documentation. 3100 3101#### `nextFocusLeft` (Android) 3102 3103- **Type**: number 3104- **Platform**: Android 3105- Description: Determines the next focusable view when navigating left using a TV remote, as per the View component documentation. 3106 3107#### `nextFocusRight` (Android) 3108 3109- **Type**: number 3110- **Platform**: Android 3111- Description: Specifies the next focusable view when navigating right with a TV remote, based on the View component documentation. 3112 3113#### `nextFocusUp` (Android) 3114 3115- **Type**: number 3116- **Platform**: Android 3117- Description: Identifies the next focusable view when navigating up using a TV remote, as detailed in the View component documentation. 3118 3119## Upgrading to new versions 3120 3121Upgrading to newer versions of React Native provides access to additional APIs, views, developer tools, and other enhancements. Although the process requires some effort, we aim to make it as straightforward as possible. 3122 3123### Expo Projects 3124 3125To upgrade an Expo project to a new version of React Native, update the `react-native`, `react`, and `expo` package versions in your `package.json`. It is recommended by Expo to incrementally upgrade SDK versions one at a time. This approach helps identify any issues or breakages during the upgrade process. For detailed guidance, refer to the Upgrading Expo SDK Walkthrough. 3126 3127### React Native Projects 3128 3129React Native projects typically consist of an Android project, an iOS project, and a JavaScript project, making upgrades complex. The Upgrade Helper is a web tool designed to assist in upgrading apps by displaying all changes between two versions and providing comments on specific files for better understanding. 3130 3131#### Steps to Upgrade 3132 3133##### 1. Select Versions 3134 3135Begin by selecting the current version and the target version you wish to upgrade to. By default, the latest major versions are selected. After making your selection, click "Show me how to upgrade." Major updates may include a "useful content" section with helpful links. 3136 3137##### 2. Upgrade Dependencies 3138 3139The first file displayed is `package.json`. Update any dependencies listed there. For instance, if changes for `react-native` and `react` are shown, install them using the following commands: 3140 3141- **Using npm:** 3142 3143 ```shell 3144 # Replace {{VERSION}} and {{REACT_VERSION}} with the versions from the diff 3145 npm install react-native@{{VERSION}} 3146 npm install react@{{REACT_VERSION}} 3147 ``` 3148 3149- **Using Yarn:** 3150 3151 ```shell 3152 # Replace {{VERSION}} and {{REACT_VERSION}} with the versions from the diff 3153 yarn add react-native@{{VERSION}} 3154 yarn add react@{{REACT_VERSION}} 3155 ``` 3156 3157##### 3. Upgrade Project Files 3158 3159New releases may include updates to files generated by `npx react-native init`. These files are listed after `package.json` on the Upgrade Helper page. If no additional changes are needed, simply rebuild your project. Otherwise, manually apply any necessary changes. 3160 3161#### Troubleshooting 3162 3163If you have made all required changes but your app still uses an old version, this issue is often related to caching. It's recommended to use react-native-clean-project to clear the cache and then rerun the process. 3164 3165## TouchableWithoutFeedback 3166 3167> For more comprehensive and future-proof handling of touch-based input, consider using the Pressable API. Use `TouchableWithoutFeedback` only if there is a compelling reason to do so. All elements that respond to press should provide visual feedback when touched. 3168 3169`TouchableWithoutFeedback` supports only one child element. If multiple children are needed, wrap them in a `View`. It's important to note that `TouchableWithoutFeedback` works by cloning its child and applying responder props to it. Therefore, any intermediary components must pass these props through to the underlying React Native component. 3170 3171### Usage Pattern 3172 3173```typescript 3174function MyComponent(props: MyComponentProps) { 3175 return ( 3176 <View {...props} style={{flex: 1, backgroundColor: '#fff'}}> 3177 <Text>My Component</Text> 3178 </View> 3179 ); 3180} 3181 3182<TouchableWithoutFeedback onPress={() => alert('Pressed!')}> 3183 <MyComponent /> 3184</TouchableWithoutFeedback>; 3185``` 3186 3187### Example 3188 3189### Reference 3190 3191### Props 3192 3193|Prop Name|Description|Type| 3194|-|-|-| 3195|`accessibilityIgnoresInvertColors` (iOS)|Indicates whether the view should be inverted when color inversion is enabled. A value of `true` prevents inversion even if color inversion is turned on. See the Accessibility guide for more information.|Boolean| 3196|`accessible`|When set to `true`, marks the view as an accessibility element. By default, all touchable elements are accessible.|bool| 3197|`accessibilityLabel`|Overrides the text read by screen readers when interacting with the element. By default, it is constructed from all child `Text` nodes separated by spaces.|string| 3198|`accessibilityLanguage` (iOS)|Specifies the language used by the screen reader for this element, following the BCP 47 specification. See the iOS `accessibilityLanguage` documentation for more information.|string| 3199|`accessibilityHint`|Provides a hint to help users understand what will happen when they perform an action on the accessibility element if it's not clear from the label.|string| 3200|`accessibilityRole`|Communicates the purpose of a component to assistive technology users. Possible values include `'none'`, `'button'`, `'link'`, `'search'`, `'image'`, `'keyboardkey'`, `'text'`, `'adjustable'`, and more.|string| 3201|`accessibilityState`|Describes the current state of a component to assistive technology users. See the Accessibility guide for more information.|object: `{disabled, selected, checked, busy, expanded}`| 3202|`accessibilityActions`|Allows assistive technologies to programmatically invoke actions on a component. Each action should include a name and label. See the Accessibility guide for more details.|array| 3203|`aria-busy`|Indicates that an element is being modified and assistive technologies may want to wait until changes are complete before notifying the user.|boolean| 3204|`aria-checked`|Represents the state of a checkable element, which can be either a boolean or `'mixed'`.|boolean, 'mixed'| 3205|`aria-disabled`|Indicates that an element is perceivable but disabled and not editable or operable.|boolean| 3206|`aria-expanded`|Shows whether an expandable element is currently expanded or collapsed.|boolean| 3207|`aria-hidden`|Specifies if the accessibility elements within this element are hidden, affecting how assistive technologies like VoiceOver interact with sibling views.|boolean| 3208|`aria-label`|Provides a string value that labels an interactive element.|string| 3209|`aria-live` (Android)|Indicates updates to an element and describes the types of updates expected by user agents, assistive technologies, and users. Options include `'assertive'`, `'off'`, and `'polite'`.|enum: `'assertive'`, `'off'`, `'polite'`| 3210|`aria-modal` (iOS)|Boolean indicating whether VoiceOver should ignore sibling elements within views. Takes precedence over the `accessibilityViewIsModal` prop.|boolean| 3211|`aria-selected`|Indicates if a selectable element is currently selected.|boolean| 3212|`onAccessibilityAction`|Invoked when an accessibility action is performed by the user. The function receives an event containing the name of the action to perform. See the Accessibility guide for more information.|function| 3213|`accessibilityValue`|Represents a component's current value, either as a textual description or range information (min, max, now) for components like sliders and progress bars.|object: `{min, max, now, text}`| 3214|`aria-valuemax`|Specifies the maximum value for range-based components, taking precedence over the `max` value in the `accessibilityValue` prop.|number| 3215|`aria-valuemin`|Specifies the minimum value for range-based components, taking precedence over the `min` value in the `accessibilityValue` prop.|number| 3216|`aria-valuenow`|Represents the current value for range-based components, taking precedence over the `now` value in the `accessibilityValue` prop.|number| 3217|`aria-valuetext`|Provides a textual description of the component's value, taking precedence over the `text` value in the `accessibilityValue` prop.|string| 3218|`delayLongPress`|Duration (in milliseconds) from `onPressIn` before `onLongPress` is called.|number| 3219|`delayPressIn`|Duration (in milliseconds) from the start of a touch until `onPressIn` is invoked.|number| 3220|`delayPressOut`|Duration (in milliseconds) after releasing a touch before `onPressOut` is called.|number| 3221|`disabled`|If set to true, disables all interactions for this component.|bool| 3222|`hitSlop`|Defines how far from the button a touch can start. This value is added to `pressRetentionOffset` when moving off of the button. The touch area does not extend past parent view bounds and sibling views with higher Z-index take precedence if overlapping.|Rect or number| 3223|`id`|Used to locate this view from native code, taking precedence over the `nativeID` prop.|string| 3224|`onBlur`|Invoked when the item loses focus.|function| 3225|`onFocus`|Invoked when the item receives focus.|function| 3226|`onLayout`|Called on mount and during layout changes.|`({nativeEvent: LayoutEvent}) => void`| 3227|`onLongPress`|Triggered if the time after `onPressIn` exceeds 370 milliseconds, customizable with `delayLongPress`.|function| 3228|`onPress`|Called when a touch is released unless cancelled (e.g., by a scroll that steals the responder lock). The first argument is an event in form of PressEvent.|function| 3229|`onPressIn`|Invoked as soon as the touchable element is pressed, even before `onPress`. Useful for tasks like network requests. The first argument is an event in form of PressEvent.|function| 3230|`onPressOut`|Called immediately after a touch is released, prior to `onPress`. The first argument is an event in form of PressEvent.|function| 3231|`pressRetentionOffset`|Defines how far a touch may move off the button before deactivating it when the scroll view is disabled. Re-activation occurs upon moving back over the button. Pass a constant to reduce memory allocations.|Rect or number| 3232|`nativeID`||string| 3233|`testID`|Used to locate this view in end-to-end tests.|string| 3234|`touchSoundDisabled` (Android)|If set to true, prevents the system sound from playing on touch.|Boolean| 3235 3236## View 3237 3238#### Accessibility Properties 3239 3240- **`accessibilityActions`**: Defines actions that can be performed on the view for accessibility purposes. 3241 3242- **`accessibilityComponentType`**: Specifies the type of component for accessibility. 3243 3244- **`accessibilityElementsHidden`**: Determines if accessibility elements are hidden. 3245 3246- **`accessibilityHint`**: Provides a hint about what performing an action will do. 3247 3248- **`accessibilityIgnoresInvertColors`**: Indicates whether to ignore invert colors settings. 3249 3250- **`accessibilityLabel`**: A label for the view that is read by screen readers. 3251 3252- **`accessibilityLiveRegion`**: Defines how updates are announced by screen readers. 3253 3254- **`accessibilityRole`**: Communicates the role of the component to assistive technologies. 3255 3256- **`accessibilityState`**: Represents the state of accessibility elements. 3257 3258- **`accessibilityStates`**: An array of states for accessibility elements. 3259 3260- **`accessibilityTraits`**: Describes traits of the view for accessibility purposes. 3261 3262- **`accessible`**: Indicates if the view is accessible. 3263 3264- **`onAccessibilityAction`**: Callback invoked when an accessibility action is performed. 3265 3266- **`onAccessibilityEscape`** (iOS): Invoked on escape gesture. 3267 3268- **`onAccessibilityTap`** (iOS): Invoked on accessibility tap gesture. 3269 3270- **`onMagicTap`** (iOS): Invoked on magic tap gesture. 3271 3272#### Layout and Rendering Properties 3273 3274- **`needsOffscreenAlphaCompositing`**: Determines if offscreen alpha compositing is needed for correct rendering. 3275 3276- **`nextFocusDown/Forward/Left/Right/Up`** (Android): Designates the next view to receive focus in various directions. 3277 3278- **`onLayout`**: Invoked when layout changes occur. 3279 3280- **`removeClippedSubviews`**: Improves performance by removing offscreen subviews. 3281 3282- **`renderToHardwareTextureAndroid`** (Android): Renders the view into a hardware texture for better performance during animations. 3283 3284- **`shouldRasterizeIOS`** (iOS): Rasterizes the view to improve animation performance. 3285 3286#### Interaction and Focus Properties 3287 3288- **`onMoveShouldSetResponder`**: Determines if the view should become the responder on touch move. 3289 3290- **`onMoveShouldSetResponderCapture`**: Allows a parent view to prevent a child from becoming the responder. 3291 3292- **`onResponderGrant`**: Invoked when the view becomes the responder for touch events. 3293 3294- **`onResponderMove`**: Triggered during finger movement. 3295 3296- **`onResponderRelease`**: Fired at the end of a touch event. 3297 3298- **`onResponderReject`**: Called if another responder takes over. 3299 3300- **`onResponderTerminate`**: Invoked when the view loses its responder status. 3301 3302- **`onResponderTerminationRequest`**: Requests to release the responder role. 3303 3304- **`onStartShouldSetResponder`**: Determines if the view should become the responder on touch start. 3305 3306- **`onStartShouldSetResponderCapture`**: Allows a parent view to prevent a child from becoming the responder on touch start. 3307 3308#### Pointer Events 3309 3310- **`pointerEvents`**: Controls whether the view can be the target of touch events. Options include `auto`, `none`, `box-none`, and `box-only`. 3311 3312#### Identification Properties 3313 3314- **`id`**: Unique identifier for the view. 3315 3316- **`importantForAccessibility`** (Android): Determines if the view is important for accessibility. 3317 3318- **`nativeID`**: Used to locate the view from native classes. 3319 3320- **`testID`**: Identifier used in end-to-end tests. 3321 3322#### Style and Role 3323 3324- **`style`**: Defines the style of the view. 3325 3326- **`role`**: Communicates the purpose of a component, with precedence over `accessibilityRole`. 3327 3328This documentation provides comprehensive details on how to configure various aspects of a `View`, focusing on accessibility, layout, interaction, and identification. 3329 3330## Style 3331 3332In React Native, styling your application is done using JavaScript. Core components accept a `style` prop, which typically mirrors CSS conventions but uses camel casing for property names (e.g., `backgroundColor` instead of `background-color`). 3333 3334### Using the `style` Prop 3335 3336The `style` prop can be defined as a plain JavaScript object, which is common in example code. Alternatively, you can pass an array of styles; the last style in the array takes precedence, allowing for inheritance. 3337 3338As components become more complex, it's often cleaner to use `StyleSheet.create` to define multiple styles in one place. Here’s how you might do this: 3339 3340```typescript 3341import { StyleSheet } from "react-native" 3342 3343const styles = StyleSheet.create({ 3344 container: { 3345 flex: 1, 3346 justifyContent: "center", 3347 alignItems: "center", 3348 }, 3349 text: { 3350 fontSize: 20, 3351 color: "blue", 3352 }, 3353}) 3354``` 3355 3356A common pattern is to allow a component to accept a `style` prop, which can then be used to style subcomponents. This approach enables styles to "cascade" similarly to CSS. 3357 3358For more detailed customization of text styles, refer to the Text component reference for a comprehensive list. 3359 3360### Enhancing Text Appearance 3361 3362With these styling techniques, you can enhance your text's appearance significantly. The next step in mastering styling is learning how to control component size effectively. 3363 3364### Known Issues 3365 3366- **react-native#29308**: React Native sometimes deviates from web CSS behavior. For instance, the touch area does not extend beyond parent view bounds, and negative margins are unsupported on Android. 3367 3368## Height and Width 3369 3370A component's height and width determine its size on the screen. 3371 3372### Fixed Dimensions 3373 3374To set the dimensions of a component, you can add fixed `width` and `height` properties in the style. In React Native, all dimensions are unitless and represent density-independent pixels (dp). 3375 3376Using fixed dimensions is typical for components that should maintain a constant size regardless of screen size. 3377 3378> **Caution:** There isn't a universal conversion from points to physical units of measurement. Consequently, a component with fixed dimensions may not appear the same size across different devices and screens. However, this discrepancy is usually negligible in most scenarios. 3379 3380### Flex Dimensions 3381 3382To allow a component's size to adjust dynamically based on available space, use `flex` in its style. Typically, you'll set `flex: 1`, which instructs the component to occupy all available space, distributed evenly among siblings with the same parent. The larger the `flex` value assigned, the more space the component will take relative to its siblings. 3383 3384> **Info:** A component can only expand to fill available space if its parent has dimensions greater than `0`. If a parent lacks either fixed `width` and `height` or `flex`, it defaults to dimensions of `0`, rendering flex children invisible. 3385 3386Once you've mastered controlling a component's size, the next step is learning how to position it on the screen. 3387 3388### Percentage Dimensions 3389 3390To occupy a specific portion of the screen without using the `flex` layout, you can use **percentage values** in the component's style. Like flex dimensions, percentage dimensions require that the parent has defined dimensions. 3391 3392## DrawerLayoutAndroid 3393 3394The `DrawerLayoutAndroid` is a React component specifically designed for Android platforms. It encapsulates the platform's native `DrawerLayout`. This layout typically serves as a navigation drawer, which can be rendered using the `renderNavigationView` prop. The main content of your application resides within its direct children. 3395 3396By default, the navigation view remains hidden and can be revealed by pulling it from the side of the screen specified by the `drawerPosition` prop. You can also adjust the width of the drawer using the `drawerWidth` prop. 3397 3398### Example 3399 3400- TypeScript 3401- JavaScript 3402 3403### Reference 3404 3405### Props 3406 3407#### View Props 3408 3409The component inherits all properties available to a standard React `View`. 3410 3411#### `drawerBackgroundColor` 3412 3413This property sets the background color for the drawer, with the default being white. To adjust opacity, use an RGBA value. For example: 3414 3415```typescript 3416<DrawerLayoutAndroid drawerBackgroundColor="rgba(0,0,0,0.5)" /> 3417``` 3418 3419- **Type**: `color` 3420- **Required**: No 3421 3422#### `drawerLockMode` 3423 3424This property determines how the drawer responds to user interactions. It can be set to one of three modes: 3425 3426- `unlocked` (default): The drawer will open or close in response to touch gestures. 3427 3428- `locked-closed`: The drawer remains closed and does not respond to gestures. 3429 3430- `locked-open`: The drawer stays open but can still be programmatically opened or closed using `openDrawer`/`closeDrawer`. 3431 3432- **Type**: `enum('unlocked', 'locked-closed', 'locked-open')` 3433 3434- **Required**: No 3435 3436#### `drawerPosition` 3437 3438This property specifies from which side of the screen the drawer will slide in. The default is set to `left`. 3439 3440- **Type**: `enum('left', 'right')` 3441- **Required**: No 3442 3443#### `drawerWidth` 3444 3445Defines the width of the drawer, specifically the portion that slides in from the edge of the window. 3446 3447- **Type**: `number` 3448- **Required**: No 3449 3450#### `keyboardDismissMode` 3451 3452Determines if the keyboard should be dismissed when a drag gesture is detected. Options include: 3453 3454- `'none'` (default): Drags do not dismiss the keyboard. 3455 3456- `'on-drag'`: The keyboard is dismissed as soon as a drag begins. 3457 3458- **Type**: `enum('none', 'on-drag')` 3459 3460- **Required**: No 3461 3462#### `onDrawerClose` 3463 3464A callback function that triggers when the navigation view is closed. 3465 3466- **Type**: `function` 3467- **Required**: No 3468 3469#### `onDrawerOpen` 3470 3471A callback function that triggers when the navigation view is opened. 3472 3473- **Type**: `function` 3474- **Required**: No 3475 3476#### `onDrawerSlide` 3477 3478This function is called during any interaction with the navigation view, such as sliding it open or closed. 3479 3480- **Type**: `function` 3481- **Required**: No 3482 3483#### `onDrawerStateChanged` 3484 3485A callback that fires when the drawer's state changes. The possible states are: 3486 3487- `idle`: No interaction with the navigation view. 3488 3489- `dragging`: An ongoing interaction with the navigation view. 3490 3491- `settling`: Interaction has ended, and the navigation view is completing its animation. 3492 3493- **Type**: `function` 3494 3495- **Required**: No 3496 3497#### `renderNavigationView` 3498 3499This required prop defines the content of the navigation view that appears from the side of the screen. 3500 3501- **Type**: `function` 3502- **Required**: Yes 3503 3504#### `statusBarBackgroundColor` 3505 3506Allows the drawer to extend over the status bar by setting its background color. This is effective only on API 21 and above. 3507 3508- **Type**: `color` 3509- **Required**: No 3510 3511### Methods 3512 3513#### `closeDrawer()` 3514 3515```typescript 3516closeDrawer() 3517``` 3518 3519Closes the navigation drawer. 3520 3521#### `openDrawer()` 3522 3523```typescript 3524openDrawer() 3525``` 3526 3527Opens the navigation drawer. 3528 3529## Layout with Flexbox 3530 3531Flexbox provides a consistent way to design layouts across different screen sizes. In React Native, it shares similarities with CSS on the web but has specific differences such as default values for properties like `flexDirection`, `alignContent`, and `flexShrink`. 3532 3533### Key Properties of Flexbox 3534 3535#### Flex 3536 3537The `flex` property determines how items distribute space along the main axis within a container. For instance: 3538 3539- A container view with `flex: 1`. 3540- Child views with `flex: 1`, `flex: 2`, and `flex: 3`. 3541 3542This means the red, orange, and green views will occupy `1/6`, `2/6`, and `3/6` of the available space respectively. 3543 3544#### Flex Direction 3545 3546The `flexDirection` property controls the layout direction of children within a node: 3547 3548- **column** (default): Top to bottom. 3549- **row**: Left to right. 3550- **column-reverse**: Bottom to top. 3551- **row-reverse**: Right to left. 3552 3553#### Layout Direction 3554 3555The `direction` property specifies text and child element orientation: 3556 3557- **LTR** (default): Left-to-right layout. 3558- **RTL**: Right-to-left layout. 3559 3560#### Justify Content 3561 3562This property aligns children along the main axis of their container: 3563 3564- **flex-start** (default) 3565- **flex-end** 3566- **center** 3567- **space-between** 3568- **space-around** 3569- **space-evenly** 3570 3571#### Align Items 3572 3573`alignItems` aligns children along the cross axis: 3574 3575- **stretch** (default): Stretch to match the height of the container's cross axis. 3576- **flex-start** 3577- **flex-end** 3578- **center** 3579- **baseline** 3580 3581#### Align Self 3582 3583Similar to `alignItems`, but applies to individual children, allowing them to override their parent's alignment. 3584 3585#### Align Content 3586 3587`alignContent` manages the distribution of lines along the cross-axis when wrapping is enabled: 3588 3589- **flex-start** (default) 3590- **flex-end** 3591- **stretch** (default on web with Yoga) 3592- **center** 3593- **space-between** 3594- **space-around** 3595- **space-evenly** 3596 3597#### Flex Wrap 3598 3599The `flexWrap` property controls how children are wrapped within a container: 3600 3601- Default: Single line. 3602- Allows wrapping into multiple lines if necessary. 3603 3604#### Flex Basis, Grow, and Shrink 3605 3606These properties manage the default size, growth, and shrinkage of items: 3607 3608- **flexBasis**: Default size along the main axis. 3609- **flexGrow**: Distribution of remaining space among children. 3610- **flexShrink**: Shrinking of children when overflow occurs. 3611 3612#### Row Gap, Column Gap, and Gap 3613 3614These properties define spacing between rows and columns: 3615 3616- **rowGap** 3617- **columnGap** 3618- **gap** (shorthand for both) 3619 3620#### Width and Height 3621 3622Specifies the dimensions of an element's content area: 3623 3624- **auto**: Default; calculated based on content. 3625- **pixels**: Absolute size in pixels. 3626- **percentage**: Relative to parent's dimension. 3627 3628#### Position 3629 3630Defines how elements are positioned relative to their containing block: 3631 3632- **relative** (default): Positioned according to normal flow with offsets. 3633- **absolute**: Positioned independently of the layout flow. 3634- **static**: Normal flow positioning, ignoring offset values. Available only on the New Architecture. 3635 3636### Containing Block 3637 3638The containing block is an ancestor element that influences an absolutely positioned element's position and size. The `top`, `right`, `bottom`, and `left` properties are relative to this block. Percentage lengths for dimensions are calculated based on the containing block's size. 3639 3640#### Determining the Containing Block 3641 3642- **Relative or Static Position**: Parent is the containing block. 3643- **Absolute Position**: Nearest ancestor with a non-static position or transform property. 3644 3645### Further Exploration 3646 3647For deeper understanding, explore interactive tools like the yoga playground. The full list of layout-controlling props and examples from Wix Engineers are available for further study. 3648 3649## Images 3650 3651### Static Image Resources 3652 3653React Native offers a unified approach for managing images and other media assets in Android and iOS applications. To add a static image, place it within your source code directory and reference it as follows: 3654 3655```typescript 3656<Image source={require('./my-icon.png')} /> 3657``` 3658 3659The image name is resolved similarly to how JavaScript modules are resolved. In the example above, the bundler searches for `my-icon.png` in the same folder as the component that requires it. 3660 3661You can use the `@2x` and `@3x` suffixes to provide images for different screen densities. For instance, with this file structure: 3662 3663``` 3664. 3665├── button.js 3666└── img 3667 ├── check.png 3668 ├── check@2x.png 3669 └── check@3x.png 3670``` 3671 3672...and the `button.js` code containing: 3673 3674```typescript 3675<Image source={require('./img/check.png')} /> 3676``` 3677 3678...the bundler will bundle and serve the image corresponding to the device's screen density. For example, `check@2x.png` is used on an iPhone 7, while `check@3x.png` is used on an iPhone 7 Plus or a Nexus 5. If no matching image for the screen density exists, the closest available option will be selected. 3679 3680On Windows, you might need to restart the bundler if new images are added to your project. 3681 3682Benefits include: 3683 36841. A unified system across Android and iOS. 36851. Images reside in the same folder as JavaScript code, making components self-contained. 36861. No global namespace, avoiding name collisions. 36871. Only used images are packaged into your app. 36881. Adding or changing images doesn't require recompilation; you can refresh the simulator as usual. 36891. The bundler knows image dimensions, eliminating the need to duplicate this information in code. 36901. Images can be distributed via npm packages. 3691 3692For this to work, the image name in `require` must be known statically: 3693 3694```typescript 3695// GOOD 3696<Image source={require('./my-icon.png')} />; 3697 3698// BAD 3699const icon = this.props.active 3700 ? 'my-icon-active' 3701 : 'my-icon-inactive'; 3702<Image source={require('./' + icon + '.png')} />; 3703 3704// GOOD 3705const icon = this.props.active 3706 ? require('./my-icon-active.png') 3707 : require('./my-icon-inactive.png'); 3708<Image source={icon} />; 3709``` 3710 3711Note that image sources required in this manner include size (width, height) information. If you need to scale the image dynamically (e.g., via flex), you may need to manually set `{width: undefined, height: undefined}` on the style attribute. 3712 3713### Static Non-Image Resources 3714 3715The `require` syntax described above can also be used to statically include audio, video, or document files in your project. Common file types supported include `.mp3`, `.wav`, `.mp4`, `.mov`, `.html`, and `.pdf`. See bundler defaults for the full list. 3716 3717You can add support for other types by adding an `assetExts` resolver option in your Metro configuration. 3718 3719A caveat is that videos must use absolute positioning instead of `flexGrow`, as size information is not currently passed for non-image assets. This limitation does not occur for videos linked directly into Xcode or the Assets folder for Android. 3720 3721### Images From Hybrid App's Resources 3722 3723If you are building a hybrid app (some UIs in React Native, some in platform code), you can still use images already bundled into the app. 3724 3725For images included via Xcode asset catalogs or the Android Assets folder, reference them by name: 3726 3727```typescript 3728<Image source={{ uri: 'image-name' }} /> 3729``` 3730 3731Note that you must specify some width and height style attributes. 3732 3733### iOS Border Radius Styles 3734 3735Please note that the following corner-specific border radius style properties might be ignored by iOS's image component: 3736 3737- `borderTopLeftRadius` 3738- `borderTopRightRadius` 3739- `borderBottomLeftRadius` 3740- `borderBottomRightRadius` 3741 3742### Off-thread Decoding 3743 3744Image decoding can take more than a frame-worth of time, which is a major source of frame drops on the web because decoding is done in the main thread. In React Native, image decoding occurs in a different thread. Practically, you already handle cases where the image isn't downloaded yet, so displaying a placeholder for a few extra frames while it decodes doesn't require any code changes. 3745 3746### Configuring iOS Image Cache Limits 3747 3748On iOS, an API is available to override React Native's default image cache limits. This should be called from within your native AppDelegate code (e.g., within `didFinishLaunchingWithOptions`): 3749 3750```objective-c 3751RCTSetImageCacheLimits(4*1024*1024, 200*1024*1024); 3752``` 3753 3754**Parameters:** 3755 3756|Name|Type|Required|Description| 3757|-|-|-|-| 3758|imageSizeLimit|number|Yes|Image cache size limit.| 3759|totalCostLimit|number|Yes|Total cache cost limit.| 3760 3761In the example above, the image size limit is set to 4 MB and the total cost limit to 200 MB. 3762 3763### Source as an Object 3764 3765In React Native, the `src` attribute is named `source` and doesn't take a string but an object with a `uri` attribute: 3766 3767```typescript 3768<Image source={{ uri: 'something.jpg' }} /> 3769``` 3770 3771On the infrastructure side, this allows attaching metadata to the object. For example, if you use `require('./my-icon.png')`, information about its actual location and size is added (though relying on this fact might change in the future!). This approach also future-proofs for features like sprites, where instead of outputting `{uri: ...}`, we can output `{uri: ..., crop: {left: 10, top: 50, width: 20, height: 40}}` and transparently support spriting on all existing call sites. 3772 3773On the user side, this lets you annotate the object with useful attributes such as image dimensions to compute its display size. Feel free to use it as your data structure for storing more information about your image. 3774 3775### Background Image via Nesting 3776 3777A common feature request from developers familiar with web development is `background-image`. To handle this use case, use the `<ImageBackground>` component, which has the same props as `<Image>`, and add any children you want to layer on top of it: 3778 3779```typescript 3780return ( 3781 <ImageBackground source={...} style={{ width: '100%', height: '100%' }}> 3782 <Text>Inside</Text> 3783 </ImageBackground> 3784); 3785``` 3786 3787Note that you must specify some width and height style attributes. 3788 3789### Best Camera Roll Image 3790 3791iOS saves multiple sizes for the same image in your Camera Roll. It's crucial to pick the one closest to your display size for performance reasons. For example, avoid using a full-quality 3264x2448 image as a source when displaying a 200x200 thumbnail. If there's an exact match, React Native will select it; otherwise, it uses the first one that's at least 50% larger to prevent blurring during resizing. This process is automatic, so you don't need to write tedious code for it. 3792 3793### Why Not Automatically Size Everything? 3794 3795*In the browser*, if no size is given to an image, the browser renders a 0x0 element, downloads the image, and then displays it with the correct size. The issue here is that your UI will jump around as images load, leading to a poor user experience known as Cumulative Layout Shift. 3796 3797*In React Native*, this behavior isn't implemented intentionally. It requires more work for developers to know the dimensions (or aspect ratio) of remote images in advance, but it leads to a better user experience. Static images loaded from the app bundle via `require('./my-icon.png')` can be automatically sized because their dimensions are available immediately at mounting time. 3798 3799For example, the result of `require('./my-icon.png')` might be: 3800 3801```json 3802{ "__packager_asset": true, "uri": "my-icon.png", "width": 591, "height": 573 } 3803``` 3804 3805### iOS Border Radius Styles 3806 3807Please note that the following corner-specific border radius style properties might be ignored by iOS's image component: 3808 3809- `borderTopLeftRadius` 3810- `borderTopRightRadius` 3811- `borderBottomLeftRadius` 3812- `borderBottomRightRadius` 3813 3814## TouchableNativeFeedback 3815 3816> For a more comprehensive and future-proof approach to handling touch-based input, consider using the Pressable API. 3817 3818TouchableNativeFeedback is an Android-specific wrapper designed to ensure views respond appropriately to touch interactions. It utilizes native state drawables to provide visual feedback during touches. 3819 3820Currently, it supports only a single View instance as a child node by replacing that View with another RCTView node, which includes additional properties. 3821 3822The background drawable for the native feedback touchable can be customized using the `background` property. 3823 3824### Example 3825 3826### Reference 3827 3828### Props 3829 3830#### TouchableWithoutFeedback Props 3831 3832Inherits props from TouchableWithoutFeedback. 3833 3834#### `background` 3835 3836Specifies the type of background drawable used to display feedback. It requires an object with a `type` property and additional data based on that `type`. Using static methods to generate this dictionary is recommended. 3837 3838- **Type**: `backgroundPropType` 3839 3840#### `useForeground` 3841 3842When set to true, adds a ripple effect to the foreground of the view instead of the background. This is useful if child views have their own backgrounds or when displaying images where you don't want the ripple covered by them. 3843 3844Ensure to check `TouchableNativeFeedback.canUseNativeForeground()` first, as this feature is only available on Android 6.0 and above. Using it on older versions will trigger a warning and fallback to background usage. 3845 3846- **Type**: `bool` 3847 3848#### `hasTVPreferredFocus` (Android) 3849 3850Indicates TV preferred focus (refer to the View component documentation). 3851 3852- **Type**: `bool` 3853 3854#### `nextFocusDown` (Android) 3855 3856Specifies TV next focus down (see View component documentation). 3857 3858- **Type**: `number` 3859 3860#### `nextFocusForward` (Android) 3861 3862Specifies TV next focus forward (see View component documentation). 3863 3864- **Type**: `number` 3865 3866#### `nextFocusLeft` (Android) 3867 3868Specifies TV next focus left (see View component documentation). 3869 3870- **Type**: `number` 3871 3872#### `nextFocusRight` (Android) 3873 3874Specifies TV next focus right (see View component documentation). 3875 3876- **Type**: `number` 3877 3878#### `nextFocusUp` (Android) 3879 3880Specifies TV next focus up (see View component documentation). 3881 3882- **Type**: `number` 3883 3884### Methods 3885 3886#### `SelectableBackground()` 3887 3888```typescript 3889static SelectableBackground( 3890 rippleRadius: number | null, 3891): ThemeAttributeBackgroundPropType; 3892``` 3893 3894Generates an object representing the Android theme's default background for selectable elements (`?android:attr/selectableItemBackground`). The `rippleRadius` parameter controls the radius of the ripple effect. 3895 3896#### `SelectableBackgroundBorderless()` 3897 3898```typescript 3899static SelectableBackgroundBorderless( 3900 rippleRadius: number | null, 3901): ThemeAttributeBackgroundPropType; 3902``` 3903 3904Generates an object representing the Android theme's default background for borderless selectable elements (`?android:attr/selectableItemBackgroundBorderless`). This is available on Android API level 21+. The `rippleRadius` parameter controls the radius of the ripple effect. 3905 3906#### `Ripple()` 3907 3908```typescript 3909static Ripple( 3910 color: ColorValue, 3911 borderless: boolean, 3912 rippleRadius?: number | null, 3913): RippleBackgroundPropType; 3914``` 3915 3916Creates an object representing a ripple drawable with a specified color (as a string). If the `borderless` property is true, the ripple will render outside of the view bounds (similar to native action bar buttons). This background type is available on Android API level 21+. 3917 3918**Parameters:** 3919 3920|Name|Type|Required|Description| 3921|-|-|-|-| 3922|color|string|Yes|The ripple color| 3923|borderless|boolean|Yes|Determines if the ripple can render outside bounds| 3924|rippleRadius|?number|No|Controls the radius of the ripple effect| 3925 3926#### `canUseNativeForeground()` 3927 3928```typescript 3929static canUseNativeForeground(): boolean; 3930``` 3931 3932## InputAccessoryView 3933 3934The `InputAccessoryView` component allows for customization of the keyboard input accessory view on iOS. This view appears above the keyboard when a `TextInput` is focused, enabling the creation of custom toolbars. 3935 3936To utilize this component, wrap your custom toolbar with `InputAccessoryView` and assign it a `nativeID`. Then, use that `nativeID` as the `inputAccessoryViewID` for any desired `TextInput`. Here's a basic example: 3937 3938This component can also facilitate sticky text inputs—text inputs anchored to the top of the keyboard. To achieve this, wrap a `TextInput` with `InputAccessoryView` without setting a `nativeID`. For an example, refer to `InputAccessoryViewExample.js`. 3939 3940### Reference 3941 3942#### Props 3943 3944##### `backgroundColor` 3945 3946|Type| 3947|-| 3948|color| 3949 3950##### `nativeID` 3951 3952A unique identifier used to associate this `InputAccessoryView` with specific TextInput(s). 3953 3954|Type| 3955|-| 3956|string| 3957 3958##### `style` 3959 3960|Type| 3961|-| 3962|View Style| 3963 3964### Known Issues 3965 3966- **react-native#18997**: Does not support multiline `TextInput`. 3967- **react-native#20157**: Incompatible with a bottom tab bar. 3968 3969## SafeAreaView 3970 3971The `SafeAreaView` component ensures that content is displayed within the safe area boundaries of a device. It's specifically designed for iOS devices running version 11 or later. 3972 3973This component automatically adjusts padding to account for areas not covered by navigation bars, tab bars, toolbars, and other ancestor views. Importantly, it also considers physical screen limitations like rounded corners or camera notches (e.g., the sensor housing area on iPhone 13). 3974 3975### Usage Example 3976 3977To implement `SafeAreaView`, wrap your top-level view with it and apply a style of `flex: 1`. Consider using a background color that aligns with your application's design. 3978 3979### Reference Details 3980 3981#### Props 3982 3983##### View Props 3984 3985`SafeAreaView` inherits all View Props. Note that any padding specified in styles applied to a `SafeAreaView` will be ignored, as the component uses its own padding logic. This can lead to different results across platforms. For more details, refer to issue #22211. 3986 3987## Image Style Props 3988 3989### Examples 3990 3991#### Image Resize Mode 3992 3993#### Image Border 3994 3995#### Image Border Radius 3996 3997#### Image Tint 3998 3999### Reference 4000 4001### Properties 4002 4003#### `backfaceVisibility` 4004 4005This property specifies whether the back face of a rotated image should be visible. 4006 4007|Type|Default| 4008|-|-| 4009|enum(`'visible'`, `'hidden'`)|`'visible'`| 4010 4011*** 4012 4013#### `backgroundColor` 4014 4015|Type| 4016|-| 4017|color| 4018 4019*** 4020 4021#### `borderBottomLeftRadius` 4022 4023|Type| 4024|-| 4025|number| 4026 4027*** 4028 4029#### `borderBottomRightRadius` 4030 4031|Type| 4032|-| 4033|number| 4034 4035*** 4036 4037#### `borderColor` 4038 4039|Type| 4040|-| 4041|color| 4042 4043*** 4044 4045#### `borderRadius` 4046 4047|Type| 4048|-| 4049|number| 4050 4051*** 4052 4053#### `borderTopLeftRadius` 4054 4055|Type| 4056|-| 4057|number| 4058 4059*** 4060 4061#### `borderTopRightRadius` 4062 4063|Type| 4064|-| 4065|number| 4066 4067*** 4068 4069#### `borderWidth` 4070 4071|Type| 4072|-| 4073|number| 4074 4075*** 4076 4077#### `opacity` 4078 4079Sets the opacity level for the image, with values ranging from `0.0` to `1.0`. 4080 4081|Type|Default| 4082|-|-| 4083|number|`1.0`| 4084 4085*** 4086 4087#### `overflow` 4088 4089|Type|Default| 4090|-|-| 4091|enum(`'visible'`, `'hidden'`)|`'visible'`| 4092 4093*** 4094 4095#### `overlayColor` (Android) 4096 4097When an image has rounded corners, specifying an `overlayColor` will fill the remaining corner space with a solid color. This is particularly useful for resize modes like `'contain'` and animated GIFs that are not fully supported by Android's implementation of rounded corners. 4098 4099A common use case involves images on a solid background where the `overlayColor` matches the background color. 4100 4101For more details, refer to the Fresco documentation. 4102 4103|Type| 4104|-| 4105|string| 4106 4107*** 4108 4109#### `resizeMode` 4110 4111Defines how an image should be resized when its frame dimensions do not match the raw image dimensions. The default mode is `cover`. 4112 4113- **`cover`:** Scale the image uniformly (maintaining aspect ratio) so that: 4114 4115 - Both dimensions of the image are equal to or larger than those of the view (minus padding). 4116 - At least one dimension matches the corresponding dimension of the view (minus padding). 4117 4118- **`contain`:** Scale the image uniformly (maintaining aspect ratio) so that both dimensions are equal to or less than those of the view (minus padding). 4119 4120- **`stretch`:** Independently scale width and height, potentially altering the aspect ratio. 4121 4122- **`repeat`:** Repeat the image to cover the frame. The image retains its size and aspect ratio unless larger than the view, in which case it is scaled down uniformly to fit within the view. 4123 4124- **`center`:** Center the image along both dimensions. If larger than the view, scale it down uniformly to fit within the view. 4125 4126|Type|Default| 4127|-|-| 4128|enum(`'cover'`, `'contain'`, `'stretch'`, `'repeat'`, `'center'`)|`'cover'`| 4129 4130*** 4131 4132#### `objectFit` 4133 4134Specifies how an image should be resized when its frame dimensions do not match the raw image dimensions. 4135 4136|Type|Default| 4137|-|-| 4138|enum(`'cover'`, `'contain'`, `'fill'`, `'scale-down'`)|`'cover'`| 4139 4140*** 4141 4142#### `tintColor` 4143 4144Alters the color of all non-transparent pixels to the specified `tintColor`. 4145 4146|Type| 4147|-| 4148|color| 4149 4150## Shadow Props 4151 4152- TypeScript 4153- JavaScript 4154 4155### Overview 4156 4157React Native provides three sets of APIs for implementing shadows: 4158 41591. **`boxShadow`:** A View style prop that aligns with the web's spec-compliant shadow implementation. 41601. **`dropShadow`:** Available as a filter function within the `filter` View style prop. 41611. **Native Shadow Props:** These include `shadowColor`, `shadowOffset`, `shadowOpacity`, and `shadowRadius`, which directly correspond to native platform-level APIs. 4162 4163#### Differences Between `dropShadow` and `boxShadow` 4164 4165- **Location:** 4166 4167 - `dropShadow` is part of the `filter` prop, while `boxShadow` stands alone. 4168 4169- **Rendering:** 4170 4171 - `dropShadow` uses an alpha mask, casting shadows only for pixels with positive alpha values. In contrast, `boxShadow` casts around the element's border box regardless of its contents unless it is inset. 4172 4173- **Platform Availability:** 4174 4175 - `dropShadow` is exclusive to Android; `boxShadow` works on both iOS and Android. 4176 4177- **Inset Capability:** 4178 4179 - Unlike `boxShadow`, `dropShadow` cannot be inset. 4180 4181- **Spread Distance:** 4182 - `dropShadow` lacks the `spreadDistance` feature available in `boxShadow`. 4183 4184While `boxShadow` and `dropShadow` offer more advanced capabilities, native shadow props are recommended for straightforward shadows. Note that only `shadowColor` is supported on both Android and iOS; other shadow properties function solely on iOS. 4185 4186### Properties 4187 4188#### `boxShadow` 4189 4190Refer to View Style Props documentation for details. 4191 4192#### `dropShadow` (Android) 4193 4194Refer to View Style Props documentation for details. 4195 4196#### `shadowColor` 4197 4198Sets the drop shadow color. This property functions only on Android API 28 and above. For similar effects on lower APIs, use the `elevation` property. 4199 4200|Type| 4201|-| 4202|color| 4203 4204#### `shadowOffset` (iOS) 4205 4206Defines the drop shadow offset. 4207 4208|Type| 4209|-| 4210|object: `{width: number,height: number}`| 4211 4212#### `shadowOpacity` (iOS) 4213 4214Determines the drop shadow opacity, factoring in the color's alpha component. 4215 4216|Type| 4217|-| 4218|number| 4219 4220#### `shadowRadius` (iOS) 4221 4222Specifies the drop shadow blur radius. 4223 4224|Type| 4225|-| 4226|number| 4227 4228## Text Style Props 4229 4230### Example 4231 4232- TypeScript 4233- JavaScript 4234 4235### Reference 4236 4237### Properties 4238 4239#### `color` 4240 4241- **Type**: color 4242 4243#### `fontFamily` 4244 4245- **Type**: string 4246 4247#### `fontSize` 4248 4249- **Type**: number 4250 4251#### `fontStyle` 4252 4253- **Type**: enum 4254 - `'normal'` 4255 - `'italic'` 4256 4257#### `fontWeight` 4258 4259Specifies the font weight. The values `'normal'` and `'bold'` are supported for most fonts. If a font does not have variants for all numeric values, the closest available variant is used. 4260 4261- **Type**: enum or number 4262 - `'normal'` 4263 - `'bold'` 4264 - `'100'` 4265 - `'200'` 4266 - `'300'` 4267 - `'400'` 4268 - `'500'` 4269 - `'600'` 4270 - `'700'` 4271 - `'800'` 4272 - `'900'` 4273- **Default**: `'normal'` 4274 4275#### `includeFontPadding` (Android) 4276 4277Set to `false` to remove extra font padding, which is intended for certain ascenders and descenders. This can help align text better when centered vertically. For optimal results, also set `textAlignVertical` to `center`. 4278 4279- **Type**: bool 4280- **Default**: `true` 4281 4282#### `fontVariant` 4283 4284Allows setting all font variants using an array of enums or a space-separated string (e.g., `'small-caps common-ligatures'`). 4285 4286- **Type**: array of enum or string 4287 - `'small-caps'` 4288 - `'oldstyle-nums'` 4289 - `'lining-nums'` 4290 - `'tabular-nums'` 4291 - `'proportional-nums'` 4292- **Default**: `[]` 4293 4294#### `letterSpacing` 4295 4296Adjusts the spacing between characters. By default, there is no extra letter spacing. 4297 4298- **Type**: number 4299 4300#### `lineHeight` 4301 4302Controls vertical spacing between lines of text within a text element by specifying the distance between baselines of consecutive lines. 4303 4304- **Type**: number 4305 4306#### `textAlign` 4307 4308Specifies text alignment. On Android, `'justify'` is supported only on Oreo (8.0) or above (API level >= 26). It falls back to `left` on lower versions. 4309 4310- **Type**: enum 4311 - `'auto'` 4312 - `'left'` 4313 - `'right'` 4314 - `'center'` 4315 - `'justify'` 4316- **Default**: `'auto'` 4317 4318#### `textAlignVertical` (Android) 4319 4320- **Type**: enum 4321 - `'auto'` 4322 - `'top'` 4323 - `'bottom'` 4324 - `'center'` 4325- **Default**: `'auto'` 4326 4327#### `textDecorationColor` (iOS) 4328 4329- **Type**: color 4330 4331#### `textDecorationLine` 4332 4333- **Type**: enum 4334 - `'none'` 4335 - `'underline'` 4336 - `'line-through'` 4337 - `'underline line-through'` 4338- **Default**: `'none'` 4339 4340#### `textDecorationStyle` (iOS) 4341 4342- **Type**: enum 4343 - `'solid'` 4344 - `'double'` 4345 - `'dotted'` 4346 - `'dashed'` 4347- **Default**: `'solid'` 4348 4349#### `textShadowColor` 4350 4351- **Type**: color 4352 4353#### `textShadowOffset` 4354 4355- **Type**: object 4356 ```typescript 4357 { width?: number; height?: number } 4358 ``` 4359 4360#### `textShadowRadius` 4361 4362- **Type**: number 4363 4364#### `textTransform` 4365 4366- **Type**: enum 4367 - `'none'` 4368 - `'uppercase'` 4369 - `'lowercase'` 4370 - `'capitalize'` 4371- **Default**: `'none'` 4372 4373#### `verticalAlign` (Android) 4374 4375- **Type**: enum 4376 - `'auto'` 4377 - `'top'` 4378 - `'bottom'` 4379 - `'middle'` 4380- **Default**: `'auto'` 4381 4382#### `writingDirection` (iOS) 4383 4384- **Type**: enum 4385 - `'auto'` 4386 - `'ltr'` 4387 - `'rtl'` 4388- **Default**: `'auto'` 4389 4390#### `userSelect` 4391 4392Allows text selection and native copy-paste functionality, taking precedence over the `selectable` prop. 4393 4394- **Type**: enum 4395 - `'auto'` 4396 - `'text'` 4397 - `'none'` 4398 - `'contain'` 4399 - `'all'` 4400- **Default**: `none` 4401 4402## View Style Props 4403 4404### Example 4405 4406### Reference 4407 4408### Properties 4409 4410#### `backfaceVisibility` 4411 4412- **Type**: `enum('visible', 'hidden')` 4413 4414#### `backgroundColor` 4415 4416- **Type**: `color` 4417 4418#### `borderBottomColor` 4419 4420- **Type**: `color` 4421 4422#### `borderBottomEndRadius` 4423 4424- **Type**: `number` 4425 4426#### `borderBottomLeftRadius` 4427 4428- **Type**: `number` 4429 4430#### `borderBottomRightRadius` 4431 4432- **Type**: `number` 4433 4434#### `borderBottomStartRadius` 4435 4436- **Type**: `number` 4437 4438#### `borderStartEndRadius` 4439 4440- **Type**: `number` 4441 4442#### `borderStartStartRadius` 4443 4444- **Type**: `number` 4445 4446#### `borderEndEndRadius` 4447 4448- **Type**: `number` 4449 4450#### `borderEndStartRadius` 4451 4452- **Type**: `number` 4453 4454#### `borderBottomWidth` 4455 4456- **Type**: `number` 4457 4458#### `borderColor` 4459 4460- **Type**: `color` 4461 4462#### `borderCurve` (iOS) 4463 4464On iOS 13+, it is possible to change the corner curve of borders. 4465 4466- **Type**: `enum('circular', 'continuous')` 4467 4468#### `borderEndColor` 4469 4470- **Type**: `color` 4471 4472#### `borderLeftColor` 4473 4474- **Type**: `color` 4475 4476#### `borderLeftWidth` 4477 4478- **Type**: `number` 4479 4480#### `borderRadius` 4481 4482If the rounded border is not visible, try applying `overflow: 'hidden'` as well. 4483 4484- **Type**: `number` 4485 4486#### `borderRightColor` 4487 4488- **Type**: `color` 4489 4490#### `borderRightWidth` 4491 4492- **Type**: `number` 4493 4494#### `borderStartColor` 4495 4496- **Type**: `color` 4497 4498#### `borderStyle` 4499 4500- **Type**: `enum('solid', 'dotted', 'dashed')` 4501 4502#### `borderTopColor` 4503 4504- **Type**: `color` 4505 4506#### `borderTopEndRadius` 4507 4508- **Type**: `number` 4509 4510#### `borderTopLeftRadius` 4511 4512- **Type**: `number` 4513 4514#### `borderTopRightRadius` 4515 4516- **Type**: `number` 4517 4518#### `borderTopStartRadius` 4519 4520- **Type**: `number` 4521 4522#### `borderTopWidth` 4523 4524- **Type**: `number` 4525 4526#### `borderWidth` 4527 4528- **Type**: `number` 4529 4530#### `boxShadow` 4531 4532**Note:**\ 4533`boxShadow` is only available on the New Architecture. Outset shadows are supported on Android 9+, and inset shadows on Android 10+. This prop adds a shadow effect to an element, allowing control over position, color, size, and blurriness of the shadow. It can be either outside or inside the border box depending on whether it is *inset*. This implementation follows web standards. 4534 4535Multiple shadows can be combined into a single `boxShadow`. 4536 4537- **Type**: `array of BoxShadowValue objects | string` 4538 4539#### `cursor` (iOS) 4540 4541On iOS 17+, setting to `pointer` enables hover effects when using a pointer device or gaze on visionOS. 4542 4543- **Type**: `enum('auto', 'pointer')` 4544 4545#### `elevation` (Android) 4546 4547Sets the elevation of a view, adding a drop shadow and affecting z-order for overlapping views. Supported only on Android 5.0+; has no effect on earlier versions. 4548 4549- **Type**: `number` 4550 4551#### `filter` 4552 4553**Note:**\ 4554Adds graphical filters to the `View`, which can include multiple filter functions representing atomic changes. Filters apply to both the `View` and its descendants, implying `overflow: hidden`. 4555 4556The following filter functions are cross-platform: 4557 4558- `brightness`: Adjusts brightness (non-negative number or percentage). 4559- `opacity`: Changes opacity/alpha (non-negative number or percentage). 4560 4561**Note:**\ 4562On iOS, only `brightness` and `opacity` are available due to performance and compliance issues. Android plans to use SwiftUI for potential workarounds. 4563 4564Android-specific filter functions: 4565 4566- `blur`: Applies Gaussian blur with a specified radius (DIP value). 4567 4568- `contrast`: Adjusts contrast (non-negative number or percentage). 4569 4570- `dropShadow`: Adds shadow around alpha mask; requires color, offsets, and optional standard deviation. 4571 4572- `grayscale`: Converts to grayscale by amount (non-negative number or percentage). 4573 4574- `hueRotate`: Rotates hue on a color wheel (angle with `deg` or `rad` units). 4575 4576- **Note:**\ 4577 `blur` and `dropShadow` are supported only on Android 12+. 4578 4579- `invert`: Inverts colors (non-negative number or percentage). 4580 4581- `sepia`: Converts to sepia by amount (non-negative number or percentage). 4582 4583- `saturate`: Changes saturation (non-negative number or percentage). 4584 4585- **Type**: `array of objects: {brightness: number|string}, {opacity: number|string}, {blur: number|string}, {contrast: number|string}, {dropShadow: DropShadowValue|string}, {grayscale: number|string}, {hueRotate: number|string}, {invert: number|string}, {sepia: number|string}, {saturate: number|string}` or `string` 4586 4587#### `opacity` 4588 4589- **Type**: `number` 4590 4591#### `outlineColor` 4592 4593**Note:**\ 4594Sets the color of an element's outline. See web documentation for more details. 4595 4596- **Type**: `color` 4597 4598#### `outlineOffset` 4599 4600**Note:**\ 4601Sets space between an outline and element bounds without affecting layout. See web documentation for more details. 4602 4603- **Type**: `number` 4604 4605#### `outlineStyle` 4606 4607**Note:**\ 4608Sets the style of an element's outline. See web documentation for more details. 4609 4610- **Type**: `enum('solid', 'dotted', 'dashed')` 4611 4612#### `outlineWidth` 4613 4614**Note:**\ 4615Defines the width of an outline drawn outside the border, without affecting layout. See web documentation for more details. 4616 4617- **Type**: `number` 4618 4619#### `pointerEvents` 4620 4621Controls whether a `View` can be targeted by touch events: 4622 4623- `'auto'`: The View can be targeted. 4624 4625- `'none'`: The View is never targeted. 4626 4627- `'box-none'`: Subviews can be targeted, but not the View itself. 4628 4629- `'box-only'`: Only the View can be targeted, not its subviews. 4630 4631- **Type**: `enum('auto', 'box-none', 'box-only', 'none')` 4632 4633## BoxShadowValue Object Type 4634 4635The `BoxShadowValue` object is utilized by the `boxShadow` style property. It consists of two to four length values, an optional color specification, and an optional boolean for inset shadows. These elements collectively define the shadow's color, position, size, and blurriness. 4636 4637### Example 4638 4639```typescript 4640{ 4641 offsetX: 10, 4642 offsetY: -3, 4643 blurRadius: '15px', 4644 spreadDistance: '10px', 4645 color: 'red', 4646 inset: true, 4647} 4648``` 4649 4650### Keys and Values 4651 4652#### `offsetX` 4653 4654The x-axis offset, which can be positive or negative. A positive value indicates a rightward direction, while a negative value indicates leftward. 4655 4656- **Type**: number | string 4657- **Optional**: No 4658 4659#### `offsetY` 4660 4661The y-axis offset, which can also be positive or negative. A positive value indicates an upward direction, and a negative value indicates downward. 4662 4663- **Type**: number | string 4664- **Optional**: No 4665 4666#### `blurRadius` 4667 4668This represents the radius used in the Gaussian blur algorithm. Larger values result in a blurrier shadow. Only non-negative values are valid; the default is 0. 4669 4670- **Type**: number | string 4671- **Optional**: Yes 4672 4673#### `spreadDistance` 4674 4675Determines how much larger or smaller the shadow grows or shrinks. A positive value enlarges the shadow, while a negative value reduces it. 4676 4677- **Type**: number | string 4678- **Optional**: Yes 4679 4680#### `color` 4681 4682Specifies the color of the shadow. The default is `black`. 4683 4684- **Type**: color 4685- **Optional**: Yes 4686 4687#### `inset` 4688 4689Indicates whether the shadow is inset or not. Inset shadows appear inside the element's border box, rather than outside. 4690 4691- **Type**: boolean 4692- **Optional**: Yes 4693 4694### Used by 4695 4696- `boxShadow` 4697 4698## Handling Touches 4699 4700Users primarily interact with mobile applications through touch gestures such as tapping buttons, scrolling lists, or zooming maps. React Native offers components to manage common gestures and a comprehensive gesture responder system for advanced recognition. The `Button` component is particularly useful for basic interactions. 4701 4702### Displaying a Basic Button 4703 4704The `Button` component in React Native provides an easy way to create buttons that look consistent across platforms. Here's a minimal example: 4705 4706```typescript 4707<Button 4708 onPress={() => { 4709 console.log('You tapped the button!'); 4710 }} 4711 title="Press Me" 4712/> 4713``` 4714 4715On iOS, this renders as a blue label, while on Android it appears as a blue rounded rectangle with light text. Pressing the button triggers the `onPress` function, which logs a message to the console in this example. You can customize the button's color using the `color` prop. 4716 4717Experiment with the `Button` component by adjusting platform settings and previewing changes. 4718 4719### Touchables 4720 4721For more customized buttons, React Native offers "Touchable" components that capture tapping gestures and provide feedback. These components require additional styling to fit your app's design. 4722 4723Choose a "Touchable" component based on desired feedback: 4724 4725- **TouchableHighlight**: Darkens the background when pressed, suitable for button or link-like interactions. 4726 4727- **TouchableNativeFeedback**: On Android, it shows ink surface ripples in response to touch. 4728 4729- **TouchableOpacity**: Reduces opacity during press, allowing background visibility. 4730 4731- **TouchableWithoutFeedback**: Detects taps without providing visual feedback. 4732 4733Long presses can be detected by using the `onLongPress` prop with any "Touchable" component. 4734 4735### Scrolling and Swiping 4736 4737For gestures like swipes and pans, which are common on touch devices, consider using the ScrollView Core Component to enable scrolling through lists or content pages. 4738 4739### Known Issues 4740 4741- **react-native#29308**: The touch area does not extend beyond parent view bounds, and negative margins are unsupported on Android. 4742 4743## DropShadowValue Object Type 4744 4745The `DropShadowValue` object is utilized by the `filter` style property for implementing the `dropShadow` function. It consists of two or three length values and an optional color, which together define the drop shadow's characteristics such as its color, position, and blurriness. 4746 4747### Example 4748 4749```typescript 4750{ 4751 offsetX: 10, 4752 offsetY: -3, 4753 standardDeviation: '15px', 4754 color: 'blue', 4755} 4756``` 4757 4758### Keys and Values 4759 4760#### `offsetX` 4761 4762The offset on the x-axis. This value can be either positive or negative, where a positive value indicates a rightward shift and a negative value indicates a leftward shift. 4763 4764|Type|Optional| 4765|-|-| 4766|number \| string|No| 4767 4768#### `offsetY` 4769 4770The offset on the y-axis. Similar to `offsetX`, this value can be either positive or negative, with a positive value indicating an upward shift and a negative value indicating a downward shift. 4771 4772|Type|Optional| 4773|-|-| 4774|number \| string|No| 4775 4776#### `standardDeviation` 4777 4778This represents the standard deviation used in the Gaussian blur algorithm. A larger value results in a blurrier shadow. Only non-negative values are valid, with the default being 0. 4779 4780|Type|Optional| 4781|-|-| 4782|number \| string|Yes| 4783 4784#### `color` 4785 4786The color of the shadow. By default, this is set to `black`. 4787 4788|Type|Optional| 4789|-|-| 4790|color|Yes| 4791 4792### Used by 4793 4794- `filter` 4795 4796## LayoutEvent Object Type 4797 4798The `LayoutEvent` object is provided in the callback following a layout change of a component, such as when using the `onLayout` event in a View component. 4799 4800### Example 4801 4802```typescript 4803{ 4804 layout: { 4805 width: 520, 4806 height: 70.5, 4807 x: 0, 4808 y: 42.5 4809 }, 4810 target: 1127 4811} 4812``` 4813 4814### Keys and Values 4815 4816#### `height` 4817 4818Represents the component's height after a layout change. 4819 4820|Type|Optional| 4821|-|-| 4822|number|No| 4823 4824#### `width` 4825 4826Indicates the component's width following a layout change. 4827 4828|Type|Optional| 4829|-|-| 4830|number|No| 4831 4832#### `x` 4833 4834Specifies the X coordinate of the component within its parent component. 4835 4836|Type|Optional| 4837|-|-| 4838|number|No| 4839 4840#### `y` 4841 4842Denotes the Y coordinate of the component inside its parent component. 4843 4844|Type|Optional| 4845|-|-| 4846|number|No| 4847 4848#### `target` 4849 4850Identifies the node ID of the element that receives the PressEvent. It can be a number, or it may be `null` or `undefined`. 4851 4852|Type|Optional| 4853|-|-| 4854|number, `null`, `undefined`|No| 4855 4856### Components Utilizing LayoutEvent 4857 4858- Image 4859- Pressable 4860- ScrollView 4861- Text 4862- TextInput 4863- TouchableWithoutFeedback 4864- View 4865 4866## PressEvent Object Type 4867 4868The `PressEvent` object is returned in the callback as a result of user press interactions, such as those triggered by the `onPress` event in Button components. 4869 4870### Example 4871 4872```typescript 4873{ 4874 changedTouches: Array<PressEvent>, 4875 identifier: number, 4876 locationX: number, 4877 locationY: number, 4878 pageX: number, 4879 pageY: number, 4880 target: number | null | undefined, 4881 timestamp: number, 4882 touches: Array<PressEvent> 4883} 4884``` 4885 4886### Keys and Values 4887 4888#### `changedTouches` 4889 4890An array containing all `PressEvents` that have changed since the last event. 4891 4892|Type|Optional| 4893|-|-| 4894|Array of PressEvents|No| 4895 4896#### `force` (iOS) 4897 4898The amount of force used during a 3D Touch press, represented as a float value ranging from `0.0` to `1.0`. 4899 4900|Type|Optional| 4901|-|-| 4902|number|Yes| 4903 4904#### `identifier` 4905 4906A unique numeric identifier assigned to the event. 4907 4908|Type|Optional| 4909|-|-| 4910|number|No| 4911 4912#### `locationX` 4913 4914The X coordinate of the touch origin within the touchable area, relative to the element. 4915 4916|Type|Optional| 4917|-|-| 4918|number|No| 4919 4920#### `locationY` 4921 4922The Y coordinate of the touch origin within the touchable area, relative to the element. 4923 4924|Type|Optional| 4925|-|-| 4926|number|No| 4927 4928#### `pageX` 4929 4930The X coordinate of the touch origin on the screen, relative to the root view. 4931 4932|Type|Optional| 4933|-|-| 4934|number|No| 4935 4936#### `pageY` 4937 4938The Y coordinate of the touch origin on the screen, relative to the root view. 4939 4940|Type|Optional| 4941|-|-| 4942|number|No| 4943 4944#### `target` 4945 4946The node ID of the element receiving the `PressEvent`. It can be a number or `null`/`undefined`. 4947 4948|Type|Optional| 4949|-|-| 4950|number, null, undefined|No| 4951 4952#### `timestamp` 4953 4954A timestamp value indicating when the `PressEvent` occurred, represented in milliseconds. 4955 4956|Type|Optional| 4957|-|-| 4958|number|No| 4959 4960#### `touches` 4961 4962An array containing all current `PressEvents` on the screen. 4963 4964|Type|Optional| 4965|-|-| 4966|Array of PressEvents|No| 4967 4968### Used By 4969 4970- Button 4971- PanResponder 4972- Pressable 4973- ScrollView 4974- Text 4975- TextInput 4976- TouchableHighlight 4977- TouchableOpacity 4978- TouchableNativeFeedback 4979- TouchableWithoutFeedback 4980- View 4981 4982## Rect Object Type 4983 4984The `Rect` object type is designed to accept numeric pixel values, which are used to extend a rectangular area. These values modify the original dimensions of the rectangle. 4985 4986### Example 4987 4988```typescript 4989{ 4990 bottom: 20, 4991 left: null, 4992 right: undefined, 4993 top: 50 4994} 4995``` 4996 4997### Keys and Values 4998 4999#### `bottom` 5000 5001|Type|Required| 5002|-|-| 5003|number, `null`, `undefined`|No| 5004 5005#### `left` 5006 5007|Type|Required| 5008|-|-| 5009|number, `null`, `undefined`|No| 5010 5011#### `right` 5012 5013|Type|Required| 5014|-|-| 5015|number, `null`, `undefined`|No| 5016 5017#### `top` 5018 5019|Type|Required| 5020|-|-| 5021|number, `null`, `undefined`|No| 5022 5023### Used By 5024 5025- `Image` 5026- `Pressable` 5027- `Text` 5028- `TouchableWithoutFeedback` 5029 5030## Platform Support 5031 5032- Android 5033- iOS 5034- macOS 5035- TV 5036- watchOS 5037- Web 5038- Windows 5039- visionOS 5040 5041If your project constraints are not well-served by a Framework or you prefer creating your own, it's possible to develop a React Native app without using one. Begin by setting up your environment and follow the steps below to create an application. 5042 5043### Step 1: Creating a New Application 5044 5045> **Note:** If you have previously installed a global `react-native-cli` package, remove it to avoid unexpected issues: 5046> 5047> ```shell 5048> npm uninstall -g react-native-cli @react-native-community/cli 5049> ``` 5050 5051Use the React Native Community CLI to generate a new project. For example, create a new React Native project named "AwesomeProject": 5052 5053```shell 5054npx @react-native-community/cli@latest init AwesomeProject 5055``` 5056 5057This step is unnecessary if you are integrating React Native into an existing application, using Expo, or adding Android support to an existing React Native project (refer to Integration with Existing Apps). Alternatively, a third-party CLI like Ignite CLI can be used for setup. 5058 5059**Info:** If you encounter issues on iOS, try reinstalling dependencies by executing the following commands: 5060 50611. Navigate to the `ios` folder: `cd ios` 50621. Install Bundler: `bundle install` 50631. Install iOS dependencies with CocoaPods: `bundle exec pod install` 5064 5065##### \[Optional] Using a Specific Version or Template 5066 5067To start a new project with a specific React Native version, use the `--version` argument: 5068 5069```shell 5070npx @react-native-community/cli@X.XX.X init AwesomeProject --version X.XX.X 5071``` 5072 5073You can also initiate a project using a custom template with the `--template` argument. More details are available in related documentation. 5074 5075### Step 2: Start Metro 5076 5077**Metro** is React Native's JavaScript build tool. To start the Metro development server, run one of these commands from your project folder: 5078 5079- Using npm: 5080 5081 ```shell 5082 npm start 5083 ``` 5084 5085- Using Yarn: 5086 5087 ```shell 5088 yarn start 5089 ``` 5090 5091**Note:** For those familiar with web development, Metro is akin to bundlers like Vite and webpack but tailored for React Native. It uses Babel to transform syntax such as JSX into executable JavaScript. 5092 5093### Step 3: Start Your Application 5094 5095Keep the Metro Bundler running in its own terminal. Open a new terminal within your project folder and execute one of these commands: 5096 5097- Using npm: 5098 5099 ```shell 5100 npm run android 5101 ``` 5102 5103- Using Yarn: 5104 5105 ```shell 5106 yarn android 5107 ``` 5108 5109If everything is configured correctly, your app should appear on the Android emulator shortly. Alternatively, you can launch it directly from within Android Studio. 5110 5111> If issues arise, consult the Troubleshooting page for assistance. 5112 5113### Step 4: Modifying Your App 5114 5115With the app running successfully, proceed to modify it: 5116 5117- Open `App.tsx` in your preferred text editor and make changes. 5118- Reload the app by pressing `R` twice or selecting `Reload` from the Dev Menu (`Ctrl + M`) to view updates. 5119 5120### Congratulations! 5121 5122You've run and modified your first barebone React Native app successfully. 5123 5124#### Next Steps 5125 5126- To integrate this new React Native code into an existing application, refer to the Integration guide. 5127- For more insights on React Native, explore the Introduction to React Native. 5128 5129## Navigating Between Screens 5130 5131Mobile applications typically consist of multiple screens, necessitating effective management of screen presentation and transitions. This is often achieved using a navigator component. This guide explores various navigation components available in React Native, with a focus on React Navigation for straightforward stack and tabbed navigation patterns across both Android and iOS platforms. 5132 5133For projects integrating React Native into existing apps that manage navigation natively or seeking alternatives to React Navigation, consider the `react-native-navigation` library, which offers native navigation solutions for both platforms. 5134 5135### React Navigation 5136 5137React Navigation is a community-driven standalone library designed to simplify screen setup in an app with minimal code. 5138 5139#### Installation and Setup 5140 5141To begin using React Navigation, install the necessary packages: 5142 5143```shell 5144npm install @react-navigation/native @react-navigation/native-stack 5145``` 5146 5147Next, install peer dependencies based on your project type: 5148 5149- **Expo Managed Project:** 5150 5151 ```shell 5152 npx expo install react-native-screens react-native-safe-area-context 5153 ``` 5154 5155- **Bare React Native Project:** 5156 5157 ```shell 5158 npm install react-native-screens react-native-safe-area-context 5159 ``` 5160 5161 For iOS, ensure CocoaPods is installed and run: 5162 5163 ```shell 5164 cd ios 5165 pod install 5166 cd .. 5167 ``` 5168 5169> Note: Post-installation warnings related to peer dependencies are common due to version range issues in some packages. These can generally be ignored if the app builds successfully. 5170 5171Wrap your entire application within a `NavigationContainer`, typically done in your entry file (`index.js` or `App.js`): 5172 5173```typescript 5174import * as React from 'react'; 5175import { NavigationContainer } from '@react-navigation/native'; 5176 5177const App = () => { 5178 return ( 5179 <NavigationContainer> 5180 {/* Rest of your app code */} 5181 </NavigationContainer> 5182 ); 5183}; 5184 5185export default App; 5186``` 5187 5188#### Usage 5189 5190Create an application with a home screen and a profile screen as follows: 5191 5192```typescript 5193import * as React from 'react'; 5194import { NavigationContainer } from '@react-navigation/native'; 5195import { createNativeStackNavigator } from '@react-navigation/native-stack'; 5196 5197const Stack = createNativeStackNavigator(); 5198 5199const MyStack = () => { 5200 return ( 5201 <NavigationContainer> 5202 <Stack.Navigator> 5203 <Stack.Screen 5204 name="Home" 5205 component={HomeScreen} 5206 options={{ title: 'Welcome' }} 5207 /> 5208 <Stack.Screen name="Profile" component={ProfileScreen} /> 5209 </Stack.Navigator> 5210 </NavigationContainer> 5211 ); 5212}; 5213``` 5214 5215In this setup, two screens (`Home` and `Profile`) are defined using the `Stack.Screen` component. You can define additional screens as needed. 5216 5217Options such as screen titles can be set via the `options` prop of `Stack.Screen`. 5218 5219Each screen requires a `component` prop that is a React component. These components receive a `navigation` prop, which includes methods to navigate between screens. For instance, use `navigation.navigate` to transition to the `Profile` screen: 5220 5221```typescript 5222const HomeScreen = ({ navigation }) => { 5223 return ( 5224 <Button 5225 title="Go to Jane's profile" 5226 onPress={() => 5227 navigation.navigate('Profile', { name: 'Jane' }) 5228 } 5229 /> 5230 ); 5231}; 5232 5233const ProfileScreen = ({ navigation, route }) => { 5234 return <Text>This is {route.params.name}'s profile</Text>; 5235}; 5236``` 5237 5238The `native-stack` navigator leverages native APIs (`UINavigationController` on iOS and `Fragment` on Android), ensuring consistent behavior and performance with natively built apps. 5239 5240React Navigation also offers packages for different navigators, such as tabs and drawers, enabling various navigation patterns in your app. For a comprehensive introduction to React Navigation, refer to the React Navigation Getting Started Guide. 5241 5242## Troubleshooting 5243 5244This guide addresses common issues encountered during the setup of React Native. If you face an issue not listed here, consider searching for it on GitHub. 5245 5246### Port Already in Use 5247 5248The Metro bundler typically runs on port 8081. If this port is occupied by another process, you can either terminate that process or configure the bundler to use a different port. 5249 5250#### Terminating a Process on Port 8081 5251 5252To find and terminate the process using port 8081: 5253 5254- **Linux/macOS:** 5255 5256 ```shell 5257 sudo lsof -i :8081 5258 ``` 5259 5260 Identify the PID from the output, then run: 5261 5262 ```shell 5263 kill -9 <PID> 5264 ``` 5265 5266- **Windows:** Use Resource Monitor to find and Task Manager to stop the process using port 8081. 5267 5268#### Using a Different Port 5269 5270Configure the bundler to use an alternative port by specifying it in your start command: 5271 5272- **npm:** 5273 5274 ```shell 5275 npm start -- --port=8088 5276 ``` 5277 5278- **Yarn:** 5279 5280 ```shell 5281 yarn start --port 8088 5282 ``` 5283 5284Update your application configurations to load the JavaScript bundle from this new port. For iOS, modify occurrences of `8081` in the `ios/__App_Name__.xcodeproj/project.pbxproj` file. 5285 5286### NPM Locking Error 5287 5288If you encounter an error like `npm WARN locking Error: EACCES`, try running: 5289 5290```shell 5291sudo chown -R $USER ~/.npm 5292sudo chown -R $USER /usr/local/lib/node_modules 5293``` 5294 5295### Missing Libraries for React 5296 5297Ensure all necessary dependencies are included if React Native is added manually. Link the binaries built by these dependencies to your app binary using the `Linked Frameworks and Binaries` section in Xcode project settings. 5298 5299For CocoaPods users, verify that React and its subspecs are specified in the `Podfile`. For example: 5300 5301```ruby 5302pod 'React', :path => '../node_modules/react-native', :subspecs => [ 5303 'RCTText', 5304 'RCTImage', 5305 'RCTNetwork', 5306 'RCTWebSocket', 5307] 5308``` 5309 5310Run `pod install` to create a `Pods/` directory with React installed. Use the generated `.xcworkspace` file for subsequent builds. 5311 5312#### Additional CocoaPods Issues 5313 5314- **React Native does not compile as a CocoaPod:** Consider using the `cocoapods-fix-react-native` plugin. 5315 5316- **Argument list too long error:** Ensure `User Search Header Paths` and `Header Search Paths` are set to defaults by CocoaPods. Remove any custom overrides in Xcode's Build Settings. 5317 5318### No Transports Available 5319 5320React Native includes a WebSocket polyfill initialized with `import React from 'react'`. If using modules like Firebase that require WebSockets, ensure they are imported after React: 5321 5322```javascript 5323import React from "react" 5324import Firebase from "firebase" 5325``` 5326 5327### Shell Command Unresponsive Exception 5328 5329If you encounter an error such as: 5330 5331``` 5332Execution failed for task ':app:installDebug'. 5333 com.android.builder.testing.api.DeviceException: com.android.ddmlib.ShellCommandUnresponsiveException 5334``` 5335 5336Try downgrading your Gradle version to 1.2.3 in `android/build.gradle`. 5337 5338### react-native init Hangs 5339 5340If `npx react-native init` hangs, run it again with verbose mode: 5341 5342```shell 5343npx react-native init --verbose 5344``` 5345 5346Refer to issue #2797 for common causes. 5347 5348For more detailed logs during debugging, use the verbose option: 5349 5350- **npm:** 5351 5352 ```shell 5353 npm run android -- --verbose 5354 ``` 5355 5356- **Yarn:** 5357 5358 ```shell 5359 yarn android --verbose 5360 ``` 5361 5362### Unable to Start React Native Package Manager (Linux) 5363 5364#### Case 1: Error "code":"ENOSPC","errno":"ENOSPC" 5365 5366This issue arises from the limit on directories inotify can monitor. Resolve it by running: 5367 5368```shell 5369echo fs.inotify.max_user_watches=582222 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p 5370``` 5371 5372#### Error: spawnSync ./gradlew EACCES 5373 5374If executing `npm run android` or `yarn android` on macOS results in this error, make the `gradlew` file executable: 5375 5376```shell 5377sudo chmod +x android/gradlew 5378``` 5379 5380## Animations 5381 5382Animations enhance user experience by simulating physically believable motion in interfaces. React Native offers two animation systems: `Animated` for detailed control and `LayoutAnimation` for global layout transitions. 5383 5384### `Animated` API 5385 5386The `Animated` API allows expressive, performant animations through declarative relationships between inputs and outputs. It includes six animatable components: `View`, `Text`, `Image`, `ScrollView`, `FlatList`, and `SectionList`. Custom animated components can be created using `Animated.createAnimatedComponent()`. 5387 5388#### Example 5389 5390A container view that fades in on mount: 5391 5392```typescript 5393import React, { useRef } from 'react'; 5394import { Animated, View } from 'react-native'; 5395 5396const FadeInView = (props) => { 5397 const fadeAnim = useRef(new Animated.Value(0)).current; 5398 5399 React.useEffect(() => { 5400 Animated.timing(fadeAnim, { 5401 toValue: 1, 5402 duration: 500, 5403 useNativeDriver: true, 5404 }).start(); 5405 }, [fadeAnim]); 5406 5407 return ( 5408 <Animated.View 5409 style={{ 5410 ...props.style, 5411 opacity: fadeAnim, 5412 }} 5413 > 5414 {props.children} 5415 </Animated.View> 5416 ); 5417}; 5418``` 5419 5420#### Key Features 5421 5422- **Native Driver**: Use `useNativeDriver: true` for better performance by offloading animations to the native thread. 5423 5424- **Gesture Mapping**: Map gestures directly to animated values using `Animated.event`. 5425 5426- **Responding to Values**: Use `addListener` or `stopAnimation` to respond to animation states. 5427 5428#### Caveats 5429 5430Not all properties are supported with the native driver. Only non-layout properties like `transform` and `opacity` can be animated natively. 5431 5432### `LayoutAnimation` API 5433 5434`LayoutAnimation` configures global animations for layout changes, useful for Flexbox updates without manual calculations. It requires enabling experimental features on Android: 5435 5436```typescript 5437import { UIManager } from "react-native" 5438 5439UIManager.setLayoutAnimationEnabledExperimental && 5440 UIManager.setLayoutAnimationEnabledExperimental(true) 5441``` 5442 5443#### Usage Example 5444 5445```typescript 5446import React, { useState } from 'react'; 5447import { View, Button, LayoutAnimation, Platform } from 'react-native'; 5448 5449const ExpandableComponent = () => { 5450 const [expanded, setExpanded] = useState(false); 5451 5452 if (Platform.OS === 'android') { 5453 UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true); 5454 } 5455 5456 return ( 5457 <View> 5458 <Button title="Toggle" onPress={() => { 5459 LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); 5460 setExpanded(!expanded); 5461 }} /> 5462 {expanded && <View style={{ height: 100, backgroundColor: 'lightblue' }} />} 5463 </View> 5464 ); 5465}; 5466``` 5467 5468### Additional Notes 5469 5470- **`requestAnimationFrame`**: A polyfill for managing frame updates in animations. 5471 5472- **`setNativeProps`**: Directly modify native component properties without re-rendering. 5473 5474Optimize animations by using `shouldComponentUpdate`, `useNativeDriver`, or deferring work with `InteractionManager`. Monitor performance with the FPS Monitor tool. 5475 5476## React Native: Building Cross-Platform Apps 5477 5478React Native is an open-source framework designed for developing Android and iOS applications. It leverages React along with the native capabilities of each platform, allowing developers to use JavaScript to access platform-specific APIs and define UI components using React's component model. 5479 5480### Understanding Views in Mobile Development 5481 5482In both Android and iOS development, a **view** serves as the fundamental unit of user interface (UI). These are small rectangular elements on the screen that can display text, images, or respond to user interactions. Every visual element within an app, from lines of text to buttons, is considered a view. Some views can even contain other views, creating a hierarchical structure. 5483 5484### Native Components in React Native 5485 5486In traditional Android development, views are typically written using Kotlin or Java, while iOS developers use Swift or Objective-C. React Native bridges these platforms by allowing you to invoke native views through JavaScript via React components. At runtime, React Native translates these components into the corresponding native views for both Android and iOS. This ensures that React Native applications have a look, feel, and performance comparable to native apps. These platform-backed components are known as **Native Components**. 5487 5488React Native provides a set of essential, ready-to-use Native Components called **Core Components**, which serve as building blocks for app development. However, it's important to note that this documentation references an older API version and should be updated to reflect the New Architecture. 5489 5490Additionally, React Native allows developers to create custom Native Components tailored to their specific needs. There is also a vibrant ecosystem of community-contributed components available through resources like Native Directory. 5491 5492### Core Components Overview 5493 5494React Native includes numerous Core Components for various functionalities, from basic controls to activity indicators. These are documented in the API section. Key Core Components include: 5495 5496|React Native UI Component|Android View|iOS View|Web Analog|Description| 5497|-|-|-|-|-| 5498|`<View>`|`<ViewGroup>`|`<UIView>`|A non-scrolling `<div>`|Acts as a container supporting layout with flexbox, style, touch handling, and accessibility controls.| 5499|`<Text>`|`<TextView>`|`<UITextView>`|`<p>`|Displays, styles, nests text strings, and handles touch events.| 5500|`<Image>`|`<ImageView>`|`<UIImageView>`|`<img>`|Used for displaying various types of images.| 5501|`<ScrollView>`|`<ScrollView>`|`<UIScrollView>`|`<div>`|A generic scrolling container that can hold multiple components and views.| 5502|`<TextInput>`|`<EditText>`|`<UITextField>`|`<input type="text">`|Enables user text input.| 5503 5504In the following sections, you will learn how to combine these Core Components to understand React's workings better. 5505 5506### Introduction to React Component APIs 5507 5508React Native utilizes the same API structure as React components, so familiarity with React component APIs is essential for getting started. The next section provides a brief introduction or refresher on this topic. If you are already well-versed in React, feel free to proceed ahead. 5509 5510A diagram illustrates that React Native's Core Components are a subset of React Components included with React Native. 5511 5512## React Fundamentals 5513 5514React Native is built upon React, a widely-used open-source library for creating user interfaces with JavaScript. Understanding React can enhance your experience with React Native. This section introduces the fundamental concepts of React: 5515 5516- Components 5517- JSX 5518- Props 5519- State 5520 5521For more in-depth knowledge, consider exploring React’s official documentation. 5522 5523### Your First Component 5524 5525This introduction to React uses cats as examples: friendly creatures that need names and a cafe to work in. Here's how you create your first `Cat` component: 5526 5527Start by importing React and the `Text` Core Component from React Native using JavaScript’s `import` statement: 5528 5529```typescript 5530import React from "react" 5531import { Text } from "react-native" 5532``` 5533 5534Define your `Cat` component as a function: 5535 5536```typescript 5537const Cat = () => {} 5538``` 5539 5540Components act like blueprints, and what a function component returns is rendered as a **React element**. These elements describe the desired screen output. 5541 5542The `Cat` component will render a `<Text>` element: 5543 5544```typescript 5545const Cat = () => { 5546 return <Text>Hello, I am your cat!</Text>; 5547}; 5548``` 5549 5550Export your function component using JavaScript’s `export default` for use throughout your app: 5551 5552```typescript 5553const Cat = () => { 5554 return <Text>Hello, I am your cat!</Text>; 5555}; 5556 5557export default Cat; 5558``` 5559 5560> This is one of several ways to export a component. Depending on your app's file structure, you might need a different convention. A cheatsheet on JavaScript imports and exports can be helpful. 5561 5562The `return` statement uses JSX syntax: `<Text>Hello, I am your cat!</Text>`. 5563 5564### JSX 5565 5566React and React Native utilize **JSX**, allowing elements to be written inside JavaScript like so: `<Text>Hello, I am your cat!</Text>`. The React docs provide a comprehensive guide on JSX. Since JSX is JavaScript, variables can be embedded within it using curly braces `{}`. 5567 5568Any JavaScript expression works between curly braces, including function calls like `{getFullName("Rum", "Tum", "Tugger")}`: 5569 5570- TypeScript 5571- JavaScript 5572 5573Curly braces act as portals into JS functionality in your JSX! 5574 5575> Ensure `import React from 'react'` is at the top of your file for JSX to work. 5576 5577### Custom Components 5578 5579React Native’s Core Components can be nested within each other to create new components. These nestable, reusable components are central to React's approach. 5580 5581For instance, you can nest `Text` and `TextInput` inside a `View`, and React Native will render them together: 5582 5583##### Developer Notes 5584 5585- Android 5586- Web 5587 5588> If familiar with web development, `<View>` and `<Text>` might resemble HTML tags like `<div>` and `<p>`. On Android, views are typically placed within layouts such as `LinearLayout`, `FrameLayout`, or `RelativeLayout` to define children arrangement. React Native uses Flexbox for layout in `View`. 5589 5590Render the component multiple times using `<Cat>` without repeating code: 5591 5592Any component rendering other components is a **parent component**. Here, `Cafe` is the parent, and each `Cat` is a **child component**. 5593 5594You can customize each `<Cat>` with different props like `name`: 5595 5596- TypeScript 5597- JavaScript 5598 5599Most React Native Core Components are customizable via props. For example, `Image` uses a `source` prop to define its displayed image. 5600 5601Props such as `style`, which accepts a JS object of design properties, allow customization: 5602 5603> Notice the double curly braces `{{ }}` around `style`'s width and height in JSX. Curly braces `{}` reference JavaScript values in JSX, useful for passing non-string props like arrays or numbers: `<Cat food={["fish", "kibble"]} age={2} />`. JS objects also use curly braces: `{width: 200, height: 200}`, so pass a JS object in JSX with another pair of curly braces: `{{width: 200, height: 200}}`. 5604 5605Props and Core Components like `Text`, `Image`, and `View` enable many customizations. For interactivity, state is necessary. 5606 5607### State 5608 5609While props configure component rendering, **state** serves as a component’s personal data storage, useful for handling dynamic or user-interactive data. State provides components with memory! 5610 5611> Generally, use props to configure a component during render and state to track data expected to change over time. 5612 5613Consider a cat cafe scenario where two hungry cats await feeding. Their hunger status, stored as state, changes over time (unlike their names). Feeding the cats involves pressing buttons that update their state. 5614 5615Add state using React’s `useState` Hook, which allows adding state to function components: 5616 5617- TypeScript 5618- JavaScript 5619 5620Import `useState` from React: 5621 5622```typescript 5623import React, { useState } from "react" 5624``` 5625 5626Declare the component’s state by calling `useState` inside its function. Here, `useState` creates an `isHungry` state variable: 5627 5628```typescript 5629const Cat = (props: CatProps) => { 5630 const [isHungry, setIsHungry] = useState(true) 5631 // ... 5632} 5633``` 5634 5635> `useState` can track various data types: strings, numbers, Booleans, arrays, objects. For instance, track how many times a cat has been petted with `const [timesPetted, setTimesPetted] = useState(0)`! 5636 5637Calling `useState` does two things: 5638 5639- Creates a “state variable” with an initial value (e.g., `isHungry` initialized to `true`) 5640- Provides a function to update that state variable (`setIsHungry`) 5641 5642The pattern is `[<getter>, <setter>] = useState(<initialValue>)`. 5643 5644Add the `Button` Core Component with an `onPress` prop: 5645 5646```typescript 5647<Button 5648 onPress={() => { 5649 setIsHungry(false); 5650 }} 5651 //.. 5652/> 5653``` 5654 5655When pressed, `onPress` triggers `setIsHungry(false)`, updating `isHungry` to `false`. This change affects the `Button`’s `disabled` and `title` props: 5656 5657```typescript 5658<Button 5659 //.. 5660 disabled={!isHungry} 5661 title={isHungry ? 'Give me some food, please!' : 'Thank you!'} 5662/> 5663``` 5664 5665> Although `isHungry` is a const, it appears reassignable. When a state-setting function like `setIsHungry` is called, the component re-renders, and `useState` provides the updated value of `isHungry`. 5666 5667Finally, place your cats inside a `Cafe` component: 5668 5669```typescript 5670const Cafe = () => { 5671 return ( 5672 <> 5673 <Cat name="Munkustrap" /> 5674 <Cat name="Spot" /> 5675 </> 5676 ); 5677}; 5678``` 5679 5680> The `<>` and `</>` are JSX fragments. Adjacent JSX elements must be wrapped in an enclosing tag, which fragments allow without adding unnecessary wrapping elements like `View`. 5681 5682*** 5683 5684Having covered React and React Native’s Core Components, let's explore handling `<TextInput>` further. 5685 5686## Core Components and APIs 5687 5688React Native offers a variety of built-in core components that can be utilized directly within your application. These components are accessible via the navigation sidebar or the top menu for narrower screens. 5689 5690### Categories to Explore 5691 5692- **Basic Components** 5693- **User Interface** 5694- **List Views** 5695- **Android-specific** 5696- **iOS-specific** 5697- **Others** 5698 5699Beyond these built-in options, React Native supports a vast community of developers who contribute additional libraries. For specific functionalities not covered by the core components, refer to guides on finding external libraries. 5700 5701### Basic Components 5702 5703These foundational elements are commonly used across most applications. 5704 5705### User Interface 5706 5707This category includes universal user interface controls that render consistently across different platforms. 5708 5709### List Views 5710 5711For optimal performance with long lists of data, consider using list view components. Unlike `ScrollView`, these components only render items currently visible on the screen. 5712 5713### Android Components and APIs 5714 5715These components often serve as wrappers for standard Android classes. 5716 5717### iOS Components and APIs 5718 5719Similarly, many components in this category wrap commonly used UIKit classes from iOS. 5720 5721### Others 5722 5723This section includes additional components that might be beneficial for specific applications. For a comprehensive list of all available components and APIs, refer to the navigation sidebar or top menu on narrow screens. 5724 5725## Gesture Responder System 5726 5727The gesture responder system orchestrates the lifecycle of gestures within your application. A touch can traverse multiple phases as the app discerns the user's intent—whether it involves scrolling, sliding on a widget, or tapping—and this determination may evolve during the touch duration. Additionally, there can be concurrent touches. 5728 5729This system is essential for enabling components to negotiate touch interactions without requiring knowledge of their parent or child components. 5730 5731### Best Practices 5732 5733To enhance your app's usability and user experience, ensure every action possesses these attributes: 5734 5735- **Feedback/Highlighting**: Clearly indicate what element is responding to the user's touch and what will occur upon gesture release. 5736- **Cancelability**: Allow users to abort an ongoing action mid-touch by dragging their finger away. 5737 5738These features foster a comfortable interaction environment, encouraging experimentation without fear of errors. 5739 5740### TouchableHighlight and Touchable\* 5741 5742The responder system can be intricate. To simplify its use, we provide an abstract `Touchable` implementation for elements intended to be "tappable." This leverages the responder system, enabling you to configure tap interactions declaratively. Use `TouchableHighlight` in scenarios where buttons or links are typically employed on web platforms. 5743 5744### Responder Lifecycle 5745 5746A view can become a touch responder by implementing appropriate negotiation methods. There are two primary methods for querying if a view wishes to assume this role: 5747 5748- `View.props.onStartShouldSetResponder: evt => true`: Should the view become the responder at the start of a touch? 5749- `View.props.onMoveShouldSetResponder: evt => true`: For every touch move on the View when it is not yet the responder, does it wish to claim touch responsiveness? 5750 5751If the view returns true and attempts to become the responder, one of these events will occur: 5752 5753- `View.props.onResponderGrant: evt => {}`: The view now handles touch events. This is an opportunity to provide feedback and highlight interactions. 5754- `View.props.onResponderReject: evt => {}`: Another entity currently holds the responder status and will not relinquish it. 5755 5756If a view is responding, these handlers may be invoked: 5757 5758- `View.props.onResponderMove: evt => {}`: The user moves their finger. 5759- `View.props.onResponderRelease: evt => {}`: This event marks the end of the touch (i.e., "touchUp"). 5760- `View.props.onResponderTerminationRequest: evt => true`: Another entity seeks to become the responder. Should this view release it? Returning true permits release. 5761- `View.props.onResponderTerminate: evt => {}`: The responder status has been transferred from the View, possibly due to other views or system actions (e.g., control center/notification center on iOS). 5762 5763The event (`evt`) is a synthetic touch event with attributes such as: 5764 5765- `nativeEvent` 5766 - `changedTouches`: Array of all touch events that have changed since the last event. 5767 - `identifier`: The ID of the touch. 5768 - `locationX`: X position relative to the element. 5769 - `locationY`: Y position relative to the element. 5770 - `pageX`: X position relative to the root element. 5771 - `pageY`: Y position relative to the root element. 5772 - `target`: Node ID of the element receiving the touch event. 5773 - `timestamp`: Time identifier for the touch, useful for velocity calculations. 5774 - `touches`: Array of all current touches on the screen. 5775 5776#### Capture ShouldSet Handlers 5777 5778`onStartShouldSetResponder` and `onMoveShouldSetResponder` are invoked in a bubbling pattern, starting from the deepest node. This ensures that the deepest component becomes the responder when multiple Views return true for these handlers, which is generally desirable as it maintains control and button usability. 5779 5780However, if a parent view needs to ensure it becomes the responder, this can be managed using the capture phase. Before the responder system bubbles up from the deepest component, it executes a capture phase, invoking `on*ShouldSetResponderCapture`. Thus, if a parent View intends to prevent a child from becoming the responder at touch start, it should implement an `onStartShouldSetResponderCapture` handler that returns true. 5781 5782- `View.props.onStartShouldSetResponderCapture: evt => true` 5783- `View.props.onMoveShouldSetResponderCapture: evt => true` 5784 5785#### PanResponder 5786 5787For more advanced gesture interpretation, consider using PanResponder. 5788 5789## Security 5790 5791Security is often overlooked during app development. While completely impenetrable software remains elusive—similar to how bank vaults can still be breached—the likelihood of a security breach decreases with increased protective measures. Although ordinary locks are vulnerable, they offer more protection than basic alternatives like cabinet hooks. 5792 5793This guide covers best practices for securing sensitive information, authentication, network security, and tools to enhance app security. It serves as an extensive resource rather than a checklist, offering various options to bolster your app's defenses. 5794 5795### Storing Sensitive Information 5796 5797Avoid embedding sensitive API keys directly in your application code, as they can be exposed by inspecting the app bundle. Tools like `react-native-dotenv` and `react-native-config` are useful for managing environment-specific variables such as API endpoints but should not replace server-side environment variables that often contain secrets. 5798 5799For accessing resources requiring an API key or secret, consider implementing an orchestration layer between your app and the resource. This could involve using serverless functions (e.g., AWS Lambda or Google Cloud Functions) to forward requests with necessary credentials. Unlike client-side code, server-side secrets are not directly accessible by consumers. 5800 5801**Choose appropriate storage for persisted user data based on its sensitivity.** As apps evolve, saving data locally may be necessary for offline functionality, reducing network requests, or maintaining session tokens without repeated authentication. 5802 5803> **Persisted vs Unpersisted Data:** Persisted data is stored on the device's disk and remains accessible across app launches, but this increases vulnerability to unauthorized access. Unpersisted data never reaches the disk, eliminating such risks. 5804 5805#### Async Storage 5806 5807Async Storage is a community-maintained module for React Native that provides an asynchronous, unencrypted key-value store. Each app operates in its own sandbox environment, preventing cross-app data access. 5808 5809|**Use Async Storage When**|**Avoid Using Async Storage For**| 5810|-|-| 5811|Persisting non-sensitive data across app runs|Token storage| 5812|Persisting Redux state|Secrets| 5813|Persisting GraphQL state|| 5814|Storing global app-wide variables|| 5815 5816##### Developer Notes 5817 5818- Web: Async Storage is akin to Local Storage in web development. 5819 5820#### Secure Storage 5821 5822React Native lacks built-in secure data storage, but existing solutions are available for Android and iOS: 5823 5824- **iOS - Keychain Services:** Ideal for securely storing small amounts of sensitive information like certificates, tokens, and passwords. 5825 5826- **Android - Secure Shared Preferences:** While not encrypted by default, Encrypted Shared Preferences provide automatic encryption for keys and values. 5827 5828- **Android - Keystore:** This system stores cryptographic keys in a secure container to prevent extraction from the device. 5829 5830To utilize iOS Keychain Services or Android Secure Shared Preferences, you can either develop a custom bridge or use libraries that offer unified APIs. Consider using: 5831 5832- `expo-secure-store` 5833- `react-native-keychain` 5834 5835> **Caution:** Avoid unintentionally storing or exposing sensitive information, such as saving sensitive form data in Redux state and persisting it with Async Storage, or sending user tokens to monitoring services like Sentry or Crashlytics. 5836 5837### Authentication and Deep Linking 5838 5839Mobile apps face a unique vulnerability through deep linking—a method of directing data directly to an app from external sources. A typical deep link format is `app://`, where `app` represents your app scheme. For instance, in an e-commerce app, `app://products/1` could open the product detail page for item 1. 5840 5841Deep links resemble URLs but lack security measures, as there's no centralized registration system for URL schemes. Malicious apps can hijack deep links by registering the same scheme and accessing the data within them. Avoid sending sensitive information through deep links to mitigate this risk. 5842 5843On Android, users are prompted with a Disambiguation dialog when multiple apps can handle a link. iOS previously made automatic choices but now uses universal links for secure content access starting from iOS 11. 5844 5845#### OAuth2 and Redirects 5846 5847OAuth2 is a widely-used authentication protocol known for its security features. It involves third-party authentication, where the user grants permission to an application via a verification code that can be exchanged for a JWT (JSON Web Token). 5848 5849While redirects are secure on the web due to unique URLs, mobile apps lack this guarantee. To enhance security, PKCE (Proof of Key Code Exchange) is used. PKCE involves generating a `code_verifier` and its SHA 256 hash (`code_challenge`). The client sends both during authentication, ensuring that only the initiating app can exchange the verification code for a JWT. 5850 5851Consider using `react-native-app-auth`, which supports OAuth2 providers and PKCE if supported by your Identity Provider. 5852 5853### Network Security 5854 5855Always use SSL encryption for APIs to protect data in transit. Secure endpoints begin with `https://` instead of `http://`. 5856 5857#### SSL Pinning 5858 5859SSL pinning enhances security by embedding trusted certificates within the client app, ensuring that only requests signed with these certificates are accepted. This prevents man-in-the-middle attacks where attackers install malicious root CA certificates on a user's device. 5860 5861> Be aware of certificate expiry when using SSL pinning. Certificates typically expire every 1-2 years and must be updated in both the app and server to maintain functionality. 5862 5863### Summary 5864 5865While no security measure is foolproof, proactive efforts can significantly reduce breach risks. Security investments should align with data sensitivity, user base size, and potential damage from unauthorized access. Prioritize protecting information that isn't requested unnecessarily. 5866 5867## Handling Text Input 5868 5869`TextInput` is a Core Component designed to facilitate text entry by users. It includes two key properties: `onChangeText`, which triggers a function every time the text changes, and `onSubmitEditing`, which activates a function when the text is submitted. 5870 5871Consider an example where user input is translated into another language. In this hypothetical scenario, each word translates to 🍕. Thus, "Hello there Bob" becomes "🍕 🍕 🍕". Here, we manage `text` within the component's state due to its dynamic nature. 5872 5873Text inputs offer various functionalities beyond basic text entry. For instance, you can validate input in real-time as users type. To explore more comprehensive examples, refer to React documentation on controlled components or the reference materials for `TextInput`. 5874 5875Text input represents one method of user interaction with an application. Next, we will examine another form of input and learn how to manage touch interactions. 5876 5877## Using a ScrollView 5878 5879A `ScrollView` is a versatile scrolling container capable of holding multiple components and views. It supports both vertical and horizontal scrolling by setting the `horizontal` property. 5880 5881This example demonstrates creating a vertical `ScrollView` that mixes images and text. 5882 5883To enable paging through views using swipe gestures, use the `pagingEnabled` prop. On Android, swiping horizontally between views can be implemented with the ViewPager component. 5884 5885On iOS, a `ScrollView` containing a single item allows users to zoom content by setting the `maximumZoomScale` and `minimumZoomScale` props, enabling pinch-to-zoom functionality. 5886 5887A `ScrollView` is ideal for displaying a small number of limited-size items. All elements within a `ScrollView` are rendered, even if not visible on screen. For long lists that exceed screen size, consider using a `FlatList`. Next, we'll explore list views. 5888 5889```typescript 5890import React from 'react'; 5891import { ScrollView, Image, Text, View } from 'react-native'; 5892 5893const MyScrollView = () => { 5894 return ( 5895 <ScrollView pagingEnabled={true}> 5896 <View> 5897 <Image source={{ uri: 'https://example.com/image1.jpg' }} /> 5898 <Text>Some text here</Text> 5899 </View> 5900 <View> 5901 <Image source={{ uri: 'https://example.com/image2.jpg' }} /> 5902 <Text>More text here</Text> 5903 </View> 5904 </ScrollView> 5905 ); 5906}; 5907 5908export default MyScrollView; 5909``` 5910 5911## Using List Views 5912 5913React Native offers several components designed for presenting lists of data efficiently. The primary choices are `FlatList` and `SectionList`. 5914 5915### FlatList Component 5916 5917The `FlatList` component is ideal for displaying a scrolling list of items that share a similar structure but may change over time. It's particularly effective for long lists where the number of items can vary, as it only renders elements currently visible on the screen, unlike the more generic `ScrollView`, which renders all elements at once. 5918 5919#### Key Props 5920 5921- **data**: This prop provides the source information for the list. 5922- **renderItem**: This function takes an item from the data source and returns a formatted component to render. 5923 5924#### Example Usage 5925 5926Below is an example of how to create a basic `FlatList` using hardcoded data. Each item in the `data` prop is rendered as a `Text` component within the `FlatListBasics` component: 5927 5928```typescript 5929import React from 'react'; 5930import { FlatList, Text, View } from 'react-native'; 5931 5932const DATA = [ 5933 { id: '1', title: 'First Item' }, 5934 { id: '2', title: 'Second Item' }, 5935 // Add more items as needed 5936]; 5937 5938const renderItem = ({ item }) => ( 5939 <View> 5940 <Text>{item.title}</Text> 5941 </View> 5942); 5943 5944const FlatListBasics = () => ( 5945 <FlatList 5946 data={DATA} 5947 renderItem={renderItem} 5948 /> 5949); 5950``` 5951 5952### SectionList Component 5953 5954For displaying data divided into logical sections, possibly with section headers (similar to `UITableView` on iOS), the `SectionList` component is more appropriate. 5955 5956#### Common Use Case 5957 5958A frequent use case for list views in React Native involves rendering data fetched from a server. To achieve this, you'll need to understand networking within React Native. 5959 5960By leveraging these components, developers can efficiently manage and display lists of data in their applications. 5961 5962## Platform-Specific Code 5963 5964When developing a cross-platform application, maximizing code reuse is ideal. However, there are instances where platform-specific implementations are necessary, such as creating distinct visual components for Android and iOS. 5965 5966React Native offers two methods to organize and separate your code by platform: 5967 5968- Using the `Platform` module. 5969- Utilizing platform-specific file extensions. 5970 5971Certain component properties may be exclusive to a specific platform. These props are annotated with `@platform` and displayed with a badge on the website. 5972 5973### Platform Module 5974 5975The `Platform` module in React Native detects the current operating system, allowing you to implement platform-specific code. This approach is suitable when only minor parts of a component require differentiation. 5976 5977```typescript 5978import { Platform, StyleSheet } from "react-native" 5979 5980const styles = StyleSheet.create({ 5981 height: Platform.OS === "ios" ? 200 : 100, 5982}) 5983``` 5984 5985`Platform.OS` returns `ios` for iOS and `android` for Android. 5986 5987The `Platform.select` method can be used to choose values based on the platform. It accepts an object with keys like `'ios' | 'android' | 'native' | 'default'`, returning the most appropriate value for the current platform. If running on a phone, it prioritizes `ios` and `android`. If neither is specified, it uses the `native` key, followed by the `default` key. 5988 5989```typescript 5990import { Platform, StyleSheet } from "react-native" 5991 5992const styles = StyleSheet.create({ 5993 container: { 5994 flex: 1, 5995 ...Platform.select({ 5996 ios: { 5997 backgroundColor: "red", 5998 }, 5999 android: { 6000 backgroundColor: "green", 6001 }, 6002 default: { 6003 // other platforms, such as web 6004 backgroundColor: "blue", 6005 }, 6006 }), 6007 }, 6008}) 6009``` 6010 6011This results in a container with `flex: 1` on all platforms, a red background on iOS, green on Android, and blue on others. 6012 6013Since it accepts any value, you can also use `Platform.select` to return platform-specific components: 6014 6015```typescript 6016const Component = Platform.select({ 6017 ios: () => require('ComponentIOS'), 6018 android: () => require('ComponentAndroid'), 6019})(); 6020 6021<Component />; 6022``` 6023 6024```typescript 6025const Component = Platform.select({ 6026 native: () => require('ComponentForNative'), 6027 default: () => require('ComponentForWeb'), 6028})(); 6029 6030<Component />; 6031``` 6032 6033#### Detecting the Android Version 6034 6035On Android, `Platform` can detect the API version: 6036 6037```typescript 6038import { Platform } from "react-native" 6039 6040if (Platform.Version === 25) { 6041 console.log("Running on Nougat!") 6042} 6043``` 6044 6045**Note**: `Version` refers to the Android API level, not the OS version. Refer to the Android Version History for details. 6046 6047#### Detecting the iOS Version 6048 6049On iOS, `Version` is derived from `-[UIDevice systemVersion]`, a string like "10.3". To detect the major iOS version: 6050 6051```typescript 6052import { Platform } from "react-native" 6053 6054const majorVersionIOS = parseInt(Platform.Version, 10) 6055if (majorVersionIOS <= 9) { 6056 console.log("Work around a change in behavior") 6057} 6058``` 6059 6060### Platform-Specific Extensions 6061 6062For more complex platform-specific code, consider splitting it into separate files. React Native detects `.ios.` or `.android.` extensions and loads the appropriate file based on the running platform. 6063 6064Example: 6065 6066```shell 6067BigButton.ios.js 6068BigButton.android.js 6069``` 6070 6071Import as follows: 6072 6073```typescript 6074import BigButton from "./BigButton" 6075``` 6076 6077React Native automatically selects the correct file for the current platform. 6078 6079### Native-Specific Extensions 6080 6081Use `.native.js` extensions when a module is shared between NodeJS/Web and React Native without Android/iOS differences. This is useful for projects sharing code among React Native and ReactJS. 6082 6083Example: 6084 6085```shell 6086Container.js # picked up by Web bundlers like webpack or Rollup 6087Container.native.js # picked up by the React Native bundler (Metro) for both Android and iOS 6088``` 6089 6090Import without `.native` extension: 6091 6092```typescript 6093import Container from "./Container" 6094``` 6095 6096**Pro tip:** Configure your Web bundler to ignore `.native.js` extensions to avoid including unused code in production, reducing bundle size. 6097 6098## Accessibility 6099 6100#### Overview of Accessibility Features in React Native 6101 6102React Native provides several accessibility features that help developers create applications usable by everyone, including people with disabilities. These features are crucial for ensuring inclusivity and compliance with accessibility standards like WCAG (Web Content Accessibility Guidelines). 6103 6104##### Key Accessibility Properties 6105 61061. **`accessibilityRole`**: Defines the role of a component, such as button, link, or image. This helps assistive technologies understand how to interact with the element. 6107 61081. **`accessibilityLabel`**: Provides a text label for screen readers, describing what the element does or represents. 6109 61101. **`accessibilityHint`**: Offers additional information about an element's action when focused by a screen reader. 6111 61121. **`accessible`**: Determines if an element is accessible to assistive technologies. 6113 61141. **`accessibilityState`**: Describes the state of an element, such as selected or checked. 6115 61161. **`accessibilityActions`**: Defines actions that can be performed on an element, like activating a button or adjusting a slider. 6117 61181. **`onAccessibilityAction`**: Handles accessibility action requests, allowing custom behavior when an action is triggered. 6119 61201. **`role`**: Similar to `accessibilityRole`, it communicates the purpose of a component and takes precedence over `accessibilityRole`. 6121 6122##### Accessibility Actions 6123 6124Accessibility actions enable assistive technologies to programmatically invoke actions on components. To support these: 6125 6126- Define supported actions using the `accessibilityActions` property. 6127- Implement an `onAccessibilityAction` function to handle action requests. 6128 6129Standard actions include: 6130 6131- `'activate'`: Activates a component. 6132- `'increment'` and `'decrement'`: Adjusts adjustable components. 6133- `'magicTap'` (iOS): Double-tap with two fingers while focused. 6134- `'escape'` (iOS): Performs a scrub gesture to exit focus. 6135- `'longpress'` (Android): Double-tap and hold. 6136 6137##### Checking Screen Reader Status 6138 6139The `AccessibilityInfo` API allows developers to check if a screen reader is active, enabling dynamic adjustments based on the user's needs. 6140 6141##### Sending Accessibility Events (Android) 6142 6143React Native's `UIManager` module can trigger accessibility events like focusing or clicking on a view. This is useful for custom views that need to announce their presence or state changes. 6144 6145```javascript 6146import { Platform, UIManager, findNodeHandle } from "react-native" 6147 6148if (Platform.OS === "android") { 6149 UIManager.sendAccessibilityEvent( 6150 findNodeHandle(this), 6151 UIManager.AccessibilityEventTypes.typeViewFocused 6152 ) 6153} 6154``` 6155 6156##### Testing Accessibility 6157 6158- **TalkBack (Android)**: Enable via Settings > Accessibility. Use the volume key shortcut or command line to toggle. 6159 6160- **VoiceOver (iOS/iPadOS)**: Enable through Settings > General > Accessibility. Use the Home button triple-click or Accessibility Shortcut. 6161 6162Testing on actual devices is recommended for accurate results, though tools like Xcode's Accessibility Inspector can simulate VoiceOver on macOS. 6163 6164##### Additional Resources 6165 6166For more detailed guidance, refer to resources like "Making React Native Apps Accessible," which provides comprehensive strategies and best practices for accessibility in React Native applications. 6167 6168## Debugging Basics 6169 6170> Note: Debugging features, such as the Dev Menu, LogBox, and React Native DevTools are disabled in release (production) builds. 6171 6172### Opening the Dev Menu 6173 6174React Native provides an in-app developer menu that offers access to debugging features. You can open this menu by shaking your device or using keyboard shortcuts: 6175 6176- **iOS Simulator**: `Ctrl` + `Cmd ⌘` + `Z` (or Device > Shake) 6177- **Android Emulators**: 6178 - macOS: `Cmd ⌘` + `M` 6179 - Windows/Linux: `Ctrl` + `M` 6180 6181Alternative for Android: Use the command `adb shell input keyevent 82`. 6182 6183### Opening DevTools 6184 6185React Native DevTools is an integrated debugger for React Native, allowing you to inspect and understand your JavaScript code execution. To open DevTools: 6186 6187- Select "Open DevTools" in the Dev Menu. 6188- Press `j` from the CLI (`npx react-native start`). 6189 6190Upon first launch, DevTools will display a welcome panel with an open console drawer for viewing logs and interacting with the JavaScript runtime. You can navigate to other panels like the React Components Inspector and Profiler from the top of the window. 6191 6192React Native DevTools is built on a dedicated debugging architecture within React Native, using a customized version of the Chrome DevTools frontend. This integration provides familiar, browser-aligned debugging features designed for reliability. 6193 6194> Note: React Native DevTools requires the Hermes engine and either Google Chrome or Microsoft Edge installed. 6195 6196#### Flipper and Alternative Debugging Tools 6197 6198React Native DevTools replaces older tools like Flipper, Experimental Debugger, and the Hermes debugger (Chrome). For older versions of React Native, refer to version-specific documentation. 6199 6200For apps using JavaScriptCore instead of Hermes, Direct JSC Debugging is available (see Other Debugging Methods). 6201 6202React Native DevTools focuses on debugging React app concerns and does not replace native tools. To inspect underlying platform layers, use Xcode or Android Studio's debugging tools. 6203 6204Other useful links: 6205 6206- [Why you don’t need Flipper in your React Native app … and how to get by without it](#) 6207 6208### LogBox 6209 6210LogBox is an in-app tool that displays warnings or errors logged by your app. 6211 6212#### Fatal Errors 6213 6214When a fatal error, such as a JavaScript syntax error, occurs, LogBox opens at the error's location. In this state, LogBox cannot be dismissed because code execution is halted. It will automatically dismiss once the syntax error is fixed via Fast Refresh or manual reload. 6215 6216#### Console Errors and Warnings 6217 6218Console errors and warnings appear as on-screen notifications with red or yellow badges: 6219 6220- **Errors**: Display a notification count. Tap to view expanded details and paginate through logs. 6221- **Warnings**: Show a notification banner without details, prompting you to open React Native DevTools. 6222 6223When React Native DevTools is active, all non-fatal errors are hidden from LogBox. It's recommended to use the Console panel within React Native DevTools as it provides comprehensive log information. 6224 6225### Performance Monitor 6226 6227On Android and iOS, an in-app performance overlay can be toggled during development by selecting **"Perf Monitor"** in the Dev Menu. Learn more about this feature [here](#). 6228 6229> Info: The Performance Monitor is a guide for in-app use. For accurate performance measurements, investigate native tooling under Android Studio and Xcode. 6230 6231## React Native DevTools 6232 6233React Native DevTools offers a modern debugging experience specifically designed for React Native applications. Built from scratch, it aims to provide deeper integration and reliability compared to previous methods. 6234 6235While React Native DevTools focuses on debugging React app concerns, it does not replace native tools. For inspecting the underlying platform layers of React Native (e.g., when developing a Native Module), use the debugging tools available in Android Studio and Xcode (see Debugging Native Code). 6236 6237### Core Features 6238 6239React Native DevTools is based on the Chrome DevTools frontend, making its features familiar to those with web development experience. For comprehensive guides and video resources, refer to the Chrome DevTools documentation. 6240 6241#### Console 6242 6243The Console panel allows you to view and filter messages, evaluate JavaScript, inspect object properties, among other functionalities. 6244 6245Console features reference | [Chrome DevTools](https://developer.chrome.com/docs/devtools/console/) 6246 6247##### Useful Tips 6248 6249- Use the filter box or adjust log levels if your app generates many logs. 6250- Monitor values over time with Live Expressions. 6251- Preserve messages across reloads using Preserve Logs. 6252- Clear the console view with `Ctrl` + `L`. 6253 6254#### Sources & Breakpoints 6255 6256The Sources panel lets you view source files and set breakpoints. Breakpoints pause your app at specific lines of code, enabling inspection of the live state and step-by-step execution. 6257 6258Pause your code with breakpoints | [Chrome DevTools](https://developer.chrome.com/docs/devtools/javascript/breakpoints/) 6259 6260##### Mini-Guide 6261 6262Breakpoints are essential for debugging: 6263 62641. Navigate to a source file using the sidebar or `Cmd ⌘`+`P` / `Ctrl`+`P`. 62651. Click in the line number column next to code to add a breakpoint. 62661. Use navigation controls at the top right to step through code when paused. 6267 6268##### Useful Tips 6269 6270- A "Paused in Debugger" overlay appears when your app is paused; tap it to resume. 6271- Inspect the current scope and call stack, and set watch expressions using the panels on the right-hand side when paused. 6272- Insert a `debugger;` statement in your text editor to quickly set a breakpoint via Fast Refresh. 6273- Explore different types of breakpoints, such as Conditional Breakpoints and Logpoints. 6274 6275#### Memory 6276 6277The Memory panel allows you to take heap snapshots and monitor JavaScript memory usage over time. 6278 6279Record heap snapshots | [Chrome DevTools](https://developer.chrome.com/docs/devtools/memory-problems/) 6280 6281##### Useful Tips 6282 6283- Use `Cmd ⌘`+`F` / `Ctrl`+`F` to filter for specific objects in the heap. 6284- Allocation timeline reports can help identify memory leaks by showing usage over time as a graph. 6285 6286### React DevTools Features 6287 6288The integrated Components and Profiler panels include all features of the React DevTools browser extension, working seamlessly within React Native DevTools. 6289 6290#### React Components 6291 6292The React Components panel lets you inspect and update the rendered React component tree. 6293 6294- Highlight elements on device by hovering or selecting them in DevTools. 6295- Locate an element in DevTools using the "Select element" button, then tap any app element. 6296 6297##### Useful Tips 6298 6299- View and modify props and state at runtime using the right-hand panel. 6300- Components optimized with React Compiler are marked with a "Memo ✨" badge. 6301 6302##### Protip: Highlight Re-renders 6303 6304Highlighting component re-renders can help identify performance issues. Enable this feature by clicking the View Settings (`⚙︎`) icon and checking "Highlight updates when components render". 6305 6306#### React Profiler 6307 6308The React Profiler panel records performance profiles to analyze component render timings and React commits. 6309 6310For more information, refer to the original 2018 guide (note that some parts may be outdated). 6311 6312### Reconnecting DevTools 6313 6314DevTools might disconnect from the target device due to: 6315 6316- App closure. 6317- App rebuild (new native build installation). 6318- Native app crash. 6319- Metro dev server shutdown. 6320- Physical device disconnection. 6321 6322Upon disconnection, a dialog with "Debugging connection was closed" will appear. You can either dismiss it or select "Reconnect DevTools" after addressing the disconnection cause. 6323 6324## Debugging Native Code 6325 6326### Projects with Native Code Only 6327 6328This section is relevant for projects that expose native code. If you are using the managed Expo workflow, refer to the prebuild guide for API usage. 6329 6330#### Accessing Logs 6331 6332To view native logs for iOS or Android apps while they are running, use these terminal commands: 6333 6334- **Android:** 6335 6336 ```shell 6337 npx react-native log-android 6338 ``` 6339 6340- **iOS:** 6341 ```shell 6342 npx react-native log-ios 6343 ``` 6344 6345Alternatively, you can access these logs through the following methods: 6346 6347- For iOS Simulator: Navigate to `Debug > Open System Log…`. 6348- For Android devices or emulators: Run the command in a terminal: 6349 ```shell 6350 adb logcat "*:S" ReactNative:V ReactNativeJS:V 6351 ``` 6352 6353#### Debugging in a Native IDE 6354 6355When working with native code, such as writing native modules, you can launch the app from Android Studio or Xcode to utilize native debugging features like setting breakpoints. 6356 6357You can also run your application using the React Native CLI and attach the native debugger of the IDE (Android Studio or Xcode) to the process. 6358 6359##### Android Studio 6360 6361To attach a debugger in Android Studio: 6362 63631. Go to the "Run" option on the menu bar. 63641. Click on "Attach to Process..." 63651. Select the running React Native app from the list. 6366 6367##### Xcode 6368 6369To attach a debugger in Xcode: 6370 63711. Click on "Debug" in the top menu bar. 63721. Select the "Attach to process" option. 63731. Choose your application from the list of "Likely Targets". 6374 6375## Debugging Release Builds 6376 6377### Symbolicating a Stack Trace 6378 6379When a React Native app encounters an unhandled exception in a release build, the output can be obfuscated and difficult to interpret. For example: 6380 6381``` 638207-15 10:58:25.820 18979 18998 E AndroidRuntime: FATAL EXCEPTION: mqt_native_modules 638307-15 10:58:25.820 18979 18998 E AndroidRuntime: Process: com.awesomeproject, PID: 18979 638407-15 10:58:25.820 18979 18998 E AndroidRuntime: com.facebook.react.common.JavascriptException: Failed, js engine: hermes, stack: 638507-15 10:58:25.820 18979 18998 E AndroidRuntime: p@1:132161 638607-15 10:58:25.820 18979 18998 E AndroidRuntime: p@1:132084 638707-15 10:58:25.820 18979 18998 E AndroidRuntime: f@1:131854 638807-15 10:58:25.820 18979 18998 E AndroidRuntime: anonymous@1:131119 6389``` 6390 6391In this stack trace, entries like `p@1:132161` are minified function names and bytecode offsets. To debug these calls effectively, we need to translate them into file, line, and function name format (e.g., `AwesomeProject/App.js:54:initializeMap`). This process is known as **symbolication**. 6392 6393To symbolicate minified function names and bytecode, use the stack trace along with a generated source map in `metro-symbolicate`. 6394 6395#### Enabling Source Maps 6396 6397Source maps are essential for symbolication. Ensure that they are enabled within the build configuration for your target platform: 6398 6399- **Android**: Source maps are enabled by default. 6400 6401 To ensure source map generation, include the following `hermesFlags` in `android/app/build.gradle`: 6402 6403 ```groovy 6404 react { 6405 hermesFlags = ["-O", "-output-source-map"] 6406 } 6407 ``` 6408 6409 If configured correctly, you should see the source map output location during Metro build output: 6410 6411 ``` 6412 Writing bundle output to:, android/app/build/generated/assets/react/release/index.android.bundle 6413 Writing sourcemap output to:, android/app/build/intermediates/sourcemaps/react/release/index.android.bundle.packager.map 6414 ``` 6415 6416- **iOS**: Source maps are disabled by default. Follow these steps to enable them: 6417 6418 To generate source maps, open Xcode and edit the build phase "Bundle React Native code and images". Add a `SOURCEMAP_FILE` entry with the desired output path above other exports: 6419 6420 ```diff 6421 + SOURCEMAP_FILE="$(pwd)/../main.jsbundle.map"; 6422 WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh" 6423 ``` 6424 6425 If configured correctly, you should see the source map output location during Metro build output: 6426 6427 ``` 6428 Writing bundle output to:, Build/Intermediates.noindex/ArchiveIntermediates/application/BuildProductsPath/Release-iphoneos/main.jsbundle 6429 Writing sourcemap output to:, Build/Intermediates.noindex/ArchiveIntermediates/application/BuildProductsPath/Release-iphoneos/main.jsbundle.map 6430 ``` 6431 6432#### Using `metro-symbolicate` 6433 6434With source maps generated, you can now translate stack traces using `metro-symbolicate`: 6435 6436```shell 6437# Print usage instructions 6438npx metro-symbolicate 6439 6440# From a file containing the stack trace 6441npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map < stacktrace.txt 6442 6443# From adb logcat (Android) 6444adb logcat -d | npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map 6445``` 6446 6447#### Notes on Source Maps 6448 6449- Multiple source maps may be generated during the build process. Ensure you use the one shown in the examples. 6450- The source map must correspond to the exact commit of the crashing app, as small changes in source code can lead to significant differences in offsets. 6451- If `metro-symbolicate` exits immediately with success, ensure that input is from a pipe or redirection rather than directly from a terminal. 6452 6453## Other Debugging Methods 6454 6455This section discusses legacy methods for JavaScript debugging in React Native or Expo apps. For new projects, it's recommended to use React Native DevTools. 6456 6457### Safari Developer Tools (Direct JSC Debugging) 6458 6459Safari can be used to debug the iOS version of your app when using JavaScriptCore (JSC) as the runtime environment. 6460 64611. **Physical Devices Only**: Open the Settings app on your device and navigate to `Safari > Advanced`. Ensure that "Web Inspector" is enabled. 64621. On a Mac, open Safari and enable the Develop menu by going to `Safari > Preferences...`, selecting the `Advanced` tab, and checking "Show develop menu in menu bar". 64631. Under the Develop menu, select your device and choose the "JSContext" option from the submenu. This action opens Safari's Web Inspector, which includes Console and Sources panels similar to Chrome DevTools. 6464 6465> **Tip**: Source maps might not be enabled by default. You can follow a guide or video to enable them and set breakpoints in the source code. 6466 6467> **Tip**: Each app reload creates a new JSContext. Enabling "Automatically Show Web Inspectors for JSContexts" eliminates the need to manually select the latest JSContext. 6468 6469### Remote JavaScript Debugging (Removed) 6470 6471*Note: This feature has been removed.* 6472 6473*** 6474 6475**Previous:** Debugging Release Builds\ 6476**Next:** Testing 6477 6478- Safari Developer Tools (Direct JSC Debugging) 6479- Remote JavaScript Debugging (Removed) 6480 6481## Testing 6482 6483As your codebase grows, small errors can lead to significant failures. Bugs negatively impact user experience and business outcomes. To prevent fragile programming, testing is essential before releasing software. 6484 6485### Why Test? 6486 6487Humans make mistakes, and testing helps uncover these errors, ensuring that your code functions as intended. Testing also verifies future functionality when new features are added or existing ones refactored. Writing a failing test to expose bugs can be an effective way to fix them. Tests serve as documentation for team members unfamiliar with the codebase, reducing time spent on manual QA. 6488 6489### Static Analysis 6490 6491Static analysis tools check your code for errors without executing it. These include: 6492 6493- **Linters**: Analyze code to catch common errors and enforce style guides. 6494- **Type checking**: Ensures that function arguments match expected types. 6495 6496React Native includes ESLint for linting and TypeScript for type checking by default. 6497 6498### Writing Testable Code 6499 6500Testable code is akin to testing individual aircraft parts before assembly. Write modular, small code units rather than a single large file. Separate business logic from UI components to facilitate independent testing of each part. 6501 6502### Writing Tests 6503 6504React Native uses Jest as the default testing framework. It includes presets tailored for this environment, allowing you to write various tests without extensive configuration. 6505 6506#### Structuring Tests 6507 6508Tests should be concise and focused on specific functionalities. Use descriptive test names and assertions to verify expected outcomes. For example: 6509 6510```javascript 6511test("given empty GroceryShoppingList, user can add an item to it", () => { 6512 const { getByPlaceholderText, getByText, getAllByText } = render( 6513 <GroceryShoppingList /> 6514 ) 6515 6516 fireEvent.changeText(getByPlaceholderText("Enter grocery item"), "banana") 6517 fireEvent.press(getByText("Add the item to list")) 6518 6519 const bananaElements = getAllByText("banana") 6520 expect(bananaElements).toHaveLength(1) // Expect 'banana' to be on the list 6521}) 6522``` 6523 6524#### Testing User Interactions 6525 6526Focus on user interactions rather than internal component states. Use libraries like React Native Testing Library to simulate user actions and verify outcomes. 6527 6528#### Testing Rendered Output 6529 6530Snapshot testing captures a textual representation of your component's render output. It helps detect unexpected changes but requires careful management to avoid false positives or negatives. 6531 6532### End-to-End Tests 6533 6534E2E tests validate app functionality from the user perspective on actual devices or simulators/emulators. They provide high confidence in app performance but are more time-consuming and prone to flakiness compared to other test types. 6535 6536Focus E2E testing on critical app areas like authentication, core functionalities, and payments. Use faster JS tests for less critical parts. 6537 6538### Summary 6539 6540Testing is crucial for maintaining code quality and ensuring reliable software delivery. Various testing methods offer different benefits and trade-offs. Start incorporating tests into your React Native projects to enhance confidence in your app's performance. 6541 6542#### Links 6543 6544- [React Testing Overview](#) 6545- [React Native Testing Library](#) 6546- [Jest Docs](#) 6547- [Detox](#) 6548- [Appium](#) 6549- [Maestro](#) 6550 6551*This guide was authored by Vojtech Novak.* 6552 6553## Performance Overview 6554 6555React Native offers a compelling advantage over WebView-based tools by aiming for smooth performance, specifically targeting 60 frames per second (FPS) with a native look and feel. While React Native handles many optimizations automatically, there are areas where manual intervention is necessary to achieve optimal performance. This guide provides insights into troubleshooting performance issues and addressing common problems. 6556 6557### Understanding Frames 6558 6559The concept of "frames" originates from the early days of cinema when movies were referred to as "moving pictures." Realistic motion in video or UI is achieved by rapidly displaying static images at a consistent rate. Each image is called a frame, and the number of frames displayed per second affects how smooth the motion appears. 6560 6561iOS devices aim for 60 FPS, allowing approximately 16.67 milliseconds (ms) to generate each frame. If this time limit is exceeded, a "frame drop" occurs, making the UI seem unresponsive. To observe frame rates in your app, open the Dev Menu and toggle `Show Perf Monitor`. You'll notice two different frame rates: 6562 6563#### JS Frame Rate (JavaScript Thread) 6564 6565In most React Native applications, business logic runs on the JavaScript thread, which handles tasks like API calls and touch events. Updates to native views are batched and sent to the native side at each event loop iteration before the frame deadline. If the JavaScript thread is unresponsive for a frame, it's considered dropped. For instance, calling `this.setState` in a complex component might take 200ms, resulting in 12 frames being dropped and causing animations to freeze. 6566 6567Common issues include: 6568 6569- **Navigator Transitions**: Rendering components for new scenes can cause jank as transitions are controlled by the JavaScript thread. 6570- **Touch Responsiveness**: Delays in processing touch events due to a busy JavaScript thread can affect components like `TouchableOpacity`. 6571 6572#### UI Frame Rate (Main Thread) 6573 6574Performance differences between `NavigatorIOS` and `Navigator` arise because `NavigatorIOS` handles animations on the main thread, avoiding interruptions from JavaScript frame drops. Similarly, scrolling through a `ScrollView` remains smooth even if the JavaScript thread is busy. 6575 6576### Common Performance Issues 6577 6578#### Development Mode (`dev=true`) 6579 6580JavaScript performance degrades in development mode due to additional runtime work for warnings and error messages. Always test performance in release builds. 6581 6582#### Using `console.log` 6583 6584In bundled apps, `console.log` statements can bottleneck the JavaScript thread. Remove them before bundling using a Babel plugin: 6585 6586```json 6587{ 6588 "env": { 6589 "production": { 6590 "plugins": ["transform-remove-console"] 6591 } 6592 } 6593} 6594``` 6595 6596Install with `npm i babel-plugin-transform-remove-console --save-dev`. 6597 6598#### Slow ListView Rendering 6599 6600Switch to `FlatList` or `SectionList` for better performance, especially with large lists. Implement `getItemLayout` to optimize rendering speed. 6601 6602#### Re-rendering Unchanged Views 6603 6604For `ListView`, use a `rowHasChanged` function to minimize unnecessary re-renders. For components, implement `shouldComponentUpdate` or use `PureComponent` with immutable data structures for efficient updates. 6605 6606#### High JavaScript Thread Workload 6607 6608Slow transitions often result from excessive work on the JavaScript thread. Use InteractionManager or LayoutAnimation to manage workload during animations. LayoutAnimation leverages Core Animation and is unaffected by frame drops. 6609 6610#### UI Frame Drops During View Movement 6611 6612Alpha compositing can cause FPS drops when moving views with transparent backgrounds. Enable `shouldRasterizeIOS` or `renderToHardwareTextureAndroid` for improvement, but monitor memory usage. 6613 6614#### Image Size Animations 6615 6616Animating image size on iOS involves re-cropping and scaling, which is costly. Use the `transform: [{scale}]` style property instead. 6617 6618#### Unresponsive TouchableX Views 6619 6620If actions in `onPress` cause frame drops, wrap them in `requestAnimationFrame`: 6621 6622```typescript 6623handleOnPress() { 6624 requestAnimationFrame(() => { 6625 this.doExpensiveAction(); 6626 }); 6627} 6628``` 6629 6630#### Slow Navigator Transitions 6631 6632Navigator animations are controlled by the JavaScript thread. Offloading animations to the native thread can improve performance. React Navigation addresses this by using native components and the `Animated` library for smooth, high-FPS animations. 6633 6634This guide aims to help you identify and resolve common performance issues in React Native applications, ensuring a smoother user experience. 6635 6636## Improving React Native Build Times 6637 6638Building a React Native app can be resource-intensive, often taking several minutes of developer time. This becomes more challenging as projects grow or in larger organizations with multiple developers. To address these performance issues, consider the following advanced techniques to improve build times. 6639 6640### Build Only One ABI During Development (Android-only) 6641 6642By default, Android builds include all four Application Binary Interfaces (ABIs): `armeabi-v7a`, `arm64-v8a`, `x86`, and `x86_64`. However, during local development and testing on an emulator or physical device, building only the necessary ABI can reduce native build time by approximately 75%. 6643 6644#### Using React Native CLI 6645 6646To build a single ABI with the React Native CLI, use the `--active-arch-only` flag: 6647 6648```bash 6649$ yarn react-native run-android --active-arch-only 6650 6651[ ... ] 6652info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag. 6653Jetifier found 1037 file(s) to forward-jetify. Using 32 workers... 6654info JS server already running. 6655info Detected architectures arm64-v8a 6656info Installing the app... 6657``` 6658 6659This approach uses the `reactNativeArchitectures` Gradle property. 6660 6661#### Using Gradle Directly 6662 6663For builds directly with Gradle, specify the desired ABI: 6664 6665```bash 6666$ ./gradlew :app:assembleDebug -PreactNativeArchitectures=x86,x86_64 6667``` 6668 6669You can also override this value locally in `gradle.properties`: 6670 6671```properties 6672# Use this property to specify which architecture you want to build. 6673# You can also override it from the CLI using 6674# ./gradlew <task> -PreactNativeArchitectures=x86_64 6675reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 6676``` 6677 6678For release builds, ensure all ABIs are included to support various devices. 6679 6680### Enable Configuration Caching (Android-only) 6681 6682Starting with React Native 0.79, Gradle Configuration Caching can be enabled to improve build times by skipping the configuration phase in subsequent builds: 6683 6684Add this line to `android/gradle.properties`: 6685 6686```properties 6687org.gradle.configuration-cache=true 6688``` 6689 6690Refer to the official Gradle documentation for more details on Configuration Caching. 6691 6692### Use a Compiler Cache 6693 6694Frequent native builds benefit from using a compiler cache, which can be either local or distributed. 6695 6696#### Local Caches 6697 6698Ccache is recommended for both Android and iOS. It wraps compilers, stores results, and skips recompilation if cached: 6699 6700##### Installation 6701 6702On macOS, install ccache with: 6703 6704```bash 6705brew install ccache 6706``` 6707 6708Alternatively, follow the official installation instructions. 6709 6710##### Usage 6711 6712Perform two clean builds to observe speed improvements. Verify cache hits/misses with: 6713 6714```bash 6715$ ccache -s 6716Summary: 6717 Hits: 196 / 3068 (6.39 %) 6718 Direct: 0 / 3068 (0.00 %) 6719 Preprocessed: 196 / 3068 (6.39 %) 6720 Misses: 2872 6721 Direct: 3068 6722 Preprocessed: 2872 6723 Uncacheable: 1 6724Primary storage: 6725 Hits: 196 / 6136 (3.19 %) 6726 Misses: 5940 6727 Cache size (GB): 0.60 / 20.00 (3.00 %) 6728``` 6729 6730Reset stats with `ccache --zero-stats` and clear cache with `ccache --clear`. 6731 6732##### XCode Specific Setup 6733 6734For iOS, enable ccache in `ios/Podfile`: 6735 6736```ruby 6737post_install do |installer| 6738 react_native_post_install( 6739 installer, 6740 config[:reactNativePath], 6741 :mac_catalyst_enabled => false, 6742 # Uncomment the line below 6743 :ccache_enabled => true 6744 ) 6745end 6746``` 6747 6748##### CI Considerations 6749 6750On CI, consider a full clean build to avoid cache issues. Use `compiler_check content` for hashing file contents instead of relying on timestamps. 6751 6752#### Distributed Caches 6753 6754For larger organizations, distributed caches like sccache can be beneficial. Refer to the sccache quickstart guide for setup instructions. 6755 6756## Optimizing Flatlist Configuration 6757 6758### Key Concepts 6759 6760- **VirtualizedList:** The underlying component for `FlatList` in React Native, implementing the virtual list concept. 6761 6762- **Memory Consumption:** Refers to how much data about your list is stored in memory, potentially leading to app crashes. 6763 6764- **Responsiveness:** Describes an application's ability to promptly respond to user interactions. Poor responsiveness can manifest as delays when interacting with components. 6765 6766- **Blank Areas:** Occur when `VirtualizedList` cannot render items quickly enough, resulting in non-rendered components appearing as blank spaces. 6767 6768- **Viewport:** The visible portion of content that is rendered on the screen. 6769 6770- **Window:** The area where items are mounted, typically larger than the viewport. 6771 6772### Properties for Performance Improvement 6773 6774#### removeClippedSubviews 6775 6776|Type|Default| 6777|-|-| 6778|Boolean|False| 6779 6780**Description:** When set to `true`, views outside of the viewport are detached from the native view hierarchy. 6781 6782- **Pros:** Reduces time on the main thread, minimizing dropped frames by excluding off-screen views from rendering and drawing. 6783 6784- **Cons:** Potential bugs such as missing content (notably on iOS) if complex transforms or absolute positioning are used. Views remain in memory but are only detached. 6785 6786#### maxToRenderPerBatch 6787 6788|Type|Default| 6789|-|-| 6790|Number|10| 6791 6792**Description:** Controls the number of items rendered per batch during scrolling. 6793 6794- **Pros:** A higher value reduces visual blank areas by increasing the fill rate. 6795 6796- **Cons:** More items per batch can lead to longer JavaScript execution times, potentially blocking other events and affecting responsiveness. 6797 6798#### updateCellsBatchingPeriod 6799 6800|Type|Default| 6801|-|-| 6802|Number|50| 6803 6804**Description:** Sets the delay in milliseconds between batch renders for `VirtualizedList`. 6805 6806- **Pros:** Allows control over rendering frequency and quantity of items per batch. 6807 6808- **Cons:** Less frequent batches may cause blank areas, while more frequent batches can impact responsiveness. 6809 6810#### initialNumToRender 6811 6812|Type|Default| 6813|-|-| 6814|Number|10| 6815 6816**Description:** Specifies the number of items to render initially. 6817 6818- **Pros:** Precisely setting this value for different devices can significantly boost initial rendering performance. 6819 6820- **Cons:** A low `initialNumToRender` may result in blank areas if it doesn't cover the viewport on initial load. 6821 6822#### windowSize 6823 6824|Type|Default| 6825|-|-| 6826|Number|21| 6827 6828**Description:** Measured in units where 1 equals the viewport height. The default is 21 (10 viewports above, 10 below, and one in between). 6829 6830- **Pros:** A larger `windowSize` reduces blank space during scrolling but increases memory usage. 6831 6832- **Cons:** A smaller `windowSize` saves memory but may increase the likelihood of encountering blank areas. 6833 6834### Tips for List Item Components 6835 6836#### Use Basic Components 6837 6838Complex components render more slowly. Minimize logic and nesting in list items, especially if they are reused frequently across your app. 6839 6840#### Use Light Components 6841 6842Heavier components take longer to render. Avoid large images by using cropped versions or thumbnails. Collaborate with the design team to minimize effects and interactions within list items. 6843 6844#### Use `memo()` 6845 6846`React.memo()` creates a memoized component that re-renders only when its props change, optimizing performance for FlatList components. 6847 6848```typescript 6849import React, { memo } from 'react'; 6850import { View, Text } from 'react-native'; 6851 6852const MyListItem = memo( 6853 ({ title }: { title: string }) => ( 6854 <View> 6855 <Text>{title}</Text> 6856 </View> 6857 ), 6858 (prevProps, nextProps) => prevProps.title === nextProps.title 6859); 6860 6861export default MyListItem; 6862``` 6863 6864#### Use Cached Optimized Images 6865 6866Utilize community packages like `react-native-fast-image` for more efficient image handling. Faster loading images free up the JavaScript thread sooner. 6867 6868#### Use getItemLayout 6869 6870For list items with consistent height (or width in horizontal lists), use `getItemLayout` to avoid asynchronous layout calculations, enhancing performance. 6871 6872#### Use keyExtractor or key 6873 6874Set the `keyExtractor` prop on your `FlatList` for caching and React's `key` tracking. Alternatively, use a `key` prop within item components. 6875 6876#### Avoid Anonymous Functions in renderItem 6877 6878For functional components, define `renderItem` outside of JSX and wrap it with `useCallback`. For class components, place `renderItem` outside the render method to prevent recreation on each call. 6879 6880```typescript 6881const renderItem = useCallback(({ item }) => ( 6882 <View key={item.key}> 6883 <Text>{item.title}</Text> 6884 </View> 6885), []); 6886 6887return ( 6888 // ... 6889 <FlatList data={items} renderItem={renderItem} /> 6890 // ... 6891); 6892``` 6893 6894## Alert 6895 6896The `Alert` API is designed to work across both Android and iOS platforms, allowing for the display of static alerts. On iOS, it also supports prompts that request user input. 6897 6898### Example Usage 6899 6900#### iOS 6901 6902On iOS, you can define any number of buttons within an alert. Each button may have a specific style or be emphasized using `AlertButtonStyle` enum and the `isPreferred` field on `AlertButton`. 6903 6904#### Android 6905 6906For Android, up to three buttons are allowed: 6907 6908- A single button is treated as 'positive' (e.g., 'OK'). 6909- Two buttons represent 'negative', 'positive' (e.g., 'Cancel', 'OK'). 6910- Three buttons denote 'neutral', 'negative', 'positive' (e.g., 'Later', 'Cancel', 'OK'). 6911 6912Alerts on Android can be dismissed by tapping outside the alert box, which is disabled by default. This behavior can be enabled with `AlertOptions` using `{cancelable: true}`. The dismissal event can be managed via an `onDismiss` callback within the `options`. 6913 6914### Reference 6915 6916#### Methods 6917 6918##### `alert()` 6919 6920```typescript 6921static alert( 6922 title: string, 6923 message?: string, 6924 buttons?: AlertButton[], 6925 options?: AlertOptions 6926); 6927``` 6928 6929**Parameters:** 6930 6931|Name|Type|Description| 6932|-|-|-| 6933|titleRequired|string|The dialog's title. Passing `null` or an empty string will hide the title.| 6934|message|string|An optional message displayed below the title.| 6935|buttons|AlertButton\[]|Optional array for button configurations.| 6936|options|AlertOptions|Optional configuration for the alert.| 6937 6938##### `prompt()` (iOS Only) 6939 6940```typescript 6941static prompt( 6942 title: string, 6943 message?: string, 6944 callbackOrButtons?: ((text: string) => void) | AlertButton[], 6945 type?: AlertType, 6946 defaultValue?: string, 6947 keyboardType?: string 6948); 6949``` 6950 6951Creates and displays a text input alert. 6952 6953**Parameters:** 6954 6955|Name|Type|Description| 6956|-|-|-| 6957|titleRequired|string|The dialog's title.| 6958|message|string|An optional message displayed above the text input.| 6959|callbackOrButtons|function \| AlertButton\[]|If a function, it is invoked with the prompt's value `(text: string) => void` when 'OK' is tapped.\*\*\*If an array, buttons are configured based on its content.| 6960|type|AlertType|Configures the text input.| 6961|defaultValue|string|Default text in the input field.| 6962|keyboardType|string|Keyboard type for the first text field (if present). One of `TextInput` keyboard types.| 6963|options|AlertOptions|Optional configuration for the alert.| 6964 6965#### Type Definitions 6966 6967##### `AlertButtonStyle` (iOS Only) 6968 6969An enum representing iOS Alert button styles. 6970 6971**Constants:** 6972 6973|Value|Description| 6974|-|-| 6975|`'default'`|Default button style.| 6976|`'cancel'`|Cancel button style.| 6977|`'destructive'`|Destructive button style.| 6978 6979##### `AlertType` (iOS Only) 6980 6981An enum representing iOS Alert types. 6982 6983**Constants:** 6984 6985|Value|Description| 6986|-|-| 6987|`'default'`|Default alert with no inputs| 6988|`'plain-text'`|Plain text input alert| 6989|`'secure-text'`|Secure text input alert| 6990|`'login-password'`|Login and password alert| 6991 6992##### `AlertButton` 6993 6994An object describing a button's configuration in an alert. 6995 6996**Properties:** 6997 6998|Name|Type|Description| 6999|-|-|-| 7000|text|string|Button label.| 7001|onPress|function|Callback when the button is pressed.| 7002|styleiOS|AlertButtonStyle|Button style, ignored on Android.| 7003|isPreferrediOS|boolean|Whether to emphasize the button, ignored on Android.| 7004 7005##### `AlertOptions` 7006 7007An object for optional alert configurations. 7008 7009**Properties:** 7010 7011|Name|Type|Description| 7012|-|-|-| 7013|cancelableAndroid|boolean|Determines if the alert can be dismissed by tapping outside of it.| 7014|userInterfaceStyleiOS|string|Interface style for the alert, set to `light` or `dark`, otherwise defaults to system style.| 7015|onDismissAndroid|function|Callback fired when the alert is dismissed.| 7016 7017## Optimizing JavaScript loading 7018 7019Parsing and executing JavaScript code requires both memory and time. As applications grow, it becomes beneficial to delay loading code until it's needed for the first time. React Native includes standard optimizations by default, but additional techniques can further enhance app efficiency. For very large apps, advanced automatic optimizations are available, though they come with tradeoffs. 7020 7021### Recommended: Use Hermes 7022 7023Hermes is the default engine for new React Native applications and is optimized for efficient code loading. In release builds, JavaScript code is precompiled to bytecode ahead of time. This bytecode is loaded into memory on-demand, eliminating the need for parsing plain JavaScript. 7024 7025**Info:** Learn more about using Hermes in React Native [here](#). 7026 7027### Recommended: Lazy-load Large Components 7028 7029If a component with substantial code or dependencies isn't needed during initial app rendering, use React's `lazy` API to defer its loading until it is rendered for the first time. Typically, consider lazy-loading screen-level components to prevent new screens from increasing startup time. 7030 7031**Info:** 7032 7033#### Tip: Avoid Module Side Effects 7034 7035Lazy-loading can alter app behavior if component modules or their dependencies have side effects, such as modifying global variables or subscribing to external events. Most React app modules should be free of side effects. 7036 7037##### Example: SideEffects.tsx 7038 7039```tsx 7040import Logger from "./utils/Logger" 7041 7042// 🚩🚩🚩 Side effect! This must execute before React can render the SplashScreen component. 7043global.logger = new Logger() 7044 7045export function SplashScreen() { 7046 // ... 7047} 7048``` 7049 7050### Advanced: Call `require` Inline 7051 7052To defer loading code without using `lazy` or asynchronous `import()`, use the `require()` function where you would typically use a static `import`. 7053 7054##### Example: VeryExpensive.tsx 7055 7056```tsx 7057import { Component } from "react" 7058import { Text } from "react-native" 7059 7060// ... import some very expensive modules 7061 7062export default function VeryExpensive() { 7063 // ... lots and lots of rendering logic 7064 return <Text>Very Expensive Component</Text> 7065} 7066``` 7067 7068##### Example: Optimized.tsx 7069 7070```tsx 7071import { useCallback, useState } from "react" 7072import { TouchableOpacity, View, Text } from "react-native" 7073 7074let VeryExpensive = null 7075 7076export default function Optimize() { 7077 const [needsExpensive, setNeedsExpensive] = useState(false) 7078 7079 const didPress = useCallback(() => { 7080 if (VeryExpensive == null) { 7081 VeryExpensive = require("./VeryExpensive").default 7082 } 7083 setNeedsExpensive(true) 7084 }, []) 7085 7086 return ( 7087 <View style={{ marginTop: 20 }}> 7088 <TouchableOpacity onPress={didPress}> 7089 <Text>Load</Text> 7090 </TouchableOpacity> 7091 {needsExpensive ? <VeryExpensive /> : null} 7092 </View> 7093 ) 7094} 7095``` 7096 7097### Advanced: Automatically Inline `require` Calls 7098 7099When using the React Native CLI to build your app, `require` calls (but not `import`s) are automatically inlined for you and any third-party packages (`node_modules`) used. 7100 7101```tsx 7102import { useCallback, useState } from "react" 7103import { TouchableOpacity, View, Text } from "react-native" 7104 7105// This top-level require call will be evaluated lazily as part of the component below. 7106const VeryExpensive = require("./VeryExpensive").default 7107 7108export default function Optimize() { 7109 const [needsExpensive, setNeedsExpensive] = useState(false) 7110 7111 const didPress = useCallback(() => { 7112 setNeedsExpensive(true) 7113 }, []) 7114 7115 return ( 7116 <View style={{ marginTop: 20 }}> 7117 <TouchableOpacity onPress={didPress}> 7118 <Text>Load</Text> 7119 </TouchableOpacity> 7120 {needsExpensive ? <VeryExpensive /> : null} 7121 </View> 7122 ) 7123} 7124``` 7125 7126**Info:** Some React Native frameworks, like Expo projects, do not inline `require` calls by default. Enable this optimization in your project's Metro config by setting `inlineRequires: true` in `getTransformOptions`. 7127 7128#### Pitfalls of Inline `require`s 7129 7130Inlining `require` calls alters the order in which modules are evaluated and can prevent some from being evaluated at all. This is generally safe as JavaScript modules are often side-effect-free. 7131 7132If a module has side effects, such as initializing logging or patching global APIs, unexpected behavior or crashes may occur. In these cases, exclude certain modules from this optimization or disable it entirely. 7133 7134To **disable automatic inlining of `require` calls**: 7135 7136Update your `metro.config.js` to set the `inlineRequires` transformer option to `false`: 7137 7138```js 7139module.exports = { 7140 transformer: { 7141 async getTransformOptions() { 7142 return { 7143 transform: { 7144 inlineRequires: false, 7145 }, 7146 } 7147 }, 7148 }, 7149} 7150``` 7151 7152To **exclude certain modules from `require` inlining**: 7153 7154Use the transformer options `inlineRequires.blockList` and `nonInlinedRequires`. See the code snippet for examples of how to use each one. 7155 7156```js 7157module.exports = { 7158 transformer: { 7159 async getTransformOptions() { 7160 return { 7161 transform: { 7162 inlineRequires: { 7163 blockList: { 7164 // require() calls in `DoNotInlineHere.js` will not be inlined. 7165 [require.resolve("./src/DoNotInlineHere.js")]: true, 7166 7167 // require() calls elsewhere will be inlined unless they match any entry nonInlinedRequires (see below). 7168 }, 7169 }, 7170 nonInlinedRequires: [ 7171 // require('react') calls will not be inlined anywhere 7172 "react", 7173 ], 7174 }, 7175 } 7176 }, 7177 }, 7178} 7179``` 7180 7181See the documentation for `getTransformOptions` in Metro for more details on setting up and fine-tuning your inline `require`s. 7182 7183### Advanced: Use Random Access Module Bundles (Non-Hermes) 7184 7185**Not supported when using Hermes.** Hermes bytecode is incompatible with RAM bundle format, offering similar or better performance across all use cases. 7186 7187Random access module bundles (RAM bundles) work alongside the techniques mentioned above to limit JavaScript code parsing and memory loading. Each module is stored as a separate string or file, parsed only when needed for execution. 7188 7189RAM bundles may be physically split into files or use an indexed format with a lookup table of multiple modules in one file. 7190 7191#### Android 7192 7193Enable RAM format by editing your `android/app/build.gradle` file. Before the line `apply from: "../../node_modules/react-native/react.gradle"`, add or amend the `project.ext.react` block: 7194 7195```gradle 7196project.ext.react = [ 7197 bundleCommand: "ram-bundle", 7198] 7199``` 7200 7201For a single indexed file on Android, use: 7202 7203```gradle 7204project.ext.react = [ 7205 bundleCommand: "ram-bundle", 7206 extraPackagerArgs: ["--indexed-ram-bundle"] 7207] 7208``` 7209 7210#### iOS 7211 7212RAM bundles are always indexed (single file) on iOS. 7213 7214Enable RAM format in Xcode by editing the build phase "Bundle React Native code and images". Before `../node_modules/react-native/scripts/react-native-xcode.sh`, add: 7215 7216```sh 7217export BUNDLE_COMMAND="ram-bundle" 7218export NODE_BINARY=node 7219../node_modules/react-native/scripts/react-native-xcode.sh 7220``` 7221 7222See the documentation for `getTransformOptions` in Metro for more details on setting up and fine-tuning your RAM bundle build. 7223 7224## Profiling 7225 7226Profiling involves analyzing an app's performance, resource usage, and behavior to identify potential bottlenecks or inefficiencies. Utilizing profiling tools ensures your app runs smoothly across various devices and conditions. 7227 7228For iOS, Instruments is a valuable tool, while on Android, the Android Studio Profiler should be used. 7229 7230**Important:** Ensure Development Mode is OFF! Your application logs should indicate `__DEV__ === false`, meaning development-level warnings are off and performance optimizations are enabled. 7231 7232### Profiling Android UI Performance with System Tracing 7233 7234Android supports over 10,000 different phones and generalizes to support software rendering. This means you might not get as much optimization out-of-the-box compared to iOS. However, there are often areas for improvement that aren't related to native code. 7235 7236The first step in debugging performance issues is determining where time is spent during each 16ms frame using the built-in System Tracing profiler in Android Studio. 7237 7238#### 1. Collecting a Trace 7239 7240- Connect your device exhibiting stuttering via USB. 7241- Open your project's `android` folder in Android Studio, select your device, and run your project as profileable. 7242- With your app running on the device, navigate to the point just before the animation or interaction you want to profile. 7243- Start "Capture System Activities" in the Android Studio Profiler pane. 7244- Perform the desired action, then press "Stop recording." 7245- Inspect the trace directly in Android Studio or export it for analysis with tools like Perfetto. 7246 7247#### 2. Reading the Trace 7248 7249After opening the trace in Android Studio or Perfetto: 7250 7251- Use WASD keys to navigate and zoom within the tool. 7252- Enable VSync highlighting at the top right of the screen to see frame boundaries as zebra stripes. If not visible, try profiling on a different device (e.g., Nexus series). 7253 7254#### 3. Find Your Process 7255 7256Scroll to find your package name in the trace. For example, `com.facebook.adsmanager` might appear as `book.adsmanager`. 7257 7258Identify key threads: 7259 7260- **UI Thread:** Handles standard Android measure/layout/draw operations. Look for events related to `Choreographer`, `traversals`, and `DispatchUI`. 7261- **JS Thread:** Executes JavaScript code. Identify it by looking for `JSCall` or `Bridge.executeJSCall`. 7262- **Native Modules Thread:** Manages native module calls (e.g., `UIManager`). Look for `NativeCall` or `callJavaModuleMethod`. 7263- **Render Thread (Android 5+):** Generates OpenGL commands. Identify it by looking for `DrawFrame` and `queueBuffer`. 7264 7265### Identifying a Culprit 7266 7267A smooth animation should show no thread working near frame boundaries, indicating 60 FPS rendering. 7268 7269If choppy performance is observed: 7270 7271- **JS Issues:** If the JS thread works continuously across frames, the problem lies in JavaScript execution. 7272- **Native UI Issues:** If the UI or Render threads work across frame boundaries, the issue is with native views being rendered. 7273 7274### Resolving JavaScript Issues 7275 7276For JS problems: 7277 7278- Investigate specific JS code. Look for frequent calls like `RCTEventEmitter`. 7279- Consider optimizing component updates using methods like `shouldComponentUpdate`. 7280 7281### Resolving Native UI Issues 7282 7283Native UI issues can arise from: 7284 72851. **Excessive GPU Work:** Long durations in `DrawFrame` indicate heavy GPU load. 7286 7287 - Use `renderToHardwareTextureAndroid` for complex animations. 7288 - Avoid `needsOffscreenAlphaCompositing`, which increases GPU load. 7289 72901. **Creating New Views on the UI Thread:** 7291 - Postpone creating new UI until after interactions or simplify the UI being created. 7292 - The React Native team is developing solutions to create and configure UI off the main thread. 7293 7294### Finding Native CPU Hotspots 7295 7296For native-side issues: 7297 7298- Use the Android Studio Profiler's "Find CPU Hotspots (Java/Kotlin Method Recording)" feature. 7299- Select Java/Kotlin recording, perform interactions, and stop recording after a short interaction. 7300- Analyze the trace in Android Studio or export it for further analysis with tools like Firefox Profiler. 7301 7302CPU hotspot profiling is resource-intensive and may not provide precise measurements but can highlight native methods consuming time during each frame. 7303 7304## ECMAScript Features Overview 7305 7306### ECMAScript 5 Reserved Words 7307 7308- **Example**: 7309 ```typescript 7310 promise.catch(function() {...}); 7311 ``` 7312 7313### ECMAScript 2015 (ES6) Arrow Functions 7314 7315- **Example**: 7316 ```typescript 7317 <C onPress={() => this.setState({pressed: true})} /> 7318 ``` 7319 7320### Block Scoping 7321 7322- **Example**: 7323 ```typescript 7324 let greeting = "hi" 7325 ``` 7326 7327### Call Spread 7328 7329- **Example**: 7330 ```typescript 7331 Math.max(...array) 7332 ``` 7333 7334### Classes 7335 7336- **Example**: 7337 ```typescript 7338 class C extends React.Component {render() { return <View />; }} 7339 ``` 7340 7341### Computed Properties 7342 7343- **Example**: 7344 ```typescript 7345 const key = "abc" 7346 const obj = { [key]: 10 } 7347 ``` 7348 7349### Constants 7350 7351- **Example**: 7352 ```typescript 7353 const answer = 42 7354 ``` 7355 7356### Destructuring 7357 7358- **Example**: 7359 ```typescript 7360 const { isActive, style } = this.props 7361 ``` 7362 7363### for…of Loop 7364 7365- **Example**: 7366 ```typescript 7367 for (var num of [1, 2, 3]) {...}; 7368 ``` 7369 7370### Function Name 7371 7372- **Example**: 7373 ```typescript 7374 let number = (x) => x 7375 ``` 7376 7377### Literals 7378 7379- **Example**: 7380 ```typescript 7381 const b = 0b11 7382 const o = 0o7 7383 const u = "Hello\u{000A}\u{0009}!" 7384 ``` 7385 7386### Modules 7387 7388- **Example**: 7389 ```typescript 7390 import React, { Component } from "react" 7391 ``` 7392 7393### Object Concise Method 7394 7395- **Example**: 7396 ```typescript 7397 const obj = { 7398 method() { 7399 return 10 7400 }, 7401 } 7402 ``` 7403 7404### Object Short Notation 7405 7406- **Example**: 7407 ```typescript 7408 const name = "vjeux" 7409 const obj = { name } 7410 ``` 7411 7412### Parameters with Default Values and Destructuring 7413 7414- **Example**: 7415 ```typescript 7416 function test(x = "hello", { a, b }, ...args) {} 7417 ``` 7418 7419### Rest Params 7420 7421- **Example**: 7422 ```typescript 7423 function(type, ...args) {}; 7424 ``` 7425 7426### Shorthand Properties 7427 7428- **Example**: 7429 ```typescript 7430 const o = { a, b, c } 7431 ``` 7432 7433### Sticky Regex 7434 7435- **Example**: 7436 ```typescript 7437 const a = /o+/y 7438 ``` 7439 7440### Template Literals 7441 7442- **Example**: 7443 ```typescript 7444 const who = "world" 7445 const str = `Hello ${who}` 7446 ``` 7447 7448### Unicode Regex 7449 7450- **Example**: 7451 ```typescript 7452 const string = "foo💩bar" 7453 const match = string.match(/foo(.)bar/u) 7454 ``` 7455 7456### ECMAScript 2016 (ES7) Exponentiation Operator 7457 7458- **Example**: 7459 ```typescript 7460 let x = 10 ** 2 7461 ``` 7462 7463### ECMAScript 2017 (ES8) Async Functions 7464 7465- **Example**: 7466 ```typescript 7467 async function doStuffAsync() { 7468 const foo = await doOtherStuffAsync() 7469 } 7470 ``` 7471 7472### Function Trailing Comma 7473 7474- **Example**: 7475 ```typescript 7476 function f(a, b, c) {} 7477 ``` 7478 7479### ECMAScript 2018 (ES9) Object Spread 7480 7481- **Example**: 7482 ```typescript 7483 const extended = { ...obj, a: 10 } 7484 ``` 7485 7486### ECMAScript 2019 (ES10) Optional Catch Binding 7487 7488- **Example**: 7489 ```typescript 7490 try { 7491 throw 0 7492 } catch { 7493 doSomethingWhichDoesNotCareAboutTheValueThrown() 7494 } 7495 ``` 7496 7497### ECMAScript 2020 (ES11) Dynamic Imports 7498 7499- **Example**: 7500 ```typescript 7501 const package = await import("package") 7502 package.function() 7503 ``` 7504 7505### Nullish Coalescing Operator 7506 7507- **Example**: 7508 ```typescript 7509 const foo = object.foo ?? "default" 7510 ``` 7511 7512### Optional Chaining 7513 7514- **Example**: 7515 ```typescript 7516 const name = obj.user?.name 7517 ``` 7518 7519### ECMAScript 2022 (ES13) Class Fields 7520 7521- **Example**: 7522 ```typescript 7523 class Bork { 7524 static a = "foo" 7525 static b 7526 x = "bar" 7527 y 7528 } 7529 ``` 7530 7531### Stage 1 Proposal: Export Default From 7532 7533- **Example**: 7534 ```typescript 7535 export v from 'mod'; 7536 ``` 7537 7538### Miscellaneous Features 7539 7540#### Babel Template 7541 7542- **Example**: 7543 ```typescript 7544 template(`const %%importName%% = require(%%source%%);`) 7545 ``` 7546 7547#### Flow Typing 7548 7549- **Example**: 7550 ```typescript 7551 function foo(x: ?number): string {} 7552 ``` 7553 7554#### ESM to CJS 7555 7556- **Example**: 7557 ```typescript 7558 export default 42 7559 ``` 7560 7561#### JSX Syntax 7562 7563- **Example**: 7564 ```typescript 7565 <View style={{color: 'red'}} /> 7566 ``` 7567 7568#### Object Assign 7569 7570- **Example**: 7571 ```typescript 7572 Object.assign(a, b) 7573 ``` 7574 7575#### React Display Name 7576 7577- **Example**: 7578 ```typescript 7579 const bar = createReactClass({}) 7580 ``` 7581 7582#### TypeScript Typing 7583 7584- **Example**: 7585 ```typescript 7586 function foo(x: { hello: true; target: "react native!" }): string {} 7587 ``` 7588 7589## Timers 7590 7591Timers play a crucial role in applications and React Native implements browser-like timers. 7592 7593### Overview of Timers 7594 7595React Native provides several timer functions: 7596 7597- `setTimeout`, `clearTimeout` 7598- `setInterval`, `clearInterval` 7599- `setImmediate`, `clearImmediate` 7600- `requestAnimationFrame`, `cancelAnimationFrame` 7601 7602It's important to note that `requestAnimationFrame(fn)` differs from `setTimeout(fn, 0)`. The former executes after all frames have been processed, while the latter runs as soon as possible (potentially over 1000 times per second on an iPhone 5S). 7603 7604`setImmediate` is executed at the end of the current JavaScript execution block, just before sending a batched response back to native. If `setImmediate` is called within its own callback, it executes immediately without yielding back to native. 7605 7606The implementation of `Promise` in React Native uses `setImmediate` for asynchronicity. 7607 7608**Note:** When debugging on Android, if there's a time drift between the debugger and device, animations or event behaviors might not function correctly. To correct this, run `adb shell "date `date +%m%d%H%M%Y.%S%3N`"` on your debugger machine. Root access is required for real devices. 7609 7610### InteractionManager 7611 7612Native apps often feel smooth because they avoid expensive operations during interactions and animations. React Native has a limitation of a single JS execution thread, but you can use `InteractionManager` to schedule long-running tasks after interactions or animations have completed. 7613 7614To schedule tasks post-interaction: 7615 7616```typescript 7617InteractionManager.runAfterInteractions(() => { 7618 // ...long-running synchronous task... 7619}) 7620``` 7621 7622#### Comparison with Other Scheduling Methods 7623 7624- **requestAnimationFrame()**: Use for code that animates a view over time. 7625- **setImmediate/setTimeout/setInterval()**: Run code later, but may delay animations. 7626- **runAfterInteractions()**: Run code later without delaying active animations. 7627 7628The touch handling system considers one or more active touches as an 'interaction' and delays `runAfterInteractions()` callbacks until all touches have ended or been canceled. 7629 7630`InteractionManager` also allows applications to register animations by creating an interaction 'handle' at the start of an animation, and clearing it upon completion: 7631 7632```typescript 7633const handle = InteractionManager.createInteractionHandle() 7634// run animation... (`runAfterInteractions` tasks are queued) 7635// later, on animation completion: 7636InteractionManager.clearInteractionHandle(handle) 7637// queued tasks run if all handles were cleared 7638``` 7639 7640This approach ensures that animations remain smooth while deferring other operations until interactions have concluded. 7641 7642## Using Hermes 7643 7644Hermes is an open-source JavaScript engine optimized for React Native. Many applications experience improved start-up time, reduced memory usage, and smaller app size when using Hermes compared to JavaScriptCore. By default, React Native uses Hermes without requiring additional configuration. 7645 7646### Bundled Hermes 7647 7648React Native includes a **bundled version** of Hermes. Each new release of React Native comes with a compatible version of Hermes, ensuring seamless integration. This change is transparent for React Native users, who can still disable Hermes if needed. Further technical details are available on the official documentation page. 7649 7650### Confirming Hermes Usage 7651 7652For newly created apps, check if Hermes is enabled in the welcome view: 7653 7654A `HermesInternal` global variable will be present in JavaScript to verify Hermes usage: 7655 7656```typescript 7657const isHermes = () => !!global.HermesInternal 7658``` 7659 7660> **Caution:** If you use a non-standard method for loading the JS bundle, the `HermesInternal` variable might exist without utilizing the optimized pre-compiled bytecode. Ensure that you are using the `.hbc` file and benchmark performance as described below. 7661 7662To observe Hermes' benefits, create a release build of your app: 7663 7664#### Android 7665 7666```shell 7667npm run android -- --mode="release" 7668``` 7669 7670```shell 7671yarn android --mode release 7672``` 7673 7674#### iOS 7675 7676```shell 7677npm run ios -- --mode="Release" 7678``` 7679 7680```shell 7681yarn ios --mode Release 7682``` 7683 7684This process compiles JavaScript to Hermes Bytecode during build time, enhancing your app's startup speed on devices. 7685 7686### Switching Back to JavaScriptCore 7687 7688React Native also supports using JavaScriptCore as the JavaScript engine. Follow these steps to opt-out of Hermes: 7689 7690#### Android 7691 7692Edit `android/gradle.properties` and set `hermesEnabled` to false: 7693 7694```diff 7695# Use this property to enable or disable the Hermes JS engine. 7696# If set to false, you will be using JSC instead. 7697- hermesEnabled=true 7698+ hermesEnabled=false 7699``` 7700 7701#### iOS 7702 7703Edit `ios/Podfile` as shown below: 7704 7705```diff 7706 use_react_native!( 7707 :path => config[:reactNativePath], 7708+ :hermes_enabled => false, 7709 # An absolute path to your application root. 7710 :app_path => "#{Pod::Config.instance.installation_root}/.." 7711 ) 7712``` 7713 7714## What is Codegen? 7715 7716**Codegen** is designed to minimize repetitive coding tasks by generating scaffolding code automatically. While not mandatory—allowing manual writing of generated code—it can significantly save time. 7717 7718React Native triggers **Codegen** during the build process for both iOS and Android apps. Developers may also run **Codegen** scripts manually, especially when working on Turbo Native Modules and Fabric Native Components, to review the types and files produced. 7719 7720### How Codegen Works 7721 7722**Codegen** is an integral part of a React Native app's development process. The scripts reside within the `react-native` NPM package and are executed during the build phase. 7723 7724The **Codegen** process begins by scanning directories specified in your `package.json`, searching for JavaScript files that define specifications (specs) for custom modules and components. These spec files use a typed dialect, with React Native supporting both Flow and TypeScript. 7725 7726Upon identifying a spec file, **Codegen** generates the necessary boilerplate code. This includes C++ glue-code and platform-specific implementations: Java for Android and Objective-C++ for iOS. 7727 7728## Using Codegen 7729 7730This guide covers how to: 7731 7732- Configure **Codegen**. 7733- Manually invoke it for each platform. 7734 7735It also describes the generated code. 7736 7737### Prerequisites 7738 7739A React Native app is required to generate code properly, even when invoking **Codegen** manually. The process is integrated with the app build and relies on scripts in the `react-native` NPM package. 7740 7741To create a project using the React Native CLI: 7742 7743```bash 7744npx @react-native-community/cli@latest init SampleApp --version 0.76.0 7745``` 7746 7747**Codegen** generates glue-code for custom modules or components. Refer to guides for Turbo Native Modules and Fabric Native Components for more details on creating them. 7748 7749### Configuring **Codegen** 7750 7751Configure **Codegen** in your app by modifying the `package.json` file using a custom field called `codegenConfig`. 7752 7753```json 7754"codegenConfig": { 7755 "name": "<SpecName>", 7756 "type": "<types>", 7757 "jsSrcsDir": "<source_dir>", 7758 "android": { 7759 "javaPackageName": "<java.package.name>" 7760 }, 7761 "ios": { 7762 "modulesConformingToProtocol": { 7763 "RCTImageURLLoader": [ 7764 "<iOS-class-conforming-to-RCTImageURLLoader>" 7765 ], 7766 "RCTURLRequestHandler": [ 7767 "<iOS-class-conforming-to-RCTURLRequestHandler>" 7768 ], 7769 "RCTImageDataDecoder": [ 7770 "<iOS-class-conforming-to-RCTImageDataDecoder>" 7771 ] 7772 }, 7773 "componentProvider": { 7774 "<componentName>": "<iOS-class-implementing-the-component>" 7775 }, 7776 "modulesProvider": { 7777 "<moduleName>": "<iOS-class-implementing-the-RCTModuleProvider-protocol>" 7778 } 7779 } 7780} 7781``` 7782 7783Customize the fields as follows: 7784 7785- `name`: The name for files containing your specs, typically ending with `Spec`. 7786- `type`: Specifies code generation type. Allowed values are `modules`, `components`, `all`. 7787 - `modules`: For Turbo Native Modules. 7788 - `components`: For Native Fabric Components. 7789 - `all`: For both components and modules. 7790- `jsSrcsDir`: Root folder for your specs. 7791- `android.javaPackageName`: Custom package name for Android code generation. 7792 7793The `ios` field is optional and allows advanced configurations: 7794 7795- `modulesConformingToProtocol`: Define iOS native modules conforming to specific protocols, injected into the React Native runtime at app start. 7796 - `RCTImageURLLoader`, `RCTURLRequestHandler`, `RCTImageDataDecoder`: List classes implementing these protocols as Native Modules. 7797- `componentProvider`: Map JS React components to their native implementations. 7798- `modulesProvider`: Map JS Native Modules to their native providers. 7799 7800**Codegen** searches for JS files following specific conventions among app dependencies: 7801 7802- Turbo Native Modules: Spec files prefixed with `Native` (e.g., `NativeLocalStorage.ts`). 7803- Native Fabric Components: Spec files suffixed with `NativeComponent` (e.g., `WebViewNativeComponent.ts`). 7804 7805### Running **Codegen** 7806 7807Assuming you have a Native Turbo Module, Native Fabric Component, or both set up in your project, and valid specification files in the `jsSrcsDir`, follow these steps: 7808 7809#### Android 7810 7811**Codegen** for Android is integrated with the React Native Gradle Plugin (RNGP). The RNGP task reads configurations from `package.json` and executes **Codegen**. Run this command inside the `android` folder of your project: 7812 7813```bash 7814./gradlew generateCodegenArtifactsFromSchema 7815``` 7816 7817This generates code in the corresponding `node_modules/<dependency>/android/build/generated/source/codegen` folder. 7818 7819##### The Generated Code 7820 7821After running the gradle task, find the generated code in the `SampleApp/android/app/build` folder. The structure is: 7822 7823``` 7824build 7825└── generated 7826 └── source 7827 └── codegen 7828 ├── java 7829 │ └── com 7830 │ ├── facebook 7831 │ │ └── react 7832 │ │ └── viewmanagers 7833 │ │ ├── <nativeComponent>ManagerDelegate.java 7834 │ │ └── <nativeComponent>ManagerInterface.java 7835 │ └── sampleapp 7836 │ └── NativeLocalStorageSpec.java 7837 ├── jni 7838 │ ├── <codegenConfig.name>-generated.cpp 7839 │ ├── <codegenConfig.name>.h 7840 │ ├── react 7841 │ │ └── renderer 7842 │ │ └── components 7843 │ │ ├── <codegenConfig.name> 7844 │ │ │ ├── ComponentDescriptors.cpp 7845 │ │ │ ├── ComponentDescriptors.h 7846 │ │ │ ├── EventEmitters.cpp 7847 │ │ │ ├── EventEmitters.h 7848 │ │ │ ├── Props.cpp 7849 │ │ │ ├── Props.h 7850 │ │ │ ├── RCTComponentViewHelpers.h 7851 │ │ │ ├── ShadowNodes.cpp 7852 │ │ │ ├── ShadowNodes.h 7853 │ │ │ └── States.cpp 7854 │ │ └── schema.json 7855 └── schema.json 7856``` 7857 7858The generated code is split into: 7859 7860- `java`: Platform-specific code. 7861- `jni`: C++ code for JS and Java interaction. 7862 7863In the `java` folder, Fabric Native component code resides in `com/facebook/viewmanagers`, including: 7864 7865- `<nativeComponent>ManagerDelegate.java`: Methods callable by `ViewManager`. 7866- `<nativeComponent>ManagerInterface.java`: Interface of the `ViewManager`. 7867 7868The Turbo Native Module abstract class is in the folder specified by `codegenConfig.android.javaPackageName`. 7869 7870In the `jni` folder, you find: 7871 7872- `<codegenConfig.name>.h`: Interface for custom C++ Turbo Native Modules. 7873- `<codegenConfig.name>-generated.cpp`: Glue code for custom C++ Turbo Native Modules. 7874- `react/renderer/components/<codegenConfig.name>`: Glue-code for your component. 7875 7876This structure is generated using the value `all` for `codegenConfig.type`. Use `modules` to exclude `react/renderer/components/`, and `components` to exclude other files. 7877 7878#### iOS 7879 7880**Codegen** for iOS uses Node scripts invoked during the build process, located in `SampleApp/node_modules/react-native/scripts/`. 7881 7882The main script is `generate-codegen-artifacts.js`. Invoke it from your app's root folder: 7883 7884```bash 7885node node_modules/react-native/scripts/generate-codegen-artifacts.js 7886 7887Usage: generate-codegen-artifacts.js -p [path to app] -t [target platform] -o [output path] 7888 7889Options: 7890 --help Show help [boolean] 7891 --version Show version number [boolean] 7892 -p, --path Path to the React Native project root. [required] 7893 -t, --targetPlatform Target platform. Supported values: "android", "ios", 7894 "all". [required] 7895 -o, --outputPath Path where generated artifacts will be output to. 7896``` 7897 7898Arguments: 7899 7900- `--path`: Path to the app's root folder. 7901- `--outputPath`: Destination for generated files. 7902- `--targetPlatform`: Platform for code generation. 7903 7904##### The Generated Code 7905 7906Run this command to generate files in the `ios/build` folder: 7907 7908```bash 7909node node_modules/react-native/scripts/generate-codegen-artifacts.js \ 7910 --path . \ 7911 --outputPath ios/ \ 7912 --targetPlatform ios 7913``` 7914 7915Generated files include: 7916 7917``` 7918build 7919└── generated 7920 └── ios 7921 ├── <codegenConfig.name> 7922 │ ├── <codegenConfig.name>-generated.mm 7923 │ └── <codegenConfig.name>.h 7924 ├── <codegenConfig.name>JSI-generated.cpp 7925 ├── <codegenConfig.name>JSI.h 7926 ├── FBReactNativeSpec 7927 │ ├── FBReactNativeSpec-generated.mm 7928 │ └── FBReactNativeSpec.h 7929 ├── FBReactNativeSpecJSI-generated.cpp 7930 ├── FBReactNativeSpecJSI.h 7931 ├── RCTModulesConformingToProtocolsProvider.h 7932 ├── RCTModulesConformingToProtocolsProvider.mm 7933 └── react 7934 └── renderer 7935 └── components 7936 └── <codegenConfig.name> 7937 ├── ComponentDescriptors.cpp 7938 ├── ComponentDescriptors.h 7939 ├── EventEmitters.cpp 7940 ├── EventEmitters.h 7941 ├── Props.cpp 7942 ├── Props.h 7943 ├── RCTComponentViewHelpers.h 7944 ├── ShadowNodes.cpp 7945 ├── ShadowNodes.h 7946 └── States.cpp 7947``` 7948 7949Files include: 7950 7951- `<codegenConfig.name>/<codegenConfig.name>.h`: Interface for custom iOS Turbo Native Modules. 7952- `<codegenConfig.name>/<codegenConfig.name>-generated.mm`: Glue code for custom iOS Turbo Native Modules. 7953- `<codegenConfig.name>JSI.h`: Interface for custom C++ Turbo Native Modules. 7954- `<codegenConfig.name>JSI-generated.cpp`: Glue code for custom C++ Turbo Native Modules. 7955- `react/renderer/components/<codegenConfig.name>`: Glue-code for your component. 7956 7957This structure is generated using the value `all` for `codegenConfig.type`. Use `modules` to exclude `react/renderer/components/`, and `components` to exclude other files. 7958 7959## The Codegen CLI 7960 7961The **Codegen** CLI simplifies running tasks by eliminating the need to remember complex commands or manually execute scripts. It facilitates executing `@react-native/codegen` for React Native projects with ease. 7962 7963### Usage 7964 7965To view available options, use: 7966 7967```sh 7968npx @react-native-community/cli codegen --help 7969``` 7970 7971#### Options 7972 7973- **--verbose**: Increases logging verbosity. 7974- **--path <path>**: Specifies the path to the React Native project root. Default is `/Users/MyUsername/projects/my-app`. 7975- **--platform <string>**: Targets a specific platform. Supported values: `android`, `ios`, `all`. Default is `all`. 7976- **--outputPath <path>**: Defines where generated artifacts will be output. 7977- **-h, --help**: Displays help for the command. 7978 7979### Examples 7980 79811. Generate code based on `package.json` in the current directory: 7982 7983 ```sh 7984 npx @react-native-community/cli codegen 7985 ``` 7986 79871. Generate iOS-specific code using the configuration from `package.json`: 7988 7989 ```sh 7990 npx @react-native-community/cli codegen --platform ios 7991 ``` 7992 79931. Generate Android code for a library located in `third-party/some-library`, outputting to `third-party/some-library/android/generated`: 7994 7995 ```sh 7996 npx @react-native-community/cli codegen \ 7997 --path third-party/some-library \ 7998 --platform android \ 7999 --outputPath third-party/some-library/android/generated 8000 ``` 8001 8002### Including Generated Code in Libraries 8003 8004The **Codegen** CLI is particularly useful for library developers. It allows previewing generated code to determine necessary interfaces. 8005 8006#### Benefits of `includesGeneratedCode = true` 8007 8008- Eliminates dependency on the app to run **Codegen**. 8009- Ensures consistency between implementation files and generated interfaces, enhancing resilience against API changes. 8010- Reduces redundancy by supporting only one architecture set for Android, ensuring backward compatibility. 8011- Enables shipping native code as a prebuild. 8012 8013#### Drawbacks 8014 8015- Generated code will use the React Native version specified in your library. This may lead to compatibility issues with apps using older React Native versions. 8016 8017### Enabling `includesGeneratedCode` 8018 8019To incorporate generated code into your library: 8020 80211. Add `includesGeneratedCode: true` to the `codegenConfig` field in your `package.json`. 80221. Execute **Codegen** locally using the CLI. 80231. Update `package.json`, `podspec`, and `build.gradle` files to include the generated code. 80241. Modify `cmakeListsPath` in `react-native.config.js` to direct Gradle to the correct output directory instead of the build directory. 8025 8026By following these steps, you can streamline your development process and ensure that your library remains compatible with various React Native versions. 8027 8028## Native Platform 8029 8030### Overview 8031 8032This guide covers how to integrate native platform features into your React Native application, which may not be directly accessible through React Native or third-party libraries. It also addresses the reuse of existing code written in Objective-C, Swift, Java, Kotlin, or C++ from within the JavaScript runtime. 8033 8034#### Key Concepts 8035 8036- **Native Modules:** These are native libraries without a user interface (UI). They include functionalities like persistent storage, notifications, and network events, accessible as JavaScript functions and objects. 8037 8038- **Native Components:** These refer to platform-specific views, widgets, and controllers that can be utilized in your application's JavaScript code through React components. 8039 8040> **Note:** Legacy Native Modules and Native Components are deprecated. However, they can still function with the New Architecture via interop layers. Consider: 8041 8042- Using alternative libraries. 8043- Upgrading to newer library versions supporting the New Architecture. 8044- Porting these libraries to Turbo Native Modules or Fabric Native Components. 8045 8046### Sections 8047 80481. **Native Modules** 8049 8050 - Android & iOS 8051 - Cross-Platform with C++ 8052 - Advanced: Custom C++ Types 8053 80541. **Fabric Native Components** 8055 - Android & iOS 8056 8057*** 8058 8059**Previous:** The Codegen CLI\ 8060**Next:** Android and iOS 8061 8062## BackHandler 8063 8064The **BackHandler** API is designed for Android devices to manage hardware button presses related to back navigation. It allows developers to register event listeners and control the application's response to these events. 8065 8066### Key Features 8067 8068- **Event Subscription Order**: Subscriptions are processed in reverse order, meaning the last registered listener is invoked first. 8069- **Subscription Behavior**: 8070 - If a subscription returns `true`, subsequent subscriptions will not be called. 8071 - If no subscription returns `true` or if none are registered, the default back button functionality (exiting the app) is triggered. 8072 8073> **Note for Modal Users**: When an app displays an open `Modal`, `BackHandler` does not trigger any events. Refer to the `Modal` documentation for more details. 8074 8075### Implementation Pattern 8076 8077Below is a TypeScript example demonstrating how to use the BackHandler API: 8078 8079```typescript 8080const subscription = BackHandler.addEventListener( 8081 "hardwareBackPress", 8082 function () { 8083 // Example logic: Check if on main screen or navigate back. 8084 if (!this.onMainScreen()) { 8085 this.goBack() 8086 // Returning true prevents further event propagation. 8087 return true 8088 } 8089 // Returning false allows the event to propagate further. 8090 return false 8091 } 8092) 8093 8094// Ensure to remove the listener when it's no longer needed 8095subscription.remove() 8096``` 8097 8098### Example Scenario 8099 8100Consider a scenario where you need user confirmation before exiting the app. The `BackHandler.addEventListener` method creates an event listener and returns a `NativeEventSubscription` object, which should be removed using the `remove` method. 8101 8102### Integration with React Navigation 8103 8104For those utilizing **React Navigation**, refer to their guide on customizing Android back button behavior for seamless integration. 8105 8106### Using Hooks 8107 8108The **React Native Hooks** library offers a convenient `useBackHandler` hook that simplifies setting up event listeners. 8109 8110*** 8111 8112## Reference Methods 8113 8114#### `addEventListener()` 8115 8116Registers an event listener for the specified event name and returns a subscription object. 8117 8118```typescript 8119static addEventListener( 8120 eventName: BackPressEventName, 8121 handler: () => boolean | null | undefined, 8122): NativeEventSubscription; 8123``` 8124 8125#### `exitApp()` 8126 8127Programmatically exits the application. 8128 8129```typescript 8130static exitApp(); 8131``` 8132 8133## Native Modules 8134 8135To implement a cross-platform `localStorage` solution using React Native's TurboModule system, you need to set up both Android and iOS platforms. Below is a step-by-step guide based on the provided instructions: 8136 8137#### Android Setup 8138 81391. **Define the JavaScript Interface:** 8140 8141 Create a TypeScript file for your module interface. 8142 8143 ```typescript 8144 // specs/NativeLocalStorageSpec.ts 8145 import { TurboModule, TurboModuleRegistry } from 'react-native'; 8146 8147 export interface Spec extends TurboModule { 8148 getItem(key: string): Promise<string | null>; 8149 setItem(value: string, key: string): Promise<void>; 8150 removeItem(key: string): Promise<void>; 8151 clear(): Promise<void>; 8152 } 8153 8154 export default NativeLocalStorage as unknown as typeof TurboModuleRegistry.get<Spec>('NativeLocalStorage'); 8155 ``` 8156 81571. **Implement the Android Module:** 8158 8159 Create a Java class that implements the `NativeLocalStorageSpec`. 8160 8161 ```java 8162 // android/src/main/java/com/nativelocalstorage/NativeLocalStoragePackage.java 8163 package com.nativelocalstorage; 8164 8165 import androidx.annotation.NonNull; 8166 import com.facebook.react.ReactPackage; 8167 import com.facebook.react.bridge.NativeModule; 8168 import com.facebook.react.bridge.ReactApplicationContext; 8169 import com.facebook.react.uimanager.ViewManager; 8170 import java.util.ArrayList; 8171 import java.util.Collections; 8172 import java.util.List; 8173 8174 public class NativeLocalStoragePackage implements ReactPackage { 8175 @NonNull 8176 @Override 8177 public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) { 8178 List<NativeModule> modules = new ArrayList<>(); 8179 modules.add(new NativeLocalStorage(reactContext)); 8180 return modules; 8181 } 8182 8183 @Override 8184 public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) { 8185 return Collections.emptyList(); 8186 } 8187 } 8188 ``` 8189 8190 ```java 8191 // android/src/main/java/com/nativelocalstorage/NativeLocalStorage.java 8192 package com.nativelocalstorage; 8193 8194 import androidx.annotation.NonNull; 8195 import com.facebook.react.bridge.Promise; 8196 import com.facebook.react.bridge.ReactApplicationContext; 8197 import com.facebook.react.bridge.ReactContextBaseJavaModule; 8198 import com.facebook.react.module.annotations.ReactModule; 8199 import java.util.HashMap; 8200 import java.util.Map; 8201 8202 @ReactModule(name = NativeLocalStorage.NAME) 8203 public class NativeLocalStorage extends ReactContextBaseJavaModule { 8204 public static final String NAME = "NativeLocalStorage"; 8205 8206 private final Map<String, String> storage = new HashMap<>(); 8207 8208 public NativeLocalStorage(@NonNull ReactApplicationContext reactContext) { 8209 super(reactContext); 8210 } 8211 8212 @Override 8213 @NonNull 8214 public String getName() { 8215 return NAME; 8216 } 8217 8218 @ReactMethod 8219 public void getItem(String key, Promise promise) { 8220 promise.resolve(storage.get(key)); 8221 } 8222 8223 @ReactMethod 8224 public void setItem(String value, String key, Promise promise) { 8225 storage.put(key, value); 8226 promise.resolve(null); 8227 } 8228 8229 @ReactMethod 8230 public void removeItem(String key, Promise promise) { 8231 storage.remove(key); 8232 promise.resolve(null); 8233 } 8234 8235 @ReactMethod 8236 public void clear(Promise promise) { 8237 storage.clear(); 8238 promise.resolve(null); 8239 } 8240 } 8241 ``` 8242 82431. **Register the Package:** 8244 8245 Update your `MainApplication.java` to include the new package. 8246 8247 ```java 8248 // android/app/src/main/java/com/yourapp/MainApplication.java 8249 import com.nativelocalstorage.NativeLocalStoragePackage; 8250 8251 @Override 8252 protected List<ReactPackage> getPackages() { 8253 return Arrays.<ReactPackage>asList( 8254 new MainReactPackage(), 8255 new NativeLocalStoragePackage() 8256 ); 8257 } 8258 ``` 8259 8260#### iOS Setup 8261 82621. **Prepare the Xcode Project:** 8263 8264 - Open `TurboModuleExample.xcworkspace`. 8265 - Create a group named `NativeLocalStorage`. 8266 - Add a new Objective-C++ file `RCTNativeLocalStorage.mm`. 8267 82681. **Implement the Module Interface:** 8269 8270 Update `RCTNativeLocalStorage.h` and `RCTNativeLocalStorage.mm`. 8271 8272 ```objc 8273 // NativeLocalStorage/RCTNativeLocalStorage.h 8274 #import <Foundation/Foundation.h> 8275 #import <NativeLocalStorageSpec/NativeLocalStorageSpec.h> 8276 8277 NS_ASSUME_NONNULL_BEGIN 8278 8279 @interface RCTNativeLocalStorage : NSObject <NativeLocalStorageSpec> 8280 @end 8281 8282 NS_ASSUME_NONNULL_END 8283 ``` 8284 8285 ```objc 8286 // NativeLocalStorage/RCTNativeLocalStorage.mm 8287 #import "RCTNativeLocalStorage.h" 8288 8289 static NSString *const RCTNativeLocalStorageKey = @"local-storage"; 8290 8291 @interface RCTNativeLocalStorage() 8292 @property (strong, nonatomic) NSUserDefaults *localStorage; 8293 @end 8294 ``` 8295 8296@implementation RCTNativeLocalStorage 8297 8298- (instancetype)init { if (self = \[super init]) { \_localStorage = \[\[NSUserDefaults alloc] initWithSuiteName:RCTNativeLocalStorageKey]; } return self; } 8299 8300- (std::shared\_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { return std::make\_shared<facebook::react::NativeLocalStorageSpecJSI>(params); } 8301 8302- (NSString \* \_Nullable)getItem:(NSString \*)key { return \[self.localStorage stringForKey:key]; } 8303 8304- (void)setItem:(NSString \*)value key:(NSString \*)key { \[self.localStorage setObject:value forKey:key]; } 8305 8306- (void)removeItem:(NSString \*)key { \[self.localStorage removeObjectForKey:key]; } 8307 8308- (void)clear { NSDictionary \*keys = \[self.localStorage dictionaryRepresentation]; for (NSString \*key in keys) { \[self removeItem:key]; } } 8309 8310* (NSString \*)moduleName { return @"NativeLocalStorage"; } 8311 8312@end 8313 8314```` 8315 83163. **Register the Module:** 8317 8318Update `package.json` to link the JS interface with the native implementation. 8319 8320```json 8321"codegenConfig": { 8322 "name": "AppSpecs", 8323 "type": "modules", 8324 "jsSrcsDir": "specs", 8325 "android": { 8326 "javaPackageName": "com.sampleapp.specs" 8327 }, 8328 "ios": { 8329 "modulesProvider": { 8330 "NativeLocalStorage": "RCTNativeLocalStorage" 8331 } 8332 } 8333} 8334```` 8335 83364. **Reinstall Pods:** 8337 8338 Run the following commands to ensure everything is set up correctly. 8339 8340 ```bash 8341 bundle exec pod install 8342 open TurboModuleExample.xcworkspace 8343 ``` 8344 8345#### Build and Run 8346 8347- For Android: 8348 8349 ```bash 8350 npm run android 8351 # or 8352 yarn run android 8353 ``` 8354 8355- For iOS: 8356 8357 ```bash 8358 npm run ios 8359 # or 8360 yarn run ios 8361 ``` 8362 8363This setup provides a consistent `localStorage` API across both platforms using React Native's TurboModule system. 8364 8365## Cross-Platform Native Modules (C++) 8366 8367Creating a cross-platform native module using C++ is an efficient way to share platform-agnostic code between Android and iOS. This guide walks through the process of creating a pure C++ Turbo Native Module, which allows you to write your logic once and reuse it across platforms. 8368 8369#### Prerequisites 8370 8371Ensure you have the following setup: 8372 8373- React Native environment set up for both Android and iOS. 8374- Basic understanding of C++, Objective-C, and JavaScript/TypeScript. 8375 8376#### Steps to Create a C++ Turbo Native Module 8377 8378##### 1. Set Up Your Project 8379 8380Start by creating a new React Native project if you haven't already: 8381 8382```bash 8383npx react-native init SampleApp 8384cd SampleApp 8385``` 8386 8387##### 2. Define the JS Spec 8388 8389Create a TypeScript file for your module spec in `specs/NativeSampleModule.ts`: 8390 8391```typescript 8392import { TurboModule } from "react-native" 8393 8394export interface Spec extends TurboModule { 8395 reverseString(value: string): string 8396} 8397 8398export default NativeModules.NativeSampleModule as Spec | null 8399``` 8400 8401##### 3. Implement the C++ Module 8402 8403###### Android Implementation 8404 84051. **Create Header and Source Files** 8406 8407 Create `NativeSampleModule.h`: 8408 8409 ```cpp 8410 #pragma once 8411 8412 #include <react/TurboModule.h> 8413 #include <react/uimanager/ViewManager.h> 8414 8415 namespace facebook { 8416 namespace react { 8417 8418 class NativeSampleModule : public TurboModule { 8419 public: 8420 using TurboModule::TurboModule; 8421 8422 virtual ~NativeSampleModule() = default; 8423 8424 DECLARE_TURBO_MODULE(NativeSampleModule, TurboModule); 8425 static constexpr auto kName = "NativeSampleModule"; 8426 8427 virtual std::string reverseString(std::string value) = 0; 8428 }; 8429 8430 } // namespace react 8431 } // namespace facebook 8432 8433 #ifdef __cplusplus 8434 extern "C" { 8435 #endif 8436 8437 JNIEXPORT void JNICALL 8438 Java_com_sampleapp_NativeSampleModule_init(JNIEnv* env, jclass clazz); 8439 8440 #ifdef __cplusplus 8441 } 8442 #endif 8443 ``` 8444 8445 Create `NativeSampleModule.cpp`: 8446 8447 ```cpp 8448 #include "NativeSampleModule.h" 8449 8450 namespace facebook { 8451 namespace react { 8452 8453 class NativeSampleModuleImpl : public NativeSampleModule { 8454 public: 8455 explicit NativeSampleModuleImpl(const std::shared_ptr<CallInvoker>& jsInvoker) 8456 : TurboModule("NativeSampleModule", jsInvoker) {} 8457 8458 std::string reverseString(std::string value) override { 8459 std::reverse(value.begin(), value.end()); 8460 return value; 8461 } 8462 }; 8463 8464 // Register the module 8465 void registerNativeSampleModule( 8466 ReactApplicationContext& context, 8467 const std::shared_ptr<CallInvoker>& jsInvoker) { 8468 auto moduleHolder = std::make_shared<std::weak_ptr<NativeSampleModule>>(); 8469 getOrSetTurboModule(context, *moduleHolder, NativeSampleModule::kName, []() -> std::shared_ptr<TurboModule> { 8470 return std::make_shared<NativeSampleModuleImpl>(jsInvoker); 8471 }); 8472 } 8473 8474 } // namespace react 8475 } // namespace facebook 8476 8477 #ifdef __cplusplus 8478 extern "C" { 8479 #endif 8480 8481 JNIEXPORT void JNICALL 8482 Java_com_sampleapp_NativeSampleModule_init(JNIEnv* env, jclass clazz) { 8483 auto& context = getReactApplicationContext(); 8484 auto jsInvoker = getJavaScriptCallInvoker(context); 8485 facebook::react::registerNativeSampleModule(context, jsInvoker); 8486 } 8487 8488 #ifdef __cplusplus 8489 } 8490 #endif 8491 ``` 8492 84931. **Register the Module in Java** 8494 8495 Create `com/sampleapp/NativeSampleModule.java`: 8496 8497 ```java 8498 package com.sampleapp; 8499 8500 import com.facebook.react.bridge.ReactApplicationContext; 8501 import com.facebook.react.bridge.ReactContextBaseJavaModule; 8502 import com.facebook.react.module.annotations.ReactModule; 8503 import com.facebook.react.turbomodule.core.interfaces.TurboModule; 8504 import com.facebook.react.turbomodule.core.internal.TurboReactPackage; 8505 8506 @ReactModule(name = NativeSampleModule.NAME) 8507 public class NativeSampleModule extends ReactContextBaseJavaModule { 8508 static final String NAME = "NativeSampleModule"; 8509 8510 private final TurboReactPackage mTurboReactPackage; 8511 8512 public NativeSampleModule(ReactApplicationContext reactContext, TurboReactPackage turboReactPackage) { 8513 super(reactContext); 8514 mTurboReactPackage = turboReactPackage; 8515 } 8516 8517 @Override 8518 public String getName() { 8519 return NAME; 8520 } 8521 8522 static void registerNativeModules(ReactPackageList packages, ReactApplicationContext context) { 8523 packages.add(new NativeSampleModule(context, (TurboReactPackage) packages.get(0))); 8524 } 8525 } 8526 ``` 8527 85281. **Modify `MainApplication.java`** 8529 8530 Ensure your `MainApplication.java` includes the Turbo module package: 8531 8532 ```java 8533 import com.facebook.react.ReactNativeHost; 8534 import com.facebook.react.ReactPackage; 8535 import com.facebook.react.shell.MainReactPackage; 8536 import com.facebook.soloader.SoLoader; 8537 import java.util.List; 8538 8539 public class MainApplication extends Application implements ReactApplication { 8540 private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 8541 @Override 8542 public boolean getUseDeveloperSupport() { 8543 return BuildConfig.DEBUG; 8544 } 8545 8546 @Override 8547 protected List<ReactPackage> getPackages() { 8548 List<ReactPackage> packages = new PackageList(this).getPackages(); 8549 packages.add(new MainReactPackage()); 8550 // Add this line 8551 packages.add(new TurboReactPackage()); 8552 return packages; 8553 } 8554 }; 8555 8556 @Override 8557 public ReactNativeHost getReactNativeHost() { 8558 return mReactNativeHost; 8559 } 8560 8561 @Override 8562 public void onCreate() { 8563 super.onCreate(); 8564 SoLoader.init(this, /* native exopackage */ false); 8565 } 8566 } 8567 ``` 8568 8569###### iOS Implementation 8570 85711. **Create the Module Provider** 8572 8573 Create `SampleNativeModuleProvider.mm`: 8574 8575 ```objc 8576 #import "SampleNativeModuleProvider.h" 8577 #import <React/RCTBridge+Private.h> 8578 #import <ReactCommon/TurboModule.h> 8579 #import "NativeSampleModule.h" 8580 8581 @implementation SampleNativeModuleProvider 8582 8583 - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { 8584 return std::make_shared<facebook::react::NativeSampleModule>(params.jsInvoker); 8585 } 8586 8587 @end 8588 ``` 8589 85901. **Register the Module in `package.json`** 8591 8592 Update your `package.json`: 8593 8594 ```json 8595 "codegenConfig": { 8596 "name": "AppSpecs", 8597 "type": "modules", 8598 "jsSrcsDir": "specs", 8599 "android": { 8600 "javaPackageName": "com.sampleapp" 8601 }, 8602 "ios": { 8603 "modulesProvider": { 8604 "NativeSampleModule": "SampleNativeModuleProvider" 8605 } 8606 } 8607 } 8608 ``` 8609 86101. **Reinstall Pods** 8611 8612 Run the following commands in the `ios` directory: 8613 8614 ```bash 8615 bundle install 8616 bundle exec pod install 8617 open SampleApp.xcworkspace 8618 ``` 8619 8620##### 4. Test Your Module 8621 8622Modify `App.tsx` to use your Turbo Native Module: 8623 8624```tsx 8625import React, { useState } from "react" 8626import { 8627 Button, 8628 SafeAreaView, 8629 StyleSheet, 8630 Text, 8631 TextInput, 8632 View, 8633} from "react-native" 8634import SampleTurboModule from "./specs/NativeSampleModule" 8635 8636function App(): JSX.Element { 8637 const [value, setValue] = useState("") 8638 const [reversedValue, setReversedValue] = useState("") 8639 8640 const onPress = () => { 8641 const revString = SampleTurboModule?.reverseString(value) || "" 8642 setReversedValue(revString) 8643 } 8644 8645 return ( 8646 <SafeAreaView style={styles.container}> 8647 <View> 8648 <Text style={styles.title}> 8649 Welcome to C++ Turbo Native Module Example 8650 </Text> 8651 <TextInput 8652 style={styles.textInput} 8653 placeholder="Write your text here" 8654 onChangeText={setValue} 8655 value={value} 8656 /> 8657 <Button title="Reverse" onPress={onPress} /> 8658 <Text>Reversed text: {reversedValue}</Text> 8659 </View> 8660 </SafeAreaView> 8661 ) 8662} 8663 8664const styles = StyleSheet.create({ 8665 container: { 8666 flex: 1, 8667 justifyContent: "center", 8668 alignItems: "center", 8669 }, 8670 title: { 8671 fontSize: 18, 8672 marginBottom: 20, 8673 }, 8674 textInput: { 8675 borderColor: "black", 8676 borderWidth: 1, 8677 borderRadius: 5, 8678 padding: 10, 8679 marginTop: 10, 8680 }, 8681}) 8682 8683export default App 8684``` 8685 8686#### Conclusion 8687 8688You've successfully created a C++ Turbo Native Module that works on both Android and iOS. This setup allows you to write platform-agnostic code in C++, reducing redundancy and improving maintainability across platforms. 8689 8690## Native Components 8691 8692To create a native web view component in React Native, you need to implement platform-specific code for both Android and iOS. Below is a step-by-step guide on how to achieve this: 8693 8694#### Step 1: Set Up Your Project 8695 8696Ensure your project is set up with the necessary dependencies for React Native development. 8697 8698```bash 8699npx react-native init WebViewDemo 8700cd WebViewDemo 8701``` 8702 8703#### Step 2: Run Codegen 8704 8705Codegen helps generate boilerplate code based on your component specifications. This step is crucial for both Android and iOS platforms. 8706 8707##### For iOS: 8708 87091. Navigate to the `ios` directory: 8710 8711 ```bash 8712 cd ios 8713 ``` 8714 87151. Install dependencies using CocoaPods: 8716 8717 ```bash 8718 bundle install 8719 bundle exec pod install 8720 ``` 8721 87221. Open the generated Xcode workspace: 8723 ```bash 8724 open Demo.xcworkspace 8725 ``` 8726 8727##### For Android: 8728 87291. Navigate to the `android` directory: 8730 8731 ```bash 8732 cd android 8733 ``` 8734 87351. Run Codegen using your terminal or command prompt. 8736 8737#### Step 3: Implement Native Components 8738 8739##### Android Implementation 8740 87411. **Create a New Group**: In Android Studio, right-click on the app and select `New → Directory`. Name it `WebView`. 8742 87431. **Add Java Files**: 8744 8745 - Create `RCTWebView.java` and `RCTWebViewPackage.java`. 8746 87471. **Implement RCTWebView\.java**: 8748 8749```java 8750package com.webviewdemo; 8751 8752import android.content.Context; 8753import android.util.AttributeSet; 8754import androidx.annotation.Nullable; 8755import com.facebook.react.uimanager.SimpleViewManager; 8756import com.facebook.react.uimanager.ThemedReactContext; 8757import com.facebook.react.views.view.ReactViewGroup; 8758import android.webkit.WebView; 8759import android.webkit.WebViewClient; 8760 8761public class RCTWebView extends ReactViewGroup { 8762 8763 private WebView webView; 8764 8765 public RCTWebView(ThemedReactContext context) { 8766 super(context); 8767 init(); 8768 } 8769 8770 public RCTWebView(Context context, @Nullable AttributeSet attrs) { 8771 super(context, attrs); 8772 init(); 8773 } 8774 8775 private void init() { 8776 webView = new WebView(getContext()); 8777 addView(webView); 8778 webView.setWebViewClient(new WebViewClient() { 8779 @Override 8780 public void onPageFinished(WebView view, String url) { 8781 // Emit event when page is loaded 8782 } 8783 }); 8784 } 8785 8786 public void loadUrl(String url) { 8787 webView.loadUrl(url); 8788 } 8789} 8790``` 8791 87924. **Implement RCTWebViewPackage.java**: 8793 8794```java 8795package com.webviewdemo; 8796 8797import androidx.annotation.NonNull; 8798import com.facebook.react.ReactPackage; 8799import com.facebook.react.bridge.NativeModule; 8800import com.facebook.react.bridge.ReactApplicationContext; 8801import com.facebook.react.uimanager.ViewManager; 8802import java.util.ArrayList; 8803import java.util.Collections; 8804import java.util.List; 8805 8806public class RCTWebViewPackage implements ReactPackage { 8807 8808 @NonNull 8809 @Override 8810 public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) { 8811 return Collections.emptyList(); 8812 } 8813 8814 @NonNull 8815 @Override 8816 public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) { 8817 List<ViewManager> viewManagers = new ArrayList<>(); 8818 viewManagers.add(new RCTWebViewManager()); 8819 return viewManagers; 8820 } 8821} 8822``` 8823 88245. **Register the Package**: Add `RCTWebViewPackage` to your `MainApplication.java`. 8825 8826```java 8827@Override 8828protected List<ReactPackage> getPackages() { 8829 return Arrays.<ReactPackage>asList( 8830 new MainReactPackage(), 8831 new RCTWebViewPackage() 8832 ); 8833} 8834``` 8835 8836##### iOS Implementation 8837 88381. **Create Files**: In Xcode, create `RCTWebView.h` and `RCTWebView.mm`. 8839 88401. **Implement RCTWebView\.h**: 8841 8842```objc 8843#import <React/RCTViewComponentView.h> 8844#import <UIKit/UIKit.h> 8845 8846NS_ASSUME_NONNULL_BEGIN 8847 8848@interface RCTWebView : RCTViewComponentView 8849 8850@end 8851 8852NS_ASSUME_NONNULL_END 8853``` 8854 88553. **Implement RCTWebView\.mm**: 8856 8857```objc 8858#import "RCTWebView.h" 8859#import <WebKit/WebKit.h> 8860 8861@implementation RCTWebView { 8862 NSURL *_sourceURL; 8863 WKWebView *_webView; 8864} 8865 8866- (instancetype)init { 8867 if (self = [super init]) { 8868 _webView = [[WKWebView alloc] initWithFrame:CGRectZero]; 8869 [_webView setNavigationDelegate:self]; 8870 [self addSubview:_webView]; 8871 } 8872 return self; 8873} 8874 8875- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps { 8876 auto newViewProps = *std::static_pointer_cast<CustomWebViewProps const>(props); 8877 NSString *urlString = [NSString stringWithCString:newViewProps.sourceURL.c_str() encoding:NSUTF8StringEncoding]; 8878 _sourceURL = [NSURL URLWithString:urlString]; 8879 8880 if (_sourceURL) { 8881 [_webView loadRequest:[NSURLRequest requestWithURL:_sourceURL]]; 8882 } 8883} 8884 8885- (void)layoutSubviews { 8886 [super layoutSubviews]; 8887 _webView.frame = self.bounds; 8888} 8889 8890#pragma mark - WKNavigationDelegate 8891 8892- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { 8893 // Emit event when page is loaded 8894} 8895 8896@end 8897``` 8898 8899#### Step 4: Use Your Native Component in React Native 8900 8901Update your `App.tsx` to use the new WebView component: 8902 8903```tsx 8904import React from "react" 8905import { Alert, StyleSheet, View } from "react-native" 8906import { WebView as CustomWebView } from "./specs/WebViewNativeComponent" 8907 8908function App(): React.JSX.Element { 8909 return ( 8910 <View style={styles.container}> 8911 <CustomWebView 8912 sourceURL="https://react.dev/" 8913 style={styles.webview} 8914 onScriptLoaded={() => Alert.alert("Page Loaded")} 8915 /> 8916 </View> 8917 ) 8918} 8919 8920const styles = StyleSheet.create({ 8921 container: { 8922 flex: 1, 8923 alignItems: "center", 8924 justifyContent: "center", 8925 }, 8926 webview: { 8927 width: "100%", 8928 height: "100%", 8929 }, 8930}) 8931 8932export default App 8933``` 8934 8935#### Step 5: Run Your App 8936 8937##### Android: 8938 8939```bash 8940npx react-native run-android 8941``` 8942 8943##### iOS: 8944 8945```bash 8946npx react-native run-ios 8947``` 8948 8949This setup will allow you to use a native web view component in your React Native application, providing better performance and integration with platform-specific features. 8950 8951## Appendix 8952 8953### I. Terminology 8954 8955- **Spec**: TypeScript or Flow code that defines the API for a Turbo Native Module or Fabric Native component. Utilized by **Codegen** to generate boilerplate code. 8956 8957- **Native Modules**: Native libraries without a User Interface (UI) for users, such as persistent storage, notifications, and network events. These are accessible in your JavaScript application code as functions and objects. 8958 8959- **Native Component**: Native platform views available to your application's JavaScript code through React Components. 8960 8961- **Legacy Native Components**: Components operating on the old React Native architecture. 8962 8963- **Legacy Native Modules**: Modules functioning on the old React Native architecture. 8964 8965### II. Codegen Typings 8966 8967The following table serves as a reference for supported types and their mappings across different platforms: 8968 8969|Flow|TypeScript|Flow Nullable Support|TypeScript Nullable Support|Android (Java)|iOS (ObjC)| 8970|-|-|-|-|-|-| 8971|`string`|`string`|`?string`|`string \| null`|`string`|`NSString`| 8972|`boolean`|`boolean`|`?boolean`|`boolean \| null`|`Boolean`|`NSNumber`| 8973|Object Literal `{ foo: string, ...}`|`{ foo: string, ...} as const`|`?{ foo: string, ...}`|`?{ foo: string, ...} as const`|-|-| 8974|Object \[1]|Object \[1]|`?Object`|`Object \| null`|`ReadableMap`|`@` (untyped dictionary)| 8975|`Array<T>`|`Array<T>`|`?Array<T>`|`Array<T> \| null`|`ReadableArray`|`NSArray` (or `RCTConvertVecToArray` when used inside objects)| 8976|`Function`|`Function`|`?Function`|`Function \| null`|-|-| 8977|`Promise<T>`|`Promise<T>`|`?Promise<T>`|`Promise<T> \| null`|`com.facebook.react.bridge.Promise`|`RCTPromiseResolve` and `RCTPromiseRejectBlock`| 8978|Type Unions `'SUCCESS'\|'FAIL'`|Type Unions `'SUCCESS'\|'FAIL'`|Only as callbacks||-|-| 8979|Callbacks `() =>`|Callbacks `() =>`|Yes||`com.facebook.react.bridge.Callback`|`RCTResponseSenderBlock`| 8980|`number`|`number`|No||`double`|`NSNumber`| 8981 8982#### Notes: 8983 8984**\[1]** It is strongly recommended to use Object literals instead of Objects. 8985 8986For additional reference, consider the JavaScript specifications for core modules in React Native located within the `Libraries/` directory of the React Native repository. 8987 8988## Guide: Extracting and Distributing a React Native Module as a Library 8989 8990React Native offers an extensive ecosystem of libraries to address common challenges. The [reactnative.directory](https://reactnative.directory) is a valuable resource for developers, providing a collection of these libraries. 8991 8992If you're working on a module that could be beneficial across multiple apps or the broader community, consider extracting it into a separate library. This guide will walk you through: 8993 8994- Extracting a module into a library 8995- Distributing the library using NPM 8996 8997### Extracting the Module into a Library 8998 8999To extract a module into its own library, use the `create-react-native-library` tool. It sets up all necessary boilerplate code and configuration files for various platforms. 9000 9001#### Steps to Create a Library 9002 90031. **Create the New Library** 9004 9005 Start by running: 9006 9007 ```sh 9008 npx create-react-native-library@latest <Name of Your Library> 9009 ``` 9010 90111. Provide details such as: 9012 9013 - A valid npm name (all lowercase, using `-` for word separation) 9014 - A description for your package 9015 90161. Follow the interactive menu until you reach the question: *"What type of library do you want to develop?"* 9017 90181. Select *Turbo module* for this guide. You can create libraries for both New and Legacy Architectures. 9019 90201. Choose whether your library will access platform-specific code (Kotlin & Objective-C) or use a shared C++ library. 9021 90221. Opt for the `Test App` option, which sets up a separate app within the library folder. 9023 9024After completing these steps, you'll have a structured project in Visual Studio Code: 9025 9026- **Android**: Contains Android-specific code. 9027- **CPP**: Houses C++ code. 9028- **iOS**: Includes iOS-specific code. 9029- **Src**: Holds JavaScript code. 9030 9031The `package.json` is pre-configured with necessary details and includes a setup for running Codegen: 9032 9033```json 9034"codegenConfig": { 9035 "name": "RN<your module name>Spec", 9036 "type": "all", 9037 "jsSrcsDir": "src", 9038 "outputDir": { 9039 "ios": "ios/generated", 9040 "android": "android/generated" 9041 }, 9042 "android": { 9043 "javaPackageName": "com.<name-of-the-module>" 9044 } 9045} 9046``` 9047 9048The library is ready to be linked with iOS and Android. 9049 9050#### Copy the Code from Your App 9051 9052Assuming you have a local Turbo Native Module in your app, follow these steps: 9053 90541. **\[Not required for legacy architecture modules]** Move code from the `specs` folder in your app to the `src` folder of the new library. 9055 90561. Update the `index.ts` file to export the Turbo Native Module spec: 9057 9058 ```typescript 9059 import NativeSampleModule from "./NativeSampleModule" 9060 9061 export default NativeSampleModule 9062 ``` 9063 90641. Copy native module code: 9065 9066 - Replace content in `android/src/main/java/com/<name-of-the-module>` with your app's native module code. 9067 - Update the `ios` folder with your iOS native module code. 9068 - Modify the `cpp` folder with your C++ native module code. 9069 90701. **\[Not required for legacy architecture modules]** Update references from the old spec name to the new one defined in `codegenConfig.name`. 9071 9072### Testing Your Library 9073 9074The tool provides an example application configured to work with your library, ideal for testing: 9075 90761. Navigate to the `example` folder. 90771. Run `yarn install`. 90781. For iOS, run `cd ios && pod install`. 90791. Build and run Android with `yarn android`. 90801. Build and run iOS with `yarn ios`. 9081 9082### Using Your Library as a Local Module 9083 9084To reuse your library locally without publishing: 9085 90861. Add the library to your app by running `yarn add ../Library` in the `App` folder. 9087 90881. For iOS, navigate to `App/ios` and run `bundle exec pod install`. 9089 90901. Update `App.tsx` to import from your library: 9091 9092 ```typescript 9093 import NativeSampleModule from "../Library/src/index" 9094 ``` 9095 90961. Modify `metro.config.js` to include the library's path: 9097 9098 ```diff 9099 const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 9100 const path = require('path'); 9101 9102 const config = { 9103 watchFolders: [ 9104 path.resolve(__dirname, '../Library'), 9105 ], 9106 resolver: { 9107 extraNodeModules: { 9108 'react-native': path.resolve(__dirname, 'node_modules/react-native'), 9109 }, 9110 }, 9111 }; 9112 9113 module.exports = mergeConfig(getDefaultConfig(__dirname), config); 9114 ``` 9115 91161. Build and run your app: 9117 - Android: `yarn android` 9118 - iOS: `yarn ios` 9119 9120### Publishing the Library on NPM 9121 9122The setup for publishing is ready: 9123 91241. Install dependencies with `yarn install`. 91251. Build the library using `yarn prepare`. 91261. Release it via `yarn release`. 9127 9128Verify your library's presence on NPM: 9129 9130```bash 9131npm view <package.name> 9132``` 9133 9134Install in your application with: 9135 9136```bash 9137yarn add <package.name> 9138``` 9139 9140**Note**: For iOS, reinstall CocoaPods after adding a new module by running `bundle exec pod install` or `pod install`. 9141 9142Congratulations! You've published your first React Native library. 9143 9144## ToastAndroid 9145 9146The `ToastAndroid` API in React Native provides access to Android's native toast notifications. It offers methods for displaying short or long messages with optional positioning and offset adjustments. 9147 9148### Methods 9149 9150#### `show()` 9151 9152Displays a simple toast message on the screen. 9153 9154```typescript 9155static show(message: string, duration: number): void; 9156``` 9157 9158- **message**: The text content of the toast. 9159- **duration**: Duration of the toast display. Use either `ToastAndroid.SHORT` or `ToastAndroid.LONG`. 9160 9161#### `showWithGravity()` 9162 9163Displays a toast with specified gravity (position). This method is applicable only on Android API 29 and below. 9164 9165```typescript 9166static showWithGravity(message: string, duration: number, gravity: number): void; 9167``` 9168 9169- **message**: The text content of the toast. 9170- **duration**: Duration of the toast display. Use either `ToastAndroid.SHORT` or `ToastAndroid.LONG`. 9171- **gravity**: Position on the screen—options are `ToastAndroid.TOP`, `ToastAndroid.BOTTOM`, or `ToastAndroid.CENTER`. 9172 9173#### `showWithGravityAndOffset()` 9174 9175Displays a toast with specified gravity and offset. This method is applicable only on Android API 29 and below. 9176 9177```typescript 9178static showWithGravityAndOffset( 9179 message: string, 9180 duration: number, 9181 gravity: number, 9182 xOffset: number, 9183 yOffset: number 9184): void; 9185``` 9186 9187- **message**: The text content of the toast. 9188- **duration**: Duration of the toast display. Use either `ToastAndroid.SHORT` or `ToastAndroid.LONG`. 9189- **gravity**: Position on the screen—options are `ToastAndroid.TOP`, `ToastAndroid.BOTTOM`, or `ToastAndroid.CENTER`. 9190- **xOffset**, **yOffset**: Offsets in pixels for positioning. 9191 9192> Note: Starting with Android 11 (API level 30), setting gravity has no effect on text toasts. For similar functionality, consider using snackbar or notification. 9193 9194### Properties 9195 9196#### `SHORT` 9197 9198Indicates a short duration for the toast display. 9199 9200```typescript 9201static SHORT: number; 9202``` 9203 9204#### `LONG` 9205 9206Indicates a long duration for the toast display. 9207 9208```typescript 9209static LONG: number; 9210``` 9211 9212#### `TOP` 9213 9214Specifies the top position on the screen for the toast. 9215 9216```typescript 9217static TOP: number; 9218``` 9219 9220#### `BOTTOM` 9221 9222Specifies the bottom position on the screen for the toast. 9223 9224```typescript 9225static BOTTOM: number; 9226``` 9227 9228#### `CENTER` 9229 9230Specifies the center position on the screen for the toast. 9231 9232```typescript 9233static CENTER: number; 9234``` 9235 9236## React Native Gradle Plugin 9237 9238This guide provides instructions on configuring the **React Native Gradle Plugin** (RNGP) when building your React Native application for Android. 9239 9240### Using the Plugin 9241 9242The React Native Gradle Plugin is distributed as a separate NPM package, automatically installed with `react-native`. 9243 9244For new projects created using `npx react-native init`, the plugin is pre-configured. No additional steps are required to install it if you used this command. 9245 9246If integrating React Native into an existing project, refer to specific instructions for installing the plugin. 9247 9248### Configuring the Plugin 9249 9250The plugin works with sensible defaults and requires customization only when necessary. Configuration can be done in the `react` block within your `android/app/build.gradle` file: 9251 9252```groovy 9253apply plugin: "com.facebook.react" 9254 9255/** 9256 * This is the configuration block to customize your React Native Android app. 9257 * By default, no configuration is needed; uncomment lines as required. 9258 */ 9259react { 9260 // Custom configuration goes here. 9261} 9262``` 9263 9264#### Configuration Keys 9265 9266##### `root` 9267 9268Specifies the root folder of your React Native project (where `package.json` resides). Default: `..`. 9269 9270```groovy 9271root = file("../") 9272``` 9273 9274##### `reactNativeDir` 9275 9276Defines the directory for the `react-native` package. Default: `../node_modules/react-native`. Adjust if using a monorepo or different package manager. 9277 9278```groovy 9279reactNativeDir = file("../node_modules/react-native") 9280``` 9281 9282##### `codegenDir` 9283 9284Specifies the folder for the `react-native-codegen` package. Default: `../node_modules/@react-native/codegen`. 9285 9286```groovy 9287codegenDir = file("../node_modules/@react-native/codegen") 9288``` 9289 9290##### `cliFile` 9291 9292The entry point for the React Native CLI, needed for bundling and app creation. Default: `../node_modules/react-native/cli.js`. 9293 9294```groovy 9295cliFile = file("../node_modules/react-native/cli.js") 9296``` 9297 9298##### `debuggableVariants` 9299 9300Lists variants considered debuggable (e.g., `debug`, not `release`). Adjust if using other variants like `staging` or `lite`. 9301 9302```groovy 9303debuggableVariants = ["liteDebug", "prodDebug"] 9304``` 9305 9306##### `nodeExecutableAndArgs` 9307 9308Specifies the node command and arguments for scripts. Default: `[node]`. Customize to add extra flags. 9309 9310```groovy 9311nodeExecutableAndArgs = ["node"] 9312``` 9313 9314##### `bundleCommand` 9315 9316Name of the `bundle` command for app bundling, useful with RAM Bundles. Default: `bundle`. 9317 9318```groovy 9319bundleCommand = "ram-bundle" 9320``` 9321 9322##### `bundleConfig` 9323 9324Path to a configuration file passed to `bundle --config <file>`. Default is empty. 9325 9326```groovy 9327bundleConfig = file("../rn-cli.config.js") 9328``` 9329 9330##### `bundleAssetName` 9331 9332Name of the generated bundle file. Default: `index.android.bundle`. 9333 9334```groovy 9335bundleAssetName = "MyApplication.android.bundle" 9336``` 9337 9338##### `entryFile` 9339 9340Entry file for bundle generation, defaulting to `index.android.js` or `index.js`. 9341 9342```groovy 9343entryFile = file("../js/MyApplication.android.js") 9344``` 9345 9346##### `extraPackagerArgs` 9347 9348Extra flags passed to the `bundle` command. Default is empty. 9349 9350```groovy 9351extraPackagerArgs = [] 9352``` 9353 9354##### `hermesCommand` 9355 9356Path to the `hermesc` command (Hermes Compiler). React Native includes a bundled version, so customization is usually unnecessary. 9357 9358##### `hermesFlags` 9359 9360Flags for `hermesc`. Default: `["-O", "-output-source-map"]`. 9361 9362```groovy 9363hermesFlags = ["-O", "-output-source-map"] 9364``` 9365 9366##### `enableBundleCompression` 9367 9368Determines if the Bundle Asset should be compressed in `.apk` packaging. Disabled by default to improve startup time at the cost of larger app size on disk. 9369 9370### Using Flavors & Build Variants 9371 9372Custom flavors allow different versions of your app from a single project. Refer to the official Android guide for configuring custom build types (e.g., `staging`) or flavors (e.g., `full`, `lite`). New apps default to two build types (`debug` and `release`) with no custom flavors. 9373 9374Build variants are combinations of all build types and flavors. For example, with `debug`/`staging`/`release` build types and `full`/`lite` flavors, you get 6 variants: `fullDebug`, `fullStaging`, `fullRelease`, etc. 9375 9376For custom variants beyond `debug` and `release`, specify which are **debuggable** using the `debuggableVariants` configuration: 9377 9378```diff 9379apply plugin: "com.facebook.react" 9380 9381react { 9382+ debuggableVariants = ["fullStaging", "fullDebug"] 9383} 9384``` 9385 9386This is necessary because the plugin skips JS bundling for all `debuggableVariants`, requiring Metro to run them. Listing `fullStaging` in `debuggableVariants` means it won't have a bundle, preventing store publication. 9387 9388### Plugin Responsibilities 9389 9390The React Native Gradle Plugin configures your Application build for production and is used by 3rd party libraries for Codegen with the New Architecture. Key responsibilities include: 9391 9392- Adding a `createBundle<Variant>JsAndAssets` task for non-debuggable variants to invoke `bundle`, `hermesc`, and `compose-source-map`. 9393- Setting up dependencies like `com.facebook.react:react-android` and `com.facebook.react:hermes-android` based on React Native version. 9394- Configuring Maven repositories (Maven Central, Google Maven Repo, JSC local Maven repo) for necessary dependencies. 9395- Setting up the NDK for apps using the New Architecture. 9396- Defining `buildConfigFields` to determine runtime if Hermes or the New Architecture are enabled. 9397- Configuring the Metro DevServer Port as an Android resource. 9398- Invoking React Native Codegen for libraries/apps using it with the New Architecture. 9399 9400## Linking Libraries 9401 9402Not every application utilizes all native capabilities, and including code for all features would increase binary size. However, we aim to support adding these features when needed. 9403 9404To address this, many features are exposed as independent static libraries. 9405 9406For most libraries, linking is quick—typically involving dragging two files, with a third step sometimes necessary. 9407 9408**Note:** All React Native libraries reside in the `Libraries` folder at the repository's root. Some are pure JavaScript and require only a `require`. Libraries relying on native code need these files added to your app; otherwise, an error occurs when using the library. 9409 9410### Steps to Link Libraries with Native Code 9411 9412#### Automatic Linking 9413 94141. Install a library with native dependencies: 9415 9416 ```shell 9417 npm install <library-with-native-dependencies> --save 9418 ``` 9419 94201. **Important:** Use the `--save` or `--save-dev` flag. React Native links libraries based on `dependencies` and `devDependencies` in your `package.json`. 9421 9422That's it! The next build will link native code via autolinking. 9423 9424#### Manual Linking 9425 9426##### Step 1 9427 9428If the library includes native code, an `.xcodeproj` file should be present. Drag this file into your Xcode project (typically under the `Libraries` group). 9429 9430##### Step 2 9431 9432Select your main project file (representing the `.xcodeproj`) and choose `Build Phases`. Drag the static library from the `Products` folder of the imported Library to `Link Binary With Libraries`. 9433 9434##### Step 3 9435 9436Not all libraries require this step. Consider: 9437 9438*Do I need to know the contents of the library at compile time?* 9439 9440This means, are you using the library on the native side or only in JavaScript? If it's just JavaScript, no further action is needed. 9441 9442If native usage is required, include the library's headers by going to your project file, selecting `Build Settings`, and searching for `Header Search Paths`. Add the path to your library. (Previously recommended using `recursive` is now discouraged due to potential build failures, especially with CocoaPods.) 9443 9444## Running On Simulator 9445 9446### Starting the Simulator 9447 9448After initializing your React Native project, you can start it using either npm or Yarn within the project directory. 9449 9450#### Commands: 9451 9452- **npm** 9453 9454 ```shell 9455 npm run ios 9456 ``` 9457 9458- **Yarn** 9459 9460 ```shell 9461 yarn ios 9462 ``` 9463 9464If everything is configured correctly, your app should appear in the iOS Simulator shortly after running these commands. 9465 9466### Specifying a Device 9467 9468To specify which device to use with the simulator, utilize the `--simulator` flag followed by the desired device name as a string. By default, it uses `"iPhone 14"`. For example, to run your app on an iPhone SE (3rd generation), execute: 9469 9470- **npm** 9471 9472 ```shell 9473 npm run ios -- --simulator="iPhone SE (3rd generation)" 9474 ``` 9475 9476- **Yarn** 9477 9478 ```shell 9479 yarn ios --simulator "iPhone SE (3rd generation)" 9480 ``` 9481 9482The device names should match those available in Xcode. You can verify the list of devices by running `xcrun simctl list devices` from your console. 9483 9484#### Specifying a Device Version 9485 9486If multiple iOS versions are installed, specify the version as well. For instance, to run on an iPhone 14 Pro with iOS 16.0, use: 9487 9488- **npm** 9489 9490 ```shell 9491 npm run ios -- --simulator="iPhone 14 Pro (16.0)" 9492 ``` 9493 9494- **Yarn** 9495 9496 ```shell 9497 yarn ios --simulator "iPhone 14 Pro (16.0)" 9498 ``` 9499 9500### Specifying a UDID 9501 9502You can also specify the device using its UDID, which you can find by running `xcrun simctl list devices`. For example, to run your app with a specific UDID: 9503 9504- **npm** 9505 9506 ```shell 9507 npm run ios -- --udid="AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA" 9508 ``` 9509 9510- **Yarn** 9511 9512 ```shell 9513 yarn ios --udid "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA" 9514 ``` 9515 9516## FlatList 9517 9518A performant interface for rendering basic, flat lists with a variety of features: 9519 9520- Fully cross-platform. 9521- Optional horizontal mode. 9522- Configurable viewability callbacks. 9523- Header and footer support. 9524- Separator support. 9525- Pull-to-refresh functionality. 9526- Scroll loading. 9527- `ScrollToIndex` support. 9528- Multiple column support. 9529 9530For sectioned lists, use `<SectionList>` instead. 9531 9532### Example 9533 9534#### TypeScript & JavaScript 9535 9536To render multiple columns, utilize the `numColumns` prop. This method avoids conflicts with item height logic that might arise from using a `flexWrap` layout. 9537 9538A more complex example includes: 9539 9540- Passing `extraData={selectedId}` to `FlatList` ensures it re-renders when state changes. Without this prop, `FlatList`, being a `PureComponent`, wouldn't recognize the need for re-rendering due to unchanged props. 9541- The `keyExtractor` prop allows using item `id`s as React keys instead of default `key` properties. 9542 9543This component is a convenience wrapper around `<VirtualizedList>`, inheriting its and `<ScrollView>`'s unlisted props, with specific considerations: 9544 9545- Internal state isn't preserved when content scrolls out of view. Ensure all data is captured in the item data or external stores like Flux, Redux, or Relay. 9546- As a `PureComponent`, it won't re-render if `props` remain shallow-equal. Pass everything your `renderItem` function depends on as props (e.g., `extraData`) that aren't strictly equal after updates to ensure UI updates on changes. This includes the `data` prop and parent component state. 9547- Content is rendered asynchronously offscreen for memory constraints and smooth scrolling, which might lead to blank content during fast scrolls. This tradeoff can be adjusted per application needs. 9548- By default, it looks for a `key` prop on each item for React keys or uses a custom `keyExtractor`. 9549 9550### Reference 9551 9552#### Props 9553 9554##### VirtualizedList Props 9555 9556Inherits from VirtualizedList Props. 9557 9558##### Required: `renderItem` 9559 9560```typescript 9561renderItem({ 9562 item: ItemT, 9563 index: number, 9564 separators: { 9565 highlight: () => void; 9566 unhighlight: () => void; 9567 updateProps: (select: 'leading' | 'trailing', newProps: any) => void; 9568 } 9569}): JSX.Element; 9570``` 9571 9572- **item**: The item to be rendered. 9573- **index**: Index of the item in the list. 9574- **separators**: Object containing methods for separator interactions. 9575 9576##### Required: `data` 9577 9578An array of items to render. Each item should have a unique key or use the `keyExtractor` prop. 9579 9580#### Methods 9581 9582##### `flashScrollIndicators()` 9583 9584Displays scroll indicators momentarily. 9585 9586```typescript 9587flashScrollIndicators(): void; 9588``` 9589 9590##### `getNativeScrollRef()` 9591 9592Provides a reference to the underlying scroll component. 9593 9594```typescript 9595getNativeScrollRef(): React.ElementRef<typeof ScrollViewComponent>; 9596``` 9597 9598##### `getScrollResponder()` 9599 9600Provides access to the underlying scroll responder. 9601 9602```typescript 9603getScrollResponder(): ScrollResponderMixin; 9604``` 9605 9606##### `getScrollableNode()` 9607 9608Provides access to the underlying scroll node. 9609 9610```typescript 9611getScrollableNode(): any; 9612``` 9613 9614##### `scrollToEnd(params?: { animated?: boolean })` 9615 9616Scrolls to the end of the content. May be less smooth without `getItemLayout`. 9617 9618**Parameters:** 9619 9620- **params**: Optional object with: 9621 - `animated`: Whether to animate the scroll (default is `true`). 9622 9623##### `scrollToIndex(params: { index: number; animated?: boolean; viewOffset?: number; viewPosition?: number })` 9624 9625Scrolls to a specific item index, positioning it based on `viewPosition`. 9626 9627**Parameters:** 9628 9629- **params**: Required object with: 9630 - `index`: Index of the item. 9631 - `animated`: Whether to animate (default is `true`). 9632 - `viewOffset`: Pixels to offset the final position. 9633 - `viewPosition`: Position in view (`0` for top, `1` for bottom, `0.5` for center). 9634 9635##### `scrollToItem(params: { animated?: boolean; item: Item; viewPosition?: number })` 9636 9637Scrolls to a specific item. Requires linear scan through data. 9638 9639**Parameters:** 9640 9641- **params**: Required object with: 9642 - `item`: The item to scroll to. 9643 - `animated`: Whether to animate (default is `true`). 9644 - `viewPosition`: Position in view (`0` for top, `1` for bottom, `0.5` for center). 9645 9646##### `scrollToOffset(params: { offset: number; animated?: boolean })` 9647 9648Scrolls to a specific content pixel offset. 9649 9650**Parameters:** 9651 9652- **params**: Required object with: 9653 - `offset`: The offset to scroll to. 9654 - `animated`: Whether to animate (default is `true`). 9655 9656## LayoutAnimation 9657 9658Automatically animates views to their new positions when the next layout occurs. This API is typically used by calling it before updating state in functional components or using `setState` in class components. 9659 9660To enable this functionality on **Android**, you must set specific flags via `UIManager`: 9661 9662```typescript 9663if (Platform.OS === "android") { 9664 if (UIManager.setLayoutAnimationEnabledExperimental) { 9665 UIManager.setLayoutAnimationEnabledExperimental(true) 9666 } 9667} 9668``` 9669 9670### Example 9671 9672### Reference 9673 9674### Methods 9675 9676#### `configureNext()` 9677 9678```typescript 9679static configureNext( 9680 config: LayoutAnimationConfig, 9681 onAnimationDidEnd?: () => void, 9682 onAnimationDidFail?: () => void, 9683): void; 9684``` 9685 9686Schedules an animation for the next layout. 9687 9688##### Parameters: 9689 9690|Name|Type|Required|Description| 9691|-|-|-|-| 9692|config|object|Yes|Configuration details (see below).| 9693|onAnimationDidEnd|function|No|Callback when the animation finishes.| 9694|onAnimationDidFail|function|No|Callback if the animation fails.| 9695 9696The `config` parameter is an object with the following keys: 9697 9698- `duration`: Duration in milliseconds. 9699- `create`: Optional configuration for animating new views. 9700- `update`: Optional configuration for animating updated views. 9701- `delete`: Optional configuration for animating removed views. 9702 9703Each of these configurations (`create`, `update`, `delete`) includes: 9704 9705- `type`: The animation type to use. 9706- `property`: The layout property to animate (optional, recommended for `create` and `delete`). 9707- `springDamping`: A number used only with `type: Type.spring`. 9708- `initialVelocity`: An optional number. 9709- `delay`: An optional number. 9710- `duration`: An optional number. 9711 9712#### `create()` 9713 9714```typescript 9715static create(duration: number, type: string, creationProp?: string): LayoutAnimationConfig; 9716``` 9717 9718Helper function to generate an object with `create`, `update`, and `delete` fields for use in `configureNext`. The `type` parameter specifies the animation type, while `creationProp` is a layout property. 9719 9720**Example:** 9721 9722### Properties 9723 9724#### Types 9725 9726An enumeration of animation types used in the `create` method or within the `create`/`update`/`delete` configurations for `configureNext`. 9727 9728|Type| 9729|-| 9730|spring| 9731|linear| 9732|easeInEaseOut| 9733|easeIn| 9734|easeOut| 9735|keyboard| 9736 9737#### Properties 9738 9739An enumeration of layout properties that can be animated, used in the `create` method or within the `create`/`update`/`delete` configurations for `configureNext`. 9740 9741|Property| 9742|-| 9743|opacity| 9744|scaleX| 9745|scaleY| 9746|scaleXY| 9747 9748#### Presets 9749 9750Predefined animation configurations to use with `configureNext`. 9751 9752|Preset|Value| 9753|-|-| 9754|easeInEaseOut|`{ create: { type: 'easeInEaseOut', property: 'opacity' } }`| 9755|linear|`{ create: { type: 'linear', property: 'opacity' } }`| 9756|spring|`{ duration: 700, create: { type: 'linear', property: 'opacity' }, update: { type: 'spring', springDamping: 0.4 }, delete: { type: 'linear', property: 'opacity' } }`| 9757 9758#### `easeInEaseOut` 9759 9760Invokes `configureNext()` with the `Presets.easeInEaseOut`. 9761 9762#### `linear` 9763 9764Invokes `configureNext()` with the `Presets.linear`. 9765 9766#### `spring` 9767 9768Invokes `configureNext()` with the `Presets.spring`. 9769 9770**Example:** 9771 9772## Appearance 9773 9774The `Appearance` module provides information about the user's appearance preferences, such as their preferred color scheme (light or dark). 9775 9776### Developer Notes 9777 9778- **Android**: On Android 10 (API level 29) and higher, the color scheme preference corresponds to the user's Light or Dark theme setting. 9779 9780- **iOS**: On iOS 13 and above, it maps to the user's Light or Dark Mode preference. Note that screenshots may flicker between light and dark modes due to asynchronous updates. 9781 9782### Example Usage 9783 9784To determine if a user prefers a dark color scheme: 9785 9786```typescript 9787import { Appearance } from "react-native" 9788 9789const colorScheme = Appearance.getColorScheme() 9790if (colorScheme === "dark") { 9791 // Implement logic for dark color scheme 9792} 9793``` 9794 9795Since the color scheme can change (e.g., due to scheduled changes at sunrise or sunset), it's recommended to call this function on every render. You might use the `useColorScheme` React hook, which subscribes to updates, or inline styles instead of a static `StyleSheet`. 9796 9797### Reference 9798 9799#### Methods 9800 9801##### `getColorScheme()` 9802 9803```typescript 9804static getColorScheme(): 'light' | 'dark' | null; 9805``` 9806 9807Returns the current user's preferred color scheme. This value can change due to direct user actions (e.g., theme selection) or scheduled changes. 9808 9809Supported values: 9810 9811- `'light'`: User prefers a light theme. 9812- `'dark'`: User prefers a dark theme. 9813- `null`: No preference indicated. 9814 9815*Note*: When debugging with Chrome, this method always returns `'light'`. 9816 9817##### `setColorScheme()` 9818 9819```typescript 9820static setColorScheme('light' | 'dark' | null): void; 9821``` 9822 9823Forces the application to use a specified interface style. The default is `null`, which follows the system's style. 9824 9825Supported values: 9826 9827- `'light'`: Apply light user interface. 9828- `'dark'`: Apply dark user interface. 9829- `null`: Follow the system's interface style. 9830 9831*Note*: This change does not affect other applications or the system's overall settings. 9832 9833##### `addChangeListener()` 9834 9835```typescript 9836static addChangeListener( 9837 listener: (preferences: { colorScheme: 'light' | 'dark' | null }) => void, 9838): NativeEventSubscription; 9839``` 9840 9841Adds an event handler that triggers when appearance preferences change. 9842 9843## AppRegistry 9844 9845### Project with Native Code Required 9846 9847In the managed Expo workflow, there's only one entry component registered with `AppRegistry`, handled automatically or through `registerRootComponent`. This API isn't necessary in this context. 9848 9849`AppRegistry` serves as the JavaScript entry point for all React Native applications. Root components should register themselves using `AppRegistry.registerComponent`. The native system then loads the app bundle and runs it by invoking `AppRegistry.runApplication`. 9850 9851```typescript 9852import { Text, View } from 'react-native'; 9853 9854const App = () => ( 9855 <View> 9856 <Text>App1</Text> 9857 </View> 9858); 9859 9860AppRegistry.registerComponent('AppName', () => App); 9861``` 9862 9863To stop an application when a view is destroyed, use `AppRegistry.unmountApplicationComponentAtRootTag` with the tag passed to `runApplication`. These should always be used as pairs. 9864 9865Ensure `AppRegistry` is required early in the sequence to set up the JavaScript execution environment before other modules are loaded. 9866 9867### Reference 9868 9869#### Methods 9870 9871##### `getAppKeys()` 9872 9873```typescript 9874static getAppKeys(): string[]; 9875``` 9876 9877Returns an array of strings. 9878 9879##### `getRegistry()` 9880 9881```typescript 9882static getRegistry(): { sections: string[]; runnables: Runnable[] }; 9883``` 9884 9885Returns a Registry object. 9886 9887##### `getRunnable()` 9888 9889```typescript 9890static getRunnable(appKey: string): Runnable | undefined; 9891``` 9892 9893**Parameters:** 9894 9895- **appKey**: Required, type: `string`. 9896 9897Returns a Runnable object. 9898 9899##### `getSectionKeys()` 9900 9901```typescript 9902static getSectionKeys(): string[]; 9903``` 9904 9905Returns an array of strings. 9906 9907##### `getSections()` 9908 9909```typescript 9910static getSections(): Record<string, Runnable>; 9911``` 9912 9913Returns a Runnables object. 9914 9915##### `registerCancellableHeadlessTask()` 9916 9917```typescript 9918static registerCancellableHeadlessTask( 9919 taskKey: string, 9920 taskProvider: TaskProvider, 9921 taskCancelProvider: TaskCancelProvider 9922); 9923``` 9924 9925Registers a headless task that can be cancelled. A headless task runs without a UI. 9926 9927**Parameters:** 9928 9929|Name|Type|Description| 9930|-|-|-| 9931|**taskKey**|`string`|Required, the native ID for this task instance used when startHeadlessTask was called.| 9932|**taskProvider**|`TaskProvider`|Required, a promise-returning function that takes data from the native side as an argument. When resolved or rejected, the native side is notified and may destroy the JS context.| 9933|**taskCancelProvider**|`TaskCancelProvider`|Required, a void-returning function with no arguments; when cancellation is requested, the taskProvider should wrap up and return ASAP.| 9934 9935##### `registerComponent()` 9936 9937```typescript 9938static registerComponent( 9939 appKey: string, 9940 getComponentFunc: ComponentProvider, 9941 section?: boolean 9942): string; 9943``` 9944 9945**Parameters:** 9946 9947|Name|Type|| 9948|-|-|-| 9949|**appKey**|`string`|| 9950|**getComponentFunc**|`ComponentProvider`|Required| 9951|**section**|`boolean`|| 9952 9953##### `registerConfig()` 9954 9955```typescript 9956static registerConfig(config: AppConfig[]); 9957``` 9958 9959**Parameters:** 9960 9961- **config**: Required, type: `AppConfig[]`. 9962 9963##### `registerHeadlessTask()` 9964 9965```typescript 9966static registerHeadlessTask( 9967 taskKey: string, 9968 taskProvider: TaskProvider 9969); 9970``` 9971 9972Registers a headless task. A headless task runs without a UI and can be used for background tasks like syncing data, handling notifications, or playing music. 9973 9974**Parameters:** 9975 9976|Name|Type|Description| 9977|-|-|-| 9978|**taskKey**|`string`|Required, the native ID for this task instance used when startHeadlessTask was called.| 9979|**taskProvider**|`TaskProvider`|Required, a promise-returning function that takes data from the native side as an argument. When resolved or rejected, the native side is notified and may destroy the JS context.| 9980 9981##### `registerRunnable()` 9982 9983```typescript 9984static registerRunnable(appKey: string, func: Runnable): string; 9985``` 9986 9987**Parameters:** 9988 9989|Name|Type| 9990|-|-| 9991|**appKey**|`string`| 9992|**func**|`function`| 9993 9994##### `registerSection()` 9995 9996```typescript 9997static registerSection( 9998 appKey: string, 9999 component: ComponentProvider 10000); 10001``` 10002 10003**Parameters:** 10004 10005|Name|Type|| 10006|-|-|-| 10007|**appKey**|`string`|| 10008|**component**|`ComponentProvider`|Required| 10009 10010##### `runApplication()` 10011 10012```typescript 10013static runApplication(appKey: string, appParameters: any): void; 10014``` 10015 10016Loads the JavaScript bundle and runs the app. 10017 10018**Parameters:** 10019 10020|Name|Type| 10021|-|-| 10022|**appKey**|`string`| 10023|**appParameters**|`any`| 10024 10025##### `setComponentProviderInstrumentationHook()` 10026 10027```typescript 10028static setComponentProviderInstrumentationHook( 10029 hook: ComponentProviderInstrumentationHook 10030); 10031``` 10032 10033**Parameters:** 10034 10035- **hook**: Required, type: `function`. 10036 10037A valid `hook` function accepts the following as arguments: 10038 10039|Name|Type|| 10040|-|-|-| 10041|**component**|`ComponentProvider`|Required| 10042|**scopedPerformanceLogger**|`IPerformanceLogger`|Required| 10043 10044The function must return a React Component. 10045 10046##### `setWrapperComponentProvider()` 10047 10048```typescript 10049static setWrapperComponentProvider( 10050 provider: WrapperComponentProvider 10051); 10052``` 10053 10054**Parameters:** 10055 10056- **provider**: Required, type: `ComponentProvider`. 10057 10058##### `startHeadlessTask()` 10059 10060```typescript 10061static startHeadlessTask( 10062 taskId: number, 10063 taskKey: string, 10064 data: any 10065); 10066``` 10067 10068Only called from native code. Starts a headless task. 10069 10070**Parameters:** 10071 10072|Name|Type|Description| 10073|-|-|-| 10074|**taskId**|`number`|Required, the native ID for this task instance to track its execution.| 10075|**taskKey**|`string`|Required, the key for the task to start.| 10076|**data**|`any`|Required, the data to pass to the task.| 10077 10078##### `unmountApplicationComponentAtRootTag()` 10079 10080```typescript 10081static unmountApplicationComponentAtRootTag(rootTag: number); 10082``` 10083 10084Stops an application when a view should be destroyed. 10085 10086**Parameters:** 10087 10088- **rootTag**: Required, type: `number`. 10089 10090### Type Definitions 10091 10092#### AppConfig 10093 10094Application configuration for the `registerConfig` method. 10095 10096- Type: `object` 10097 10098**Properties:** 10099 10100|Name|Type|| 10101|-|-|-| 10102|**appKey**|`string`|Required| 10103|component|`ComponentProvider`|| 10104|run|`function`|| 10105|section|`boolean`|| 10106 10107> **Note:** Every config must set either the `component` or `run` function. 10108 10109#### Registry 10110 10111- Type: `object` 10112 10113**Properties:** 10114 10115|Name|Type| 10116|-|-| 10117|runnables|Array of Runnables| 10118|sections|Array of strings| 10119 10120#### Runnable 10121 10122- Type: `object` 10123 10124**Properties:** 10125 10126|Name|Type| 10127|-|-| 10128|component|`ComponentProvider`| 10129|run|`function`| 10130 10131#### Runnables 10132 10133An object with a key of `appKey` and value of type `Runnable`. 10134 10135- Type: `object` 10136 10137#### Task 10138 10139A `Task` is a function that accepts any data as an argument and returns a Promise resolving to `undefined`. 10140 10141- Type: `function` 10142 10143#### TaskCanceller 10144 10145A `TaskCanceller` is a function that accepts no arguments and returns void. 10146 10147- Type: `function` 10148 10149#### TaskCancelProvider 10150 10151A valid `TaskCancelProvider` is a function returning a `TaskCanceller`. 10152 10153- Type: `function` 10154 10155#### TaskProvider 10156 10157A valid `TaskProvider` is a function returning a `Task`. 10158 10159- Type: `function` 10160 10161## React Native and Frameworks 10162 10163React Native enables developers familiar with React to build native applications. It also allows native developers to achieve parity across platforms by writing shared features once. 10164 10165The optimal way to experience React Native is through a **Framework**, which provides all necessary APIs for building production-ready apps. 10166 10167While it's possible to use React Native without a Framework, many developers find that using one like Expo offers significant benefits. Expo includes features such as file-based routing, high-quality universal libraries, and the ability to write plugins that modify native code without managing native files directly. 10168 10169### Start a New Project with Expo 10170 10171#### Platform Support 10172 10173- Android 10174- iOS 10175- TV 10176- Web 10177 10178Expo is a production-grade React Native Framework offering developer tooling to simplify app development. This includes file-based routing, a standard library of native modules, and more. 10179 10180The Expo Framework is free, open-source, and supported by an active community on GitHub and Discord. The Expo team collaborates closely with the React Native team at Meta to integrate the latest features into the Expo SDK. 10181 10182Additionally, Expo provides Expo Application Services (EAS), which are optional services that enhance the development process alongside the Expo Framework. 10183 10184#### Creating a New Expo Project 10185 10186To start a new project using Expo, execute the following command in your terminal: 10187 10188```shell 10189npx create-expo-app@latest 10190``` 10191 10192After creating your app, refer to Expo’s getting started guide for further development steps. 10193 10194## PixelRatio 10195 10196`PixelRatio` provides access to the device's pixel density and font scale. 10197 10198### Fetching a Correctly Sized Image 10199 10200To ensure optimal image quality on high pixel density devices, it is advisable to adjust the image size by multiplying it with the pixel ratio. Here’s how you can achieve this: 10201 10202```typescript 10203const image = getImage({ 10204 width: PixelRatio.getPixelSizeForLayoutSize(200), 10205 height: PixelRatio.getPixelSizeForLayoutSize(100), 10206}); 10207<Image source={image} style={{width: 200, height: 100}} />; 10208``` 10209 10210### Pixel Grid Snapping 10211 10212On iOS devices, you can specify element positions and dimensions with high precision. However, due to the fixed number of pixels on displays (e.g., 640×1136 for iPhone SE or 828×1792 for iPhone 11), iOS attempts to maintain user-defined values by spreading a single pixel across multiple ones, which may result in blurriness. 10213 10214Developers often prefer manual rounding to avoid this blurriness. React Native handles automatic rounding of pixels to prevent such issues. It's crucial to ensure that rounded and unrounded values are not mixed to prevent cumulative rounding errors, as even minor discrepancies can significantly affect element borders. 10215 10216In React Native, calculations in JavaScript and the layout engine use arbitrary precision numbers. Rounding occurs only when setting native element positions and dimensions on the main thread, relative to the root rather than the parent, to minimize rounding errors. 10217 10218### Reference 10219 10220#### Methods 10221 10222##### `get()` 10223 10224```typescript 10225static get(): number; 10226``` 10227 10228Returns the device pixel density with examples: 10229 10230- `PixelRatio.get() === 1`: mdpi Android devices 10231- `PixelRatio.get() === 1.5`: hdpi Android devices 10232- `PixelRatio.get() === 2`: iPhone SE, 6S, 7, 8; iPhone XR; iPhone 11; xhdpi Android devices 10233- `PixelRatio.get() === 3`: iPhone 6S Plus, 7 Plus, 8 Plus; iPhone X, XS, XS Max; iPhone 11 Pro, 11 Pro Max; Pixel, Pixel 2; xxhdpi Android devices 10234- `PixelRatio.get() === 3.5`: Nexus 6; Pixel XL, Pixel 2 XL; xxxhdpi Android devices 10235 10236##### `getFontScale()` 10237 10238```typescript 10239static getFontScale(): number; 10240``` 10241 10242Returns the scaling factor for font sizes based on user preferences: 10243 10244- On Android: Reflects settings in **Settings > Display > Font size** 10245- On iOS: Reflects settings in **Settings > Display & Brightness > Text Size** or **Settings > Accessibility > Display & Text Size > Larger Text** 10246 10247If no font scale is set, it returns the device pixel ratio. 10248 10249##### `getPixelSizeForLayoutSize()` 10250 10251```typescript 10252static getPixelSizeForLayoutSize(layoutSize: number): number; 10253``` 10254 10255Converts a layout size (dp) to pixel size (px), ensuring an integer return value. 10256 10257##### `roundToNearestPixel()` 10258 10259```typescript 10260static roundToNearestPixel(layoutSize: number): number; 10261``` 10262 10263Rounds a layout size (dp) to the nearest size that corresponds to an integer number of pixels. For instance, on a device with a PixelRatio of 3, `PixelRatio.roundToNearestPixel(8.4)` results in 8.33, which equals exactly 25 pixels when multiplied by 3. 10264 10265## SectionList 10266 10267A performant interface for rendering sectioned lists with features such as: 10268 10269- Cross-platform compatibility. 10270- Configurable viewability callbacks. 10271- Support for list headers and footers. 10272- Item and section separator support. 10273- Heterogeneous data and item rendering. 10274- Pull to Refresh functionality. 10275- Scroll loading. 10276 10277For simpler interfaces without section support, consider using `<FlatList>`. 10278 10279### Example 10280 10281`<SectionList>` is a convenience wrapper around `<VirtualizedList>`, inheriting its props (and those of `<ScrollView>`) that aren't explicitly listed here. Note the following: 10282 10283- Internal state isn't preserved when content scrolls out of view. Ensure all data is captured in item data or external stores like Flux, Redux, or Relay. 10284- As a `PureComponent`, it won't re-render if `props` remain shallow-equal. Pass everything your `renderItem` function depends on as props (e.g., `extraData`) that change after updates to ensure UI updates correctly. 10285- Content is rendered asynchronously offscreen for memory constraints and smooth scrolling, which may result in blank content during fast scrolls. This tradeoff can be adjusted per application needs. 10286- By default, the list uses a `key` prop on each item as the React key or allows a custom `keyExtractor`. 10287 10288### Reference 10289 10290#### Props 10291 10292##### VirtualizedList Props 10293 10294Inherits props from `VirtualizedList`. 10295 10296##### Required: `renderItem` 10297 10298Default renderer for every item in every section. Can be overridden per-section. Should return a React element. 10299 10300|Type| 10301|-| 10302|function| 10303 10304The render function receives an object with: 10305 10306- 'item' (object) - the item as specified in this section's `data` key. 10307- 'index' (number) - Item's index within the section. 10308- 'section' (object) - The full section object as specified in `sections`. 10309- 'separators' (object) with: 10310 - 'highlight' (function) - `() => void` 10311 - 'unhighlight' (function) - `() => void` 10312 - 'updateProps' (function) - `(select, newProps) => void` where: 10313 - 'select' (enum) - possible values are 'leading', 'trailing' 10314 - 'newProps' (object) 10315 10316##### Required: `sections` 10317 10318The data to render, similar to the `data` prop in `FlatList`. 10319 10320|Type| 10321|-| 10322|array of Sections| 10323 10324##### `extraData` 10325 10326A marker property for re-rendering since it implements `PureComponent`. Use this if your `renderItem`, Header, Footer, etc., depend on anything outside the `data` prop. Treat it immutably. 10327 10328|Type| 10329|-| 10330|any| 10331 10332##### `initialNumToRender` 10333 10334Number of items to render initially. Should fill the screen but not much more. These items won't be unmounted for improved scroll-to-top performance. 10335 10336|Type|Default| 10337|-|-| 10338|number|`10`| 10339 10340##### `inverted` 10341 10342Reverses the direction of scroll using scale transforms of -1. 10343 10344|Type|Default| 10345|-|-| 10346|boolean|`false`| 10347 10348##### `ItemSeparatorComponent` 10349 10350Rendered between each item, excluding top and bottom. By default, provides `highlighted`, `section`, and `[leading/trailing][Item/Section]` props. `renderItem` offers `separators.highlight`/`unhighlight` to update the `highlighted` prop, with custom props via `separators.updateProps`. Can be a React Component or element. 10351 10352|Type| 10353|-| 10354|component, function, element| 10355 10356##### `keyExtractor` 10357 10358Extracts a unique key for an item at a specified index. Used for caching and tracking item re-ordering. Defaults to checking `item.key`, then `item.id`, and falls back to the index. 10359 10360|Type| 10361|-| 10362|(item: object, index: number) => string| 10363 10364##### `ListEmptyComponent` 10365 10366Rendered when the list is empty. Can be a React Component or element. 10367 10368|Type| 10369|-| 10370|component, element| 10371 10372##### `ListFooterComponent` 10373 10374Rendered at the end of the list. Can be a React Component or element. 10375 10376|Type| 10377|-| 10378|component, element| 10379 10380##### `ListHeaderComponent` 10381 10382Rendered at the beginning of the list. Can be a React Component or element. 10383 10384|Type| 10385|-| 10386|component, element| 10387 10388##### `onRefresh` 10389 10390Adds "Pull to Refresh" functionality if provided. Ensure the `refreshing` prop is set correctly. Use `progressViewOffset={100}` to offset from the top. 10391 10392|Type| 10393|-| 10394|function| 10395 10396##### `onViewableItemsChanged` 10397 10398Called when viewability of rows changes, as defined by the `viewabilityConfig` prop. 10399 10400|Type| 10401|-| 10402|`(callback: {changed: ViewToken[], viewableItems: ViewToken[]}) => void`| 10403 10404##### `refreshing` 10405 10406Set to true while waiting for new data from a refresh. 10407 10408|Type|Default| 10409|-|-| 10410|boolean|`false`| 10411 10412##### `removeClippedSubviews` 10413 10414> Note: May have bugs (missing content) in some circumstances - use at your own risk. This may improve scroll performance for large lists. 10415 10416|Type|Default| 10417|-|-| 10418|boolean|`false`| 10419 10420##### `renderSectionFooter` 10421 10422Rendered at the bottom of each section. 10423 10424|Type| 10425|-| 10426|`(info: {section: Section}) => element | null`| 10427 10428##### `renderSectionHeader` 10429 10430Rendered at the top of each section. Sticks to the top by default on iOS unless `stickySectionHeadersEnabled` is set otherwise. 10431 10432|Type| 10433|-| 10434|`(info: {section: Section}) => element | null`| 10435 10436##### `SectionSeparatorComponent` 10437 10438Rendered at the top and bottom of each section, different from `ItemSeparatorComponent`. Receives `highlighted`, `[leading/trailing][Item/Section]`, and custom props via `separators.updateProps`. 10439 10440|Type| 10441|-| 10442|component, element| 10443 10444##### `stickySectionHeadersEnabled` 10445 10446Makes section headers stick to the top of the screen until pushed off by the next one. Enabled by default on iOS. 10447 10448|Type|Default| 10449|-|-| 10450|boolean|`false`Android\*\*\*`true`iOS| 10451 10452### Methods 10453 10454#### `flashScrollIndicators()` (iOS) 10455 10456```typescript 10457flashScrollIndicators() 10458``` 10459 10460Displays scroll indicators momentarily. 10461 10462#### `recordInteraction()` 10463 10464```typescript 10465recordInteraction() 10466``` 10467 10468Informs the list of an interaction, triggering viewability calculations if `waitForInteractions` is true and the user hasn't scrolled. Typically called by taps on items or navigation actions. 10469 10470#### `scrollToLocation()` 10471 10472```typescript 10473scrollToLocation(params: SectionListScrollParams); 10474``` 10475 10476Scrolls to the item at the specified `sectionIndex` and `itemIndex`, positioning it in the viewable area based on `viewPosition`. Note: Cannot scroll outside the render window without `getItemLayout` or `onScrollToIndexFailed`. 10477 10478**Parameters:** 10479 10480|Name|Type| 10481|-|-| 10482|paramsRequired|object| 10483 10484Valid `params` keys: 10485 10486- 'animated' (boolean) - Whether to animate while scrolling. Defaults to `true`. 10487- 'itemIndex' (number) - Index within section for the item to scroll to. Required. 10488- 'sectionIndex' (number) - Section index containing the item to scroll to. Required. 10489- 'viewOffset' (number) - Fixed pixel offset for final target position, e.g., for sticky headers. 10490- 'viewPosition' (number) - `0` places the item at the top, `1` at the bottom, and `0.5` centered. 10491 10492### Type Definitions 10493 10494#### Section 10495 10496An object identifying data to be rendered for a given section. 10497 10498|Type| 10499|-| 10500|any| 10501 10502**Properties:** 10503 10504|Name|Type|Description| 10505|-|-|-| 10506|dataRequired|array|Data for rendering items in this section. Array of objects, similar to `FlatList`'s data prop.| 10507|key|string|Optional key for tracking section re-ordering. Defaults to array index if not specified.| 10508|renderItem|function|Optionally define an arbitrary item renderer for this section, overriding the default `renderItem`.| 10509|ItemSeparatorComponent|component, element|Optionally define an arbitrary item separator for this section, overriding the default `ItemSeparatorComponent`.| 10510|keyExtractor|function|Optionally define a custom key extractor for this section, overriding the default `keyExtractor`.| 10511 10512## AccessibilityInfo 10513 10514The `AccessibilityInfo` API is designed to determine if a screen reader or other accessibility services are active on a device. It allows querying the current state of these services and registering for notifications when their states change. 10515 10516### Example 10517 10518*Example content omitted.* 10519 10520### Reference 10521 10522#### Methods 10523 10524##### `addEventListener()` 10525 10526```typescript 10527static addEventListener( 10528 eventName: AccessibilityChangeEventName | AccessibilityAnnouncementEventName, 10529 handler: ( 10530 event: AccessibilityChangeEvent | AccessibilityAnnouncementFinishedEvent, 10531 ) => void, 10532): EmitterSubscription; 10533``` 10534 10535Adds an event handler for various accessibility-related events. Supported events include: 10536 10537|Event Name|Description| 10538|-|-| 10539|`accessibilityServiceChanged` (Android)|Fires when any accessibility services, such as TalkBack or third-party apps, are enabled. The argument is a boolean: `true` if enabled, otherwise `false`.| 10540|`announcementFinished` (iOS)|Fires after the screen reader finishes an announcement. Argument includes: - `announcement`: The announced string.<br>- `success`: Boolean indicating success of the announcement.| 10541|`boldTextChanged` (iOS)|Fires when bold text toggle state changes. Argument is a boolean: `true` if enabled, otherwise `false`.| 10542|`grayscaleChanged` (iOS)|Fires when grayscale toggle state changes. Argument is a boolean: `true` if enabled, otherwise `false`.| 10543|`invertColorsChanged` (iOS)|Fires when invert colors toggle state changes. Argument is a boolean: `true` if enabled, otherwise `false`.| 10544|`reduceMotionChanged`|Fires when reduce motion toggle state changes. Argument is a boolean: `true` if enabled or "Animation off" in Developer options, otherwise `false`.| 10545|`reduceTransparencyChanged` (iOS)|Fires when reduce transparency toggle state changes. Argument is a boolean: `true` if enabled, otherwise `false`.| 10546|`screenReaderChanged`|Fires when the screen reader's state changes. Argument is a boolean: `true` if enabled, otherwise `false`.| 10547 10548##### `announceForAccessibility()` 10549 10550```typescript 10551static announceForAccessibility(announcement: string); 10552``` 10553 10554Posts a string to be announced by the screen reader. 10555 10556##### `announceForAccessibilityWithOptions()` 10557 10558```typescript 10559static announceForAccessibilityWithOptions( 10560 announcement: string, 10561 options: { queue?: boolean }, 10562); 10563``` 10564 10565Posts a string for the screen reader with modification options. By default, announcements interrupt existing speech; on iOS, they can be queued by setting `queue` to `true`. 10566 10567**Parameters:** 10568 10569|Name|Type|Description| 10570|-|-|-| 10571|announcement|string|The string to be announced.| 10572|options|object|Contains `queue`: If set to `true`, queues the announcement behind existing speech on iOS.| 10573 10574##### `getRecommendedTimeoutMillis()` (Android) 10575 10576```typescript 10577static getRecommendedTimeoutMillis(originalTimeout: number): Promise<number>; 10578``` 10579 10580Returns the recommended timeout in milliseconds based on "Accessibility timeout" settings. 10581 10582**Parameters:** 10583 10584|Name|Type|Description| 10585|-|-|-| 10586|originalTimeout|number|The fallback timeout in milliseconds if no accessibility timeout is set.| 10587 10588##### `isAccessibilityServiceEnabled()` (Android) 10589 10590```typescript 10591static isAccessibilityServiceEnabled(): Promise<boolean>; 10592``` 10593 10594Checks if any accessibility service, including TalkBack or third-party apps, is enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10595 10596> **Note**: Use `isScreenReaderEnabled` for checking only the status of TalkBack. 10597 10598##### `isBoldTextEnabled()` (iOS) 10599 10600```typescript 10601static isBoldTextEnabled(): Promise<boolean>; 10602``` 10603 10604Checks if bold text is currently enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10605 10606##### `isGrayscaleEnabled()` (iOS) 10607 10608```typescript 10609static isGrayscaleEnabled(): Promise<boolean>; 10610``` 10611 10612Checks if grayscale mode is currently enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10613 10614##### `isInvertColorsEnabled()` (iOS) 10615 10616```typescript 10617static isInvertColorsEnabled(): Promise<boolean>; 10618``` 10619 10620Checks if invert colors mode is currently enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10621 10622##### `isReduceMotionEnabled()` 10623 10624```typescript 10625static isReduceMotionEnabled(): Promise<boolean>; 10626``` 10627 10628Checks if reduce motion is currently enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10629 10630##### `isReduceTransparencyEnabled()` (iOS) 10631 10632```typescript 10633static isReduceTransparencyEnabled(): Promise<boolean>; 10634``` 10635 10636Checks if reduce transparency mode is currently enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10637 10638##### `isScreenReaderEnabled()` 10639 10640```typescript 10641static isScreenReaderEnabled(): Promise<boolean>; 10642``` 10643 10644Checks if a screen reader is currently enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10645 10646##### `prefersCrossFadeTransitions()` (iOS) 10647 10648```typescript 10649static prefersCrossFadeTransitions(): Promise<boolean>; 10650``` 10651 10652Checks if reduce motion and prefer cross-fade transitions settings are enabled. Returns a promise resolving to a boolean: `true` if enabled, otherwise `false`. 10653 10654##### `setAccessibilityFocus()` 10655 10656```typescript 10657static setAccessibilityFocus(reactTag: number); 10658``` 10659 10660Sets accessibility focus on a React component by calling `UIManager.sendAccessibilityEvent` with the specified `reactTag` and `UIManager.AccessibilityEventTypes.typeViewFocused`. 10661 10662> **Note**: Ensure any `View` intended to receive accessibility focus has `accessible={true}`. 10663 10664## AppState 10665 10666The `AppState` module provides information about whether an application is in the foreground or background and notifies you of any state changes. It's particularly useful for determining how to handle push notifications based on the app's current state. 10667 10668### App States 10669 10670- **active**: The app is running in the foreground. 10671- **background**: The app is running in the background, with the user either: 10672 - In another application 10673 - On the home screen 10674 - \[Android] Engaged in a different `Activity`, even if initiated by your app 10675- \[iOS] **inactive**: This state occurs during transitions between foreground and background or when the device is inactive, such as entering multitasking view, opening Notification Center, or receiving an incoming call. 10676 10677For more details, refer to Apple's documentation. 10678 10679### Basic Usage 10680 10681To check the current state of the app, use `AppState.currentState`, which remains updated. Note that `currentState` will be null at launch while `AppState` retrieves it over the bridge. This example typically displays "Current state is: active" because the app is visible only in the `active` state, and the null state occurs briefly. For experimentation, using your own device instead of an embedded preview is recommended. 10682 10683### Reference 10684 10685#### Events 10686 10687- **change**: Triggered when the app state changes. The listener receives one of the current app state values. 10688 10689- **memoryWarning**: Used to handle memory warnings or release resources as needed. 10690 10691- **focus** \[Android]: Fired when the app gains focus, indicating user interaction with the app. 10692 10693- **blur** \[Android]: Triggered when the user is not actively interacting with the app. Useful for detecting actions like pulling down the notification drawer. The `AppState` state remains unchanged, but the `blur` event is fired. 10694 10695#### Methods 10696 10697##### `addEventListener()` 10698 10699```typescript 10700static addEventListener( 10701 type: AppStateEvent, 10702 listener: (state: AppStateStatus) => void, 10703): NativeEventSubscription; 10704``` 10705 10706Sets up a function to be called whenever the specified event type on `AppState` occurs. Valid values for `type` are listed above. Returns an `EventSubscription`. 10707 10708#### Properties 10709 10710##### `currentState` 10711 10712```typescript 10713static currentState: AppStateStatus; 10714``` 10715 10716## Platform 10717 10718### Example 10719 10720*** 10721 10722### Reference 10723 10724### Properties 10725 10726#### `constants` 10727 10728```typescript 10729static constants: PlatformConstants; 10730``` 10731 10732Returns an object containing all common and specific platform-related constants. 10733 10734**Properties:** 10735 10736|Name|Type|Optional|Description| 10737|-|-|-|-| 10738|isTesting|boolean|No|| 10739|reactNativeVersion|object|No|Information about React Native version. Keys are `major`, `minor`, `patch` with optional `prerelease` and values are `number`s.| 10740|VersionAndroid|number|No|OS version constant specific to Android.| 10741|ReleaseAndroid|string|No|| 10742|SerialAndroid|string|No|Hardware serial number of an Android device.| 10743|FingerprintAndroid|string|No|A unique identifier for the build.| 10744|ModelAndroid|string|No|The end-user-visible name for the Android device.| 10745|BrandAndroid|string|No|The consumer-visible brand associated with the product/hardware.| 10746|ManufacturerAndroid|string|No|The manufacturer of the Android device.| 10747|ServerHostAndroid|string|Yes|| 10748|uiModeAndroid|string|No|Possible values: `'car'`, `'desk'`, `'normal'`,`'tv'`, `'watch'` and `'unknown'`. Read more about Android ModeType.| 10749|forceTouchAvailableiOS|boolean|No|Indicates the availability of 3D Touch on a device.| 10750|interfaceIdiomiOS|string|No|The interface type for the device. Read more about UIUserInterfaceIdiom.| 10751|osVersioniOS|string|No|OS version constant specific to iOS.| 10752|systemNameiOS|string|No|OS name constant specific to iOS.| 10753 10754*** 10755 10756#### `isPad`iOS 10757 10758```typescript 10759static isPad: boolean; 10760``` 10761 10762Returns a boolean indicating if the device is an iPad. 10763 10764|Type| 10765|-| 10766|boolean| 10767 10768*** 10769 10770#### `isTV` 10771 10772```typescript 10773static isTV: boolean; 10774``` 10775 10776Returns a boolean indicating if the device is a TV. 10777 10778|Type| 10779|-| 10780|boolean| 10781 10782*** 10783 10784#### `isVision` 10785 10786```typescript 10787static isVision: boolean; 10788``` 10789 10790Returns a boolean indicating if the device is an Apple Vision. Note that for Apple Vision Pro (Designed for iPad), `isVision` will be `false`, but `isPad` will be `true`. 10791 10792|Type| 10793|-| 10794|boolean| 10795 10796*** 10797 10798#### `isTesting` 10799 10800```typescript 10801static isTesting: boolean; 10802``` 10803 10804Returns a boolean indicating if the application is running in Developer Mode with the testing flag set. 10805 10806|Type| 10807|-| 10808|boolean| 10809 10810*** 10811 10812#### `OS` 10813 10814```typescript 10815static OS: 'android' | 'ios'; 10816``` 10817 10818Returns a string representing the current operating system. 10819 10820|Type| 10821|-| 10822|enum(`'android'`, `'ios'`)| 10823 10824*** 10825 10826#### `Version` 10827 10828```typescript 10829static Version: 'number' | 'string'; 10830``` 10831 10832Returns the version of the OS, as either a number for Android or a string for iOS. 10833 10834|Type| 10835|-| 10836|numberAndroid\*\*\*stringiOS| 10837 10838### Methods 10839 10840#### `select()` 10841 10842```typescript 10843static select<T>(config: Record<string, T>): T; 10844``` 10845 10846Returns the most fitting value for the platform you are currently running on. 10847 10848##### Parameters: 10849 10850|Name|Type|Required|Description| 10851|-|-|-|-| 10852|config|object|Yes|See configuration description below.| 10853 10854The `select` method returns the most appropriate value based on the current platform. If running on a phone, keys for `android` and `ios` take precedence. If these are not specified, the `native` key is used, followed by the `default` key. 10855 10856The `config` parameter is an object with the following keys: 10857 10858- `android`: any 10859- `ios`: any 10860- `native`: any 10861- `default`: any 10862 10863**Example usage:** 10864 10865```typescript 10866import { Platform, StyleSheet } from "react-native" 10867 10868const styles = StyleSheet.create({ 10869 container: { 10870 flex: 1, 10871 ...Platform.select({ 10872 android: { 10873 backgroundColor: "green", 10874 }, 10875 ios: { 10876 backgroundColor: "red", 10877 }, 10878 default: { 10879 // other platforms, web for example 10880 backgroundColor: "blue", 10881 }, 10882 }), 10883 }, 10884}) 10885``` 10886 10887This results in a container with `flex: 1` on all platforms. It has a green background color on Android, red on iOS, and blue on other platforms. 10888 10889Since the value of the corresponding platform key can be of type `any`, the `select` method can also return platform-specific components: 10890 10891```typescript 10892const Component = Platform.select({ 10893 ios: () => require('ComponentIOS'), 10894 android: () => require('ComponentAndroid'), 10895})(); 10896 10897<Component />; 10898``` 10899 10900```typescript 10901const Component = Platform.select({ 10902 native: () => require('ComponentForNative'), 10903 default: () => require('ComponentForWeb'), 10904})(); 10905 10906<Component />; 10907``` 10908 10909## Using TypeScript 10910 10911TypeScript enhances JavaScript by adding type definitions. New React Native projects target TypeScript by default, but also support JavaScript and Flow. 10912 10913### Getting Started with TypeScript 10914 10915React Native CLI or popular templates like Ignite create new projects using TypeScript by default. 10916 10917TypeScript can be used with Expo, which provides TypeScript templates or prompts for automatic installation and configuration when a `.ts` or `.tsx` file is added to your project. 10918 10919```shell 10920npx create-expo-app --template 10921``` 10922 10923### Adding TypeScript to an Existing Project 10924 109251. Install TypeScript, types, and ESLint plugins: 10926 10927 - **npm** 10928 10929 ```shell 10930 npm install -D typescript @react-native/typescript-config @types/jest @types/react @types/react-test-renderer 10931 ``` 10932 10933 - **Yarn** 10934 ```shell 10935 yarn add --dev typescript @react-native/typescript-config @types/jest @types/react @types/react-test-renderer 10936 ``` 10937 10938 > Note: This command installs the latest versions of dependencies. You may need to adjust versions to match existing packages in your project using tools like React Native Upgrade Helper. 10939 109401. Create a `tsconfig.json` file at the root of your project: 10941 10942 ```json 10943 { 10944 "extends": "@react-native/typescript-config" 10945 } 10946 ``` 10947 109481. Rename a JavaScript file to use `.tsx`. 10949 10950 > Keep the `./index.js` entrypoint file unchanged to avoid bundling issues in production builds. 10951 109521. Run `tsc` for type-checking: 10953 10954 - **npm** 10955 10956 ```shell 10957 npx tsc 10958 ``` 10959 10960 - **Yarn** 10961 ```shell 10962 yarn tsc 10963 ``` 10964 10965### Using JavaScript Instead of TypeScript 10966 10967React Native defaults to TypeScript, but `.jsx` files are treated as JavaScript and won't be type-checked. JavaScript modules can still be imported by TypeScript modules and vice versa. 10968 10969### How TypeScript and React Native Work 10970 10971TypeScript sources are transformed by Babel during bundling. It's recommended to use the TypeScript compiler only for type checking, which is `tsc`'s default behavior in new applications. Existing TypeScript code ported to React Native may require adjustments when using Babel instead of TypeScript. 10972 10973### Example: React Native + TypeScript 10974 10975You can define interfaces for a React Component's Props and State using `React.Component<Props, State>`, enabling type-checking and editor auto-completion: 10976 10977```tsx 10978import { useState } from "react" 10979import { Button, StyleSheet, Text, View } from "react-native" 10980 10981export type Props = { 10982 name: string 10983 baseEnthusiasmLevel?: number 10984} 10985 10986function Hello({ name, baseEnthusiasmLevel = 0 }: Props) { 10987 const [enthusiasmLevel, setEnthusiasmLevel] = useState(baseEnthusiasmLevel) 10988 10989 const onIncrement = () => setEnthusiasmLevel(enthusiasmLevel + 1) 10990 const onDecrement = () => 10991 setEnthusiasmLevel(enthusiasmLevel > 0 ? enthusiasmLevel - 1 : 0) 10992 10993 const getExclamationMarks = (numChars: number) => 10994 numChars > 0 ? Array(numChars + 1).join("!") : "" 10995 10996 return ( 10997 <View style={styles.container}> 10998 <Text style={styles.greeting}> 10999 Hello {name} 11000 {getExclamationMarks(enthusiasmLevel)} 11001 </Text> 11002 <View> 11003 <Button 11004 title="Increase enthusiasm" 11005 accessibilityLabel="increment" 11006 onPress={onIncrement} 11007 color="blue" 11008 /> 11009 <Button 11010 title="Decrease enthusiasm" 11011 accessibilityLabel="decrement" 11012 onPress={onDecrement} 11013 color="red" 11014 /> 11015 </View> 11016 </View> 11017 ) 11018} 11019 11020const styles = StyleSheet.create({ 11021 container: { 11022 flex: 1, 11023 alignItems: "center", 11024 justifyContent: "center", 11025 }, 11026 greeting: { 11027 fontSize: 20, 11028 fontWeight: "bold", 11029 margin: 16, 11030 }, 11031}) 11032 11033export default Hello 11034``` 11035 11036Explore more syntax in the TypeScript playground. 11037 11038### Where to Find Useful Advice 11039 11040- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html) 11041- React's documentation on TypeScript 11042- React + TypeScript Cheatsheets for an overview of using React with TypeScript 11043 11044### Using Custom Path Aliases with TypeScript 11045 11046To use custom path aliases, configure both Babel and TypeScript: 11047 110481. Update `tsconfig.json` to include custom path mappings: 11049 11050 ```json 11051 { 11052 "extends": "@react-native/typescript-config", 11053 "compilerOptions": { 11054 "baseUrl": ".", 11055 "paths": { 11056 "*": ["src/*"], 11057 "tests": ["tests/*"], 11058 "@components/*": ["src/components/*"] 11059 } 11060 } 11061 } 11062 ``` 11063 110641. Install `babel-plugin-module-resolver`: 11065 11066 - **npm** 11067 11068 ```shell 11069 npm install --save-dev babel-plugin-module-resolver 11070 ``` 11071 11072 - **Yarn** 11073 ```shell 11074 yarn add --dev babel-plugin-module-resolver 11075 ``` 11076 110771. Configure `babel.config.js`: 11078 11079 ```json 11080 { 11081 "presets": ["module:metro-react-native-babel-preset"], 11082 "plugins": [ 11083 [ 11084 "module-resolver", 11085 { 11086 "root": ["./src"], 11087 "extensions": [ 11088 ".ios.js", 11089 ".android.js", 11090 ".js", 11091 ".ts", 11092 ".tsx", 11093 ".json" 11094 ], 11095 "alias": { 11096 "tests": ["./tests/"], 11097 "@components": "./src/components" 11098 } 11099 } 11100 ] 11101 ] 11102 } 11103 ``` 11104 11105## VirtualizedList 11106 11107The `VirtualizedList` component serves as a foundational implementation for more user-friendly components like `<FlatList>` and `<SectionList>`. It is particularly useful when additional flexibility is required, such as working with immutable data structures instead of plain arrays. 11108 11109Virtualization significantly enhances memory efficiency and performance in handling large lists by maintaining only a finite number of active items within the render window. Items outside this window are replaced with appropriately sized blank spaces. The size of this window dynamically adjusts based on scrolling behavior, rendering items incrementally at low priority if they are far from the visible area or at high priority otherwise to minimize blank space visibility. 11110 11111### Example 11112 11113- TypeScript 11114- JavaScript 11115 11116#### Caveats: 11117 11118- Internal state is not preserved when content scrolls out of the render window. Ensure all data is captured within item data or external stores like Flux, Redux, or Relay. 11119- As a `PureComponent`, it will not re-render if props are shallow-equal. Ensure that everything your `renderItem` function depends on is passed as a prop (e.g., `extraData`) and is not strictly equal after updates to ensure UI updates on changes. This includes the `data` prop and parent component state. 11120- To maintain memory constraints and enable smooth scrolling, content is rendered asynchronously offscreen. This may result in faster-than-fill-rate scrolling revealing blank content temporarily. This tradeoff can be adjusted per application needs, with ongoing improvements being made behind the scenes. 11121- By default, the list looks for a `key` prop on each item to use as the React key. Alternatively, you can provide a custom `keyExtractor` prop. 11122 11123### Reference 11124 11125#### Props 11126 11127##### ScrollView Props 11128 11129Inherits ScrollView Props. 11130 11131##### `data` 11132 11133Opaque data type passed to `getItem` and `getItemCount` to retrieve items. 11134 11135- **Type**: any 11136 11137##### Require `getItem` 11138 11139```typescript 11140;(data: any, index: number) => any 11141``` 11142 11143A generic accessor for extracting an item from any sort of data blob. 11144 11145- **Type**: function 11146 11147##### Require `getItemCount` 11148 11149```typescript 11150;(data: any) => number 11151``` 11152 11153Determines how many items are in the data blob. 11154 11155- **Type**: function 11156 11157##### Require `renderItem` 11158 11159```typescript 11160(info: any) => ?React.Element<any> 11161``` 11162 11163Takes an item from `data` and renders it into the list. 11164 11165- **Type**: function 11166 11167##### `CellRendererComponent` 11168 11169Customizes how cells rendered by `renderItem`/`ListItemComponent` are wrapped within the underlying ScrollView. This component must accept event handlers notifying VirtualizedList of changes within the cell. 11170 11171- **Type**: `React.ComponentType<CellRendererProps>` 11172 11173##### `ItemSeparatorComponent` 11174 11175Rendered between each item, excluding the top and bottom. By default, `highlighted` and `leadingItem` props are provided. `renderItem` provides `separators.highlight`/`unhighlight` to update the `highlighted` prop, with custom props added via `separators.updateProps`. Can be a React Component (e.g., `SomeComponent`) or a React element (e.g., `<SomeComponent />`). 11176 11177- **Type**: component, function, element 11178 11179##### `ListEmptyComponent` 11180 11181Rendered when the list is empty. Can be a React Component (e.g., `SomeComponent`) or a React element (e.g., `<SomeComponent />`). 11182 11183- **Type**: component, element 11184 11185##### `ListItemComponent` 11186 11187Each data item is rendered using this element. Can be a React Component Class or a render function. 11188 11189- **Type**: component, function 11190 11191##### `ListFooterComponent` 11192 11193Rendered at the bottom of all items. Can be a React Component (e.g., `SomeComponent`) or a React element (e.g., `<SomeComponent />`). 11194 11195- **Type**: component, element 11196 11197##### `ListFooterComponentStyle` 11198 11199Styling for internal View for `ListFooterComponent`. 11200 11201- **Type**: ViewStyleProp 11202- **Required**: No 11203 11204##### `ListHeaderComponent` 11205 11206Rendered at the top of all items. Can be a React Component (e.g., `SomeComponent`) or a React element (e.g., `<SomeComponent />`). 11207 11208- **Type**: component, element 11209 11210##### `ListHeaderComponentStyle` 11211 11212Styling for internal View for `ListHeaderComponent`. 11213 11214- **Type**: View Style 11215 11216##### `debug` 11217 11218Enables extra logging and visual overlays to aid debugging of usage and implementation, with a significant performance hit. 11219 11220- **Type**: boolean 11221 11222##### `disableVirtualization` 11223 11224> **Deprecated.** Virtualization provides significant performance and memory optimizations by fully unmounting React instances outside the render window. Only disable for debugging purposes. 11225 11226- **Type**: boolean 11227 11228##### `extraData` 11229 11230A marker property to trigger re-rendering since it implements `PureComponent`. If your `renderItem`, `ListEmptyComponent`, or other components depend on external data, pass this as a prop and ensure it changes when the data updates. 11231 11232##### `flashScrollIndicators()` 11233 11234```typescript 11235flashScrollIndicators() 11236``` 11237 11238##### `getScrollableNode()` 11239 11240```typescript 11241getScrollableNode(): any; 11242``` 11243 11244##### `getScrollRef()` 11245 11246```typescript 11247getScrollRef(): 11248 | React.ElementRef<typeof ScrollView> 11249 | React.ElementRef<typeof View> 11250 | null; 11251``` 11252 11253##### `getScrollResponder()` 11254 11255```typescript 11256getScrollResponder () => ScrollResponderMixin | null; 11257``` 11258 11259Provides a handle to the underlying scroll responder. Note that `this._scrollRef` might not be a `ScrollView`, so we need to check that it responds to `getScrollResponder` before calling it. 11260 11261##### `persistentScrollbar` 11262 11263- **Type**: bool 11264 11265##### `progressViewOffset` 11266 11267Set this when an offset is needed for the loading indicator to show correctly. 11268 11269- **Type**: number 11270 11271##### `refreshControl` 11272 11273A custom refresh control element. When set, it overrides the default `<RefreshControl>` component built internally. The `onRefresh` and `refreshing` props are also ignored. Only works for vertical VirtualizedList. 11274 11275- **Type**: element 11276 11277##### `refreshing` 11278 11279Set this to true while waiting for new data from a refresh. 11280 11281- **Type**: boolean 11282 11283##### `removeClippedSubviews` 11284 11285This may improve scroll performance for large lists. 11286 11287> Note: May have bugs (missing content) in some circumstances - use at your own risk. 11288 11289- **Type**: boolean 11290 11291##### `renderScrollComponent` 11292 11293```typescript 11294;(props: object) => element 11295``` 11296 11297Render a custom scroll component, e.g., with a differently styled `RefreshControl`. 11298 11299- **Type**: function 11300 11301##### `scrollToEnd()` 11302 11303```typescript 11304scrollToEnd(params?: {animated?: boolean}); 11305``` 11306 11307Scrolls to the end of the content. May be janky without the `getItemLayout` prop. 11308 11309**Parameters:** 11310 11311- Name: params 11312- Type: object 11313 11314Valid `params` keys are: 11315 11316- `'animated'` (boolean) - Whether the list should do an animation while scrolling. Defaults to `true`. 11317 11318##### `scrollToIndex()` 11319 11320```typescript 11321scrollToIndex(params: { 11322 index: number; 11323 animated?: boolean; 11324 viewOffset?: number; 11325 viewPosition?: number; 11326}); 11327``` 11328 11329Valid `params` consist of: 11330 11331- `'index'` (number). Required. 11332- `'animated'` (boolean). Optional. 11333- `'viewOffset'` (number). Optional. 11334- `'viewPosition'` (number). Optional. 11335 11336##### `scrollToItem()` 11337 11338```typescript 11339scrollToItem(params: { 11340 item: ItemT; 11341 animated?: boolean; 11342 viewOffset?: number; 11343 viewPosition?: number; 11344}); 11345``` 11346 11347Valid `params` consist of: 11348 11349- `'item'` (Item). Required. 11350- `'animated'` (boolean). Optional. 11351- `'viewOffset'` (number). Optional. 11352- `'viewPosition'` (number). Optional. 11353 11354##### `scrollToOffset()` 11355 11356```typescript 11357scrollToOffset(params: { 11358 offset: number; 11359 animated?: boolean; 11360}); 11361``` 11362 11363Scroll to a specific content pixel offset in the list. Param `offset` expects the offset to scroll to. In case of `horizontal` is true, the offset is the x-value; otherwise, it's the y-value. Param `animated` (`true` by default) defines whether the list should do an animation while scrolling. 11364 11365##### `viewabilityConfig` 11366 11367See `ViewabilityHelper.js` for flow type and further documentation. 11368 11369- **Type**: ViewabilityConfig 11370 11371##### `viewabilityConfigCallbackPairs` 11372 11373List of `ViewabilityConfig`/`onViewableItemsChanged` pairs. A specific `onViewableItemsChanged` will be called when its corresponding `ViewabilityConfig`'s conditions are met. See `ViewabilityHelper.js` for flow type and further documentation. 11374 11375- **Type**: array of ViewabilityConfigCallbackPair 11376 11377##### `updateCellsBatchingPeriod` 11378 11379Amount of time between low-priority item render batches, e.g., for rendering items quite a ways off screen. Similar fill rate/responsiveness tradeoff as `maxToRenderPerBatch`. 11380 11381- **Type**: number 11382 11383##### `windowSize` 11384 11385Determines the maximum number of items rendered outside of the visible area, in units of visible lengths. For example, if your list fills the screen, then `windowSize={21}` (the default) will render the visible screen area plus up to 10 screens above and below the viewport. Reducing this number will decrease memory consumption and may improve performance but increase the chance that fast scrolling reveals momentary blank areas of unrendered content. 11386 11387- **Type**: number 11388 11389## RootTag 11390 11391The `RootTag` serves as an opaque identifier for the native root view in React Native applications. This refers to instances like `ReactRootView` or `RCTRootView` on Android and iOS platforms, respectively. Essentially, it acts as a surface identifier. 11392 11393### When to Use a RootTag? 11394 11395For most developers working with React Native, handling `RootTags` might not be necessary. However, they become crucial when an application renders multiple React Native root views, necessitating distinct handling of native API calls for each view. A common scenario is using native navigation where each screen corresponds to a separate React Native root view. 11396 11397In such setups, every React Native root view is embedded within the platform's navigation component (e.g., `Activity` on Android or `UINavigationViewController` on iOS). This allows developers to utilize platform-specific navigation features like native look and feel and transitions. Interactions with these native navigation APIs can be facilitated through a native module. 11398 11399For instance, updating a screen’s title bar might involve calling the navigation module's API method `setTitle("Updated Title")`. To specify which screen in the stack should have its title updated, a `RootTag` is required to identify the relevant root view and its container. 11400 11401Another scenario for using `RootTag` arises when an application needs to attribute JavaScript calls to their native origins based on different root views. A `RootTag` helps differentiate these calls across various surfaces. 11402 11403### Accessing RootTag 11404 11405In React Native versions 0.65 and earlier, accessing a `RootTag` was done through a legacy context. With the introduction of Concurrent features in React 18, React Native transitioned to using the latest Context API via `RootTagContext` starting from version 0.66. Version 0.65 supports both the legacy context and the new `RootTagContext`, providing developers time to migrate their code. 11406 11407#### Accessing RootTag with RootTagContext 11408 11409```typescript 11410import { useContext } from "react" 11411import { RootTagContext } from "react-native" 11412import NativeAnalytics from "native-analytics" 11413import NativeNavigation from "native-navigation" 11414 11415function ScreenA() { 11416 const rootTag = useContext(RootTagContext) 11417 11418 const updateTitle = (title: string) => { 11419 NativeNavigation.setTitle(rootTag, title) 11420 } 11421 11422 const handleOneEvent = () => { 11423 NativeAnalytics.logEvent(rootTag, "one_event") 11424 } 11425 11426 // ... 11427} 11428 11429class ScreenB extends React.Component { 11430 static contextType = RootTagContext 11431 11432 updateTitle(title: string) { 11433 NativeNavigation.setTitle(this.context, title) 11434 } 11435 11436 handleOneEvent() { 11437 NativeAnalytics.logEvent(this.context, "one_event") 11438 } 11439 11440 // ... 11441} 11442``` 11443 11444For more information on using the Context API with classes and hooks, refer to the React documentation. 11445 11446#### Breaking Changes 11447 11448- **Version 0.65**: The `RootTagContext` was previously named `unstable_RootTagContext`. It has been renamed to `RootTagContext`, so any references in your codebase should be updated accordingly. 11449 11450- **Version 0.66**: Access via the legacy context for `RootTag` will be removed, with `RootTagContext` taking its place. Developers are encouraged to migrate their usage of `RootTag` to `RootTagContext` starting from version 0.65. 11451 11452### Future Plans 11453 11454As React Native's architecture evolves, future updates to `RootTag` aim to maintain its opaque nature and prevent unnecessary complexity in codebases. It is important not to rely on the current implementation where `RootTag` aliases to a number. Developers relying on `RootTags` should monitor version change logs for updates. 11455 11456## DevSettings Module 11457 11458The `DevSettings` module provides methods for developers to customize settings during development. 11459 11460### Reference 11461 11462#### Methods 11463 11464##### `addMenuItem()` 11465 11466```typescript 11467static addMenuItem(title: string, handler: () => any): void; 11468``` 11469 11470Adds a custom menu item to the Developer Menu. 11471 11472**Parameters:** 11473 11474|Name|Type| 11475|-|-| 11476|title|string| 11477|handler|function| 11478 11479**Example Usage:** 11480 11481```typescript 11482DevSettings.addMenuItem("Show Secret Dev Screen", () => { 11483 Alert.alert("Showing secret dev screen!") 11484}) 11485``` 11486 11487##### `reload()` 11488 11489```typescript 11490static reload(reason?: string): void; 11491``` 11492 11493Reloads the application. This can be triggered directly or through user interaction. 11494 11495**Example Usage:** 11496 11497```typescript 11498<Button title="Reload" onPress={() => DevSettings.reload()} /> 11499``` 11500 11501*** 11502 11503### Related Modules 11504 11505- **AccessibilityInfo** 11506 11507 - Alert 11508 - Animated 11509 - Animated.Value 11510 - Animated.ValueXY 11511 - Appearance 11512 - AppRegistry 11513 - AppState 11514 - Dimensions 11515 - Easing 11516 - InteractionManager 11517 - Keyboard 11518 - LayoutAnimation 11519 - Linking 11520 - PanResponder 11521 - PixelRatio 11522 - Platform 11523 - PlatformColor 11524 - RootTag 11525 - Share 11526 - StyleSheet 11527 - Systrace 11528 - Transforms 11529 - Vibration 11530 11531- **Hooks** 11532 11533 - useColorScheme 11534 - useWindowDimensions 11535 11536- **iOS Specific Modules** 11537 11538 - ActionSheetIOS 11539 - DynamicColorIOS 11540 - Settings 11541 11542- **Android Specific Modules** 11543 - BackHandler 11544 - PermissionsAndroid 11545 - ToastAndroid 11546 11547## Share 11548 11549### Example 11550 11551- TypeScript 11552- JavaScript 11553 11554### Reference 11555 11556### Methods 11557 11558```typescript 11559static share(content: ShareContent, options?: ShareOptions): Promise<any>; 11560``` 11561 11562This method opens a dialog to share text content. 11563 11564#### iOS Behavior: 11565 11566- Returns a `Promise` that resolves with an object containing `action` and `activityType`. 11567- If the user dismisses the dialog, the `Promise` is resolved with `action` set to `Share.dismissedAction`, while other keys remain undefined. 11568- Note: Some share options may not appear or function on the iOS simulator. 11569 11570#### Android Behavior: 11571 11572- Returns a `Promise` that always resolves with `action` being `Share.sharedAction`. 11573 11574**Properties:** 11575 11576|Name|Type|Description| 11577|-|-|-| 11578|contentRequired|object|- `message`: A message to share<br>- `url`: A URL to share<br>- iOS: `title`: Title of the message<br>- Android: At least one of `url` or `message` is required.| 11579|options|object|- Android: `dialogTitle`<br>- iOS: `excludedActivityTypes`, `subject` (a subject for email), `tintColor`, `anchor` (node to anchor the action sheet, used on iPad)| 11580 11581### Properties 11582 11583#### `sharedAction` 11584 11585```typescript 11586static sharedAction: 'sharedAction'; 11587``` 11588 11589Indicates that the content was successfully shared. 11590 11591#### `dismissedAction` (iOS) 11592 11593```typescript 11594static dismissedAction: 'dismissedAction'; 11595``` 11596 11597Indicates that the dialog has been dismissed. 11598 11599## React Node Object Type 11600 11601A React Node can be one of several types: 11602 11603- **Boolean**: This type is ignored. 11604- `null` or `undefined`: These are also ignored. 11605- **Number** 11606- **String** 11607- A **React element**, which results from JSX. 11608- An array containing any of the above types, potentially nested. 11609 11610*** 11611 11612### Related Object Types 11613 11614- BoxShadowValue Object Type 11615- DropShadowValue Object Type 11616- LayoutEvent Object Type 11617- PressEvent Object Type 11618- Rect Object Type 11619- ViewToken Object Type 11620 11621*** 11622 11623#### Navigation 11624 11625- [Previous: PressEvent Object Type](#) 11626- [Next: Rect Object Type](#) 11627 11628## StyleSheet 11629 11630A `StyleSheet` serves as an abstraction similar to CSS StyleSheets. It enhances code quality by: 11631 11632- Moving styles away from the render function, making the code easier to understand. 11633- Naming styles adds meaning to low-level components in the render function and encourages reuse. 11634- In most IDEs, using `StyleSheet.create()` provides static type checking and suggestions for writing valid styles. 11635 11636### Reference 11637 11638#### Methods 11639 11640##### `compose()` 11641 11642```typescript 11643static compose(style1: Object, style2: Object): Object | Object[]; 11644``` 11645 11646Combines two styles such that `style2` will override any styles in `style1`. If either style is falsy, the other one is returned without allocating an array. This approach saves allocations and maintains reference equality for PureComponent checks. 11647 11648##### `create()` 11649 11650```typescript 11651static create(styles: Object extends Record<string, ViewStyle | ImageStyle | TextStyle>): Object; 11652``` 11653 11654An identity function for creating styles. The main practical benefit of using `StyleSheet.create()` is static type checking against native style properties. 11655 11656##### `flatten()` 11657 11658```typescript 11659static flatten(style: Array<Object extends Record<string, ViewStyle | ImageStyle | TextStyle>>): Object; 11660``` 11661 11662Flattens an array of style objects into one aggregated style object. 11663 11664##### `setStyleAttributePreprocessor()` 11665 11666> **WARNING: EXPERIMENTAL.** Breaking changes may occur frequently and will not be reliably announced. The feature might be deleted; use at your own risk. 11667 11668```typescript 11669static setStyleAttributePreprocessor( 11670 property: string, 11671 process: (propValue: any) => any, 11672); 11673``` 11674 11675Sets a function to pre-process a style property value. This is used internally for processing color and transform values. It should only be used if you are certain of its necessity after exploring other options. 11676 11677#### Properties 11678 11679##### `absoluteFill` 11680 11681A common pattern involves creating overlays with position absolute and zero positioning (`position: 'absolute', left: 0, right: 0, top: 0, bottom: 0`). The `absoluteFill` property is used for convenience to reduce duplication of these repeated styles. It can be customized in a StyleSheet. 11682 11683##### `absoluteFillObject` 11684 11685For cases where you need `absoluteFill` with slight modifications, `absoluteFillObject` allows customization within a StyleSheet. 11686 11687##### `hairlineWidth` 11688 11689Defined as the width of a thin line on the platform, this property is useful for setting the thickness of borders or divisions between elements. It ensures crisp lines by being a round number of pixels and attempts to match the standard width of a thin line on the underlying platform. However, its value may vary across different platforms and screen densities. 11690 11691A line with `hairlineWidth` might not be visible if your simulator is downscaled. 11692 11693## Dimensions 11694 11695`useWindowDimensions` is the recommended API for React components, as it updates automatically with changes to the window's dimensions. This aligns well with the React paradigm. 11696 11697```typescript 11698import { Dimensions } from "react-native" 11699``` 11700 11701To obtain the application window's width and height, use: 11702 11703```typescript 11704const windowWidth = Dimensions.get("window").width 11705const windowHeight = Dimensions.get("window").height 11706``` 11707 11708> Note: While dimensions are available immediately, they can change due to factors like device rotation or foldable devices. Therefore, rendering logic or styles dependent on these values should call this function on every render instead of caching the value (e.g., using inline styles rather than setting a value in a `StyleSheet`). 11709 11710For targeting foldable devices or those that can alter screen size or app window size, use the event listener provided by the Dimensions module as demonstrated below. 11711 11712### Example 11713 11714### Reference 11715 11716### Methods 11717 11718#### `addEventListener()` 11719 11720```typescript 11721static addEventListener( 11722 type: 'change', 11723 handler: ({ 11724 window, 11725 screen, 11726 }: DimensionsValue) => void, 11727): EmitterSubscription; 11728``` 11729 11730Add an event handler. Supported events: 11731 11732- `change`: Triggers when a property within the `Dimensions` object changes. The argument to the event handler is of type `DimensionsValue`. 11733 11734*** 11735 11736#### `get()` 11737 11738```typescript 11739static get(dim: 'window' | 'screen'): ScaledSize; 11740``` 11741 11742Initial dimensions are set before `runApplication` is called, making them available before any other requires are executed, though they may be updated later. 11743 11744Example usage: 11745 11746```typescript 11747const { height, width } = Dimensions.get("window") 11748``` 11749 11750**Parameters:** 11751 11752|Name|Type|Description| 11753|-|-|-| 11754|dimRequired|string|The name of the dimension as defined when calling `set`. Returns value for the dimension.| 11755 11756> Note: On Android, the `window` dimension excludes the size used by the status bar (if not translucent) and bottom navigation bar. 11757 11758*** 11759 11760### Type Definitions 11761 11762#### DimensionsValue 11763 11764**Properties:** 11765 11766|Name|Type|Description| 11767|-|-|-| 11768|window|ScaledSize|Size of the visible Application window.| 11769|screen|ScaledSize|Size of the device's screen.| 11770 11771#### ScaledSize 11772 11773|Type| 11774|-| 11775|object| 11776 11777**Properties:** 11778 11779|Name|Type| 11780|-|-| 11781|width|number| 11782|height|number| 11783|scale|number| 11784|fontScale|number| 11785 11786## Props 11787 11788In React Native, most components are customizable through parameters known as `props`, short for properties. These allow developers to tailor component behavior and appearance. 11789 11790### Example: The Image Component 11791 11792Consider the basic `Image` component. It uses a prop named `source` to determine which image is displayed: 11793 11794```typescript 11795<Image source={pic} /> 11796``` 11797 11798Here, `{pic}` embeds the JavaScript variable `pic` into JSX. Any valid JavaScript expression can be placed within braces in JSX. 11799 11800### Custom Components with Props 11801 11802Custom components can also utilize `props`, enabling a single component to serve multiple purposes across an application by varying its properties. This is achieved by referencing `props` within the component's `render` function. Here’s how it works: 11803 11804#### Example: Greeting Component 11805 11806Using `name` as a prop allows customization of the `Greeting` component, making it reusable for different greetings. 11807 11808```typescript 11809function Greeting(props) { 11810 return <Text>Hello, {props.name}!</Text>; 11811} 11812 11813// Usage in JSX 11814<Greeting name="Alice" /> 11815``` 11816 11817This example demonstrates how components can be used similarly to Core Components. The ability to create and use custom components is a powerful feature of React. 11818 11819### View Component 11820 11821The `View` component acts as a container for other components, aiding in style and layout management: 11822 11823```typescript 11824<View> 11825 <Greeting name="Bob" /> 11826</View> 11827``` 11828 11829By leveraging `props` along with basic components like `Text`, `Image`, and `View`, developers can construct a variety of static screens. To create dynamic applications that change over time, understanding State is essential. 11830 11831## Animated.Value 11832 11833`Animated.Value` is the standard value used for driving animations in a synchronized manner across multiple properties, though it can only be driven by one mechanism at a time. Initiating a new animation or calling `setValue` will halt any ongoing ones. 11834 11835Typically initialized with `useAnimatedValue(0);` or `new Animated.Value(0);` in class components. 11836 11837### Reference 11838 11839#### Methods 11840 11841##### `setValue()` 11842 11843```typescript 11844setValue(value: number): void; 11845``` 11846 11847Directly sets the value, stopping any running animations and updating all bound properties. 11848 11849**Parameters:** 11850 11851- **value**: *number* (Required) - The new value to set. 11852 11853##### `setOffset()` 11854 11855```typescript 11856setOffset(offset: number): void; 11857``` 11858 11859Applies an offset on top of the current value, useful for adjustments like compensating a pan gesture start. 11860 11861**Parameters:** 11862 11863- **offset**: *number* (Required) - The offset value to apply. 11864 11865##### `flattenOffset()` 11866 11867```typescript 11868flattenOffset(): void; 11869``` 11870 11871Merges the offset into the base value and resets the offset to zero without changing the final output of the value. 11872 11873##### `extractOffset()` 11874 11875```typescript 11876extractOffset(): void; 11877``` 11878 11879Sets the offset to the base value, resetting the base value to zero while keeping the final output unchanged. 11880 11881##### `addListener()` 11882 11883```typescript 11884addListener(callback: (state: {value: number}) => void): string; 11885``` 11886 11887Adds an asynchronous listener for observing updates from animations. Returns a string identifier for the listener. 11888 11889**Parameters:** 11890 11891- **callback**: *function* (Required) - A function receiving an object with a `value` key set to the new value. 11892 11893##### `removeListener()` 11894 11895```typescript 11896removeListener(id: string): void; 11897``` 11898 11899Unregisters a listener using the identifier returned by `addListener()`. 11900 11901**Parameters:** 11902 11903- **id**: *string* (Required) - The identifier of the listener being removed. 11904 11905##### `removeAllListeners()` 11906 11907```typescript 11908removeAllListeners(): void; 11909``` 11910 11911Removes all registered listeners. 11912 11913##### `stopAnimation()` 11914 11915```typescript 11916stopAnimation(callback?: (value: number) => void): void; 11917``` 11918 11919Stops any running animation or tracking. Optionally invokes a callback with the final value, useful for updating state to match the animation position. 11920 11921**Parameters:** 11922 11923- **callback**: *function* (Optional) - A function receiving the final value after stopping the animation. 11924 11925##### `resetAnimation()` 11926 11927```typescript 11928resetAnimation(callback?: (value: number) => void): void; 11929``` 11930 11931Stops any animation and resets the value to its original state. Optionally invokes a callback with the original value. 11932 11933**Parameters:** 11934 11935- **callback**: *function* (Optional) - A function receiving the original value after resetting the animation. 11936 11937##### `interpolate()` 11938 11939```typescript 11940interpolate(config: InterpolationConfigType): void; 11941``` 11942 11943Interpolates the value before updating properties, e.g., mapping 0-1 to 0-10. See `AnimatedInterpolation.js` for details. 11944 11945**Parameters:** 11946 11947- **config**: *object* (Required) - Configuration object with keys: 11948 - **inputRange**: *array of numbers* 11949 - **outputRange**: *array of numbers or strings* 11950 - **easing** (optional): *function* returning a number given an input number 11951 - **extrapolate** (optional): *string* such as 'extend', 'identity', or 'clamp' 11952 - **extrapolateLeft** (optional): *string* such as 'extend', 'identity', or 'clamp' 11953 - **extrapolateRight** (optional): *string* such as 'extend', 'identity', or 'clamp' 11954 11955##### `animate()` 11956 11957```typescript 11958animate(animation: Animation, callback: () => void): void; 11959``` 11960 11961Typically used internally but can be utilized by a custom Animation class. 11962 11963**Parameters:** 11964 11965|Name|Type|Required|Description| 11966|-|-|-|-| 11967|animation|Animation|Yes|See `Animation.js`.| 11968|callback|function|Yes|Callback function.| 11969 11970## Systrace 11971 11972`Systrace` is a standard Android marker-based profiling tool included with the installation of the Android platform-tools package. It visualizes profiled code blocks, which are surrounded by start/end markers, in a colorful chart format. Both the Android SDK and React Native framework provide standard markers that can be visualized using `Systrace`. 11973 11974### Example 11975 11976`Systrace` enables marking JavaScript (JS) events with a tag and an integer value. Non-Timed JS events can be captured using EasyProfiler. 11977 11978### Reference 11979 11980### Methods 11981 11982#### `isEnabled()` 11983 11984```typescript 11985static isEnabled(): boolean; 11986``` 11987 11988#### `beginEvent()` 11989 11990```typescript 11991static beginEvent(eventName: string | (() => string), args?: EventArgs); 11992``` 11993 11994Use `beginEvent`/`endEvent` to start and end a profile within the same call stack frame. 11995 11996#### `endEvent()` 11997 11998```typescript 11999static endEvent(args?: EventArgs); 12000``` 12001 12002#### `beginAsyncEvent()` 12003 12004```typescript 12005static beginAsyncEvent( 12006 eventName: string | (() => string), 12007 args?: EventArgs, 12008): number; 12009``` 12010 12011Use `beginAsyncEvent`/`endAsyncEvent` to start and then end a profile where the end can occur on another thread or outside of the current stack frame. The returned cookie variable should be used as input into the `endAsyncEvent` call. 12012 12013#### `endAsyncEvent()` 12014 12015```typescript 12016static endAsyncEvent( 12017 eventName: EventName, 12018 cookie: number, 12019 args?: EventArgs, 12020); 12021``` 12022 12023#### `counterEvent()` 12024 12025```typescript 12026static counterEvent(eventName: string | (() => string), value: number); 12027``` 12028 12029Register the value to the profile name on the systrace timeline. 12030 12031## Easing 12032 12033The `Easing` module provides a collection of common easing functions used to create physically believable motion in animations, particularly with `Animated.timing()`. 12034 12035A visualization of some common easing functions can be found at [easings.net](https://easings.net/). 12036 12037### Predefined Animations 12038 12039The `Easing` module offers several predefined animations: 12040 12041- **Back**: An animation where the object moves slightly backward before proceeding forward. 12042- **Bounce**: A bouncing effect for animations. 12043- **Ease**: A basic inertial interaction, akin to an object gradually accelerating. 12044- **Elastic**: Simulates a spring-like oscillation. 12045 12046### Standard Functions 12047 12048The module includes three standard easing functions: 12049 12050- `linear` 12051- `quad` 12052- `cubic` 12053 12054Additionally, the `poly` function can be used for higher power functions like quartic and quintic. 12055 12056### Additional Mathematical Functions 12057 12058Other mathematical functions provided include: 12059 12060- **Bezier**: Implements a cubic bezier curve. 12061- **Circle**: Provides a circular easing function. 12062- **Sin**: Offers a sinusoidal function. 12063- **Exp**: An exponential function. 12064 12065#### Helpers to Modify Easing Functions 12066 12067- `in`: Runs an easing function forwards. 12068- `out`: Executes an easing function in reverse. 12069- `inOut`: Symmetrizes any easing function, running it forward for half the duration and backward for the remainder. 12070 12071### Example Usage 12072 12073The module can be used with TypeScript or JavaScript. 12074 12075### Reference Methods 12076 12077#### Stepping Functions 12078 12079##### `step0()` 12080 12081```typescript 12082static step0(n: number): number; 12083``` 12084 12085Returns 1 for any positive value of `n`. 12086 12087##### `step1()` 12088 12089```typescript 12090static step1(n: number): number; 12091``` 12092 12093Returns 1 if `n` is greater than or equal to 1. 12094 12095#### Linear Function 12096 12097##### `linear()` 12098 12099```typescript 12100static linear(t: number): number; 12101``` 12102 12103A linear function where position correlates directly with elapsed time.\ 12104[Visualization](https://cubic-bezier.com/#0,0,1,1) 12105 12106#### Basic Inertial Interaction 12107 12108##### `ease()` 12109 12110```typescript 12111static ease(t: number): number; 12112``` 12113 12114Simulates an object slowly accelerating to speed.\ 12115[Visualization](https://cubic-bezier.com/#.42,0,1,1) 12116 12117#### Quadratic Function 12118 12119##### `quad()` 12120 12121```typescript 12122static quad(t: number): number; 12123``` 12124 12125Position equals the square of elapsed time.\ 12126[Visualization](https://easings.net/#easeInQuad) 12127 12128#### Cubic Function 12129 12130##### `cubic()` 12131 12132```typescript 12133static cubic(t: number): number; 12134``` 12135 12136Position equals the cube of elapsed time.\ 12137[Visualization](https://easings.net/#easeInCubic) 12138 12139#### Power Function 12140 12141##### `poly(n)` 12142 12143```typescript 12144static poly(n: number): (t: number) => number; 12145``` 12146 12147Position is equal to the Nth power of elapsed time. 12148 12149- n = 4: [Quartic Visualization](https://easings.net/#easeInQuart) 12150- n = 5: [Quintic Visualization](https://easings.net/#easeInQuint) 12151 12152#### Sinusoidal Function 12153 12154##### `sin()` 12155 12156```typescript 12157static sin(t: number): number; 12158``` 12159 12160[Visualization](https://easings.net/#easeInSine) 12161 12162#### Circular Function 12163 12164##### `circle()` 12165 12166```typescript 12167static circle(t: number): number; 12168``` 12169 12170[Visualization](https://easings.net/#easeInCirc) 12171 12172#### Exponential Function 12173 12174##### `exp()` 12175 12176```typescript 12177static exp(t: number): number; 12178``` 12179 12180[Visualization](https://easings.net/#easeInExpo) 12181 12182#### Elastic Interaction 12183 12184##### `elastic(bounciness)` 12185 12186```typescript 12187static elastic(bounciness: number): (t: number) => number; 12188``` 12189 12190Simulates a spring oscillating back and forth. 12191 12192- Default bounciness is 1, with slight overshoot. 12193- Bounciness of 0 results in no overshoot. 12194- Higher values result in more overshoots.\ 12195 [Visualization](https://easings.net/#easeInElastic) 12196 12197#### Back Animation 12198 12199##### `back(s)` 12200 12201```typescript 12202static back(s: number): (t: number) => number; 12203``` 12204 12205Use with `Animated.parallel()` to create an effect where the object moves slightly backward at the start of the animation. 12206 12207#### Bouncing Effect 12208 12209##### `bounce()` 12210 12211```typescript 12212static bounce(t: number): number; 12213``` 12214 12215Provides a basic bouncing effect.\ 12216[Visualization](https://easings.net/#easeInBounce) 12217 12218#### Cubic Bezier Curve 12219 12220##### `bezier(x1, y1, x2, y2)` 12221 12222```typescript 12223static bezier(x1: number, y1: number, x2: number, y2: number): (t: number) => number; 12224``` 12225 12226Equivalent to CSS Transitions' `transition-timing-function`.\ 12227[Bezier Curve Tool](https://cubic-bezier.com/) 12228 12229#### Modify Easing Functions 12230 12231##### `in(easing)` 12232 12233```typescript 12234static in(easing: (t: number) => number): (t: number) => number; 12235``` 12236 12237Runs an easing function forwards. 12238 12239##### `out(easing)` 12240 12241```typescript 12242static out(easing: (t: number) => number): (t: number) => number; 12243``` 12244 12245Executes an easing function in reverse. 12246 12247##### `inOut(easing)` 12248 12249```typescript 12250static inOut(easing: (t: number) => number): (t: number) => number; 12251``` 12252 12253Symmetrizes any easing function, running it forward for half the duration and backward for the remainder. 12254 12255## Vibration 12256 12257This section describes how to make a device vibrate. 12258 12259### Example 12260 12261For Android applications, it is necessary to request the `android.permission.VIBRATE` permission. This can be done by adding `<uses-permission android:name="android.permission.VIBRATE"/>` in the `AndroidManifest.xml`. 12262 12263On iOS devices, vibration functionality is achieved using the `AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)` method. 12264 12265*** 12266 12267### Reference 12268 12269#### Methods 12270 12271##### `cancel()` 12272 12273```typescript 12274static cancel(): void; 12275``` 12276 12277This method stops any ongoing vibrations that were initiated with a repeating pattern by calling `vibrate()`. 12278 12279*** 12280 12281##### `vibrate()` 12282 12283```typescript 12284static vibrate( 12285 pattern?: number | number[], 12286 repeat?: boolean 12287): void; 12288``` 12289 12290Initiates a vibration for a specified duration. By default, the vibration lasts for 400 milliseconds on Android. On iOS, this duration is fixed at approximately 400 milliseconds. 12291 12292The `vibrate()` method can accept a `pattern` argument, which is an array of numbers representing time in milliseconds. If `repeat` is set to true, the vibration pattern will continue looping until `cancel()` is invoked. 12293 12294- **On Android:** The odd indices in the `pattern` array specify the duration of each vibration, while even indices indicate the pause between vibrations. 12295- **On iOS:** All numbers in the `pattern` array represent the pause durations since the vibration length remains constant. 12296 12297**Parameters:** 12298 12299|Name|Type|Default|Description| 12300|-|-|-|-| 12301|pattern|number \| number\[]|`400`|Specifies either a single duration for vibration in milliseconds or an array of times.| 12302|repeat|boolean|`false`|If true, the vibration pattern will continue until `cancel()` is called.| 12303 12304## Animated.ValueXY 12305 12306A 2D value designed for driving 2D animations such as pan gestures. It shares a similar API with the standard `Animated.Value`, but it is multiplexed, containing two regular `Animated.Value` instances internally. 12307 12308### Example 12309 12310*Example content not provided.* 12311 12312### Reference 12313 12314#### Methods 12315 12316##### `setValue()` 12317 12318```typescript 12319setValue(value: { x: number; y: number }): void; 12320``` 12321 12322Directly sets the value. This action stops any ongoing animations and updates all bound properties. 12323 12324**Parameters:** 12325 12326- **value**: `{x: number; y: number}` (Required)\ 12327 The new value to set, consisting of `x` and `y` coordinates. 12328 12329##### `setOffset()` 12330 12331```typescript 12332setOffset(offset: { x: number; y: number }): void; 12333``` 12334 12335Applies an offset on top of the current value. This can be useful for compensating initial positions in gestures like panning. 12336 12337**Parameters:** 12338 12339- **offset**: `{x: number; y: number}` (Required)\ 12340 The offset to apply, consisting of `x` and `y` coordinates. 12341 12342##### `flattenOffset()` 12343 12344```typescript 12345flattenOffset(): void; 12346``` 12347 12348Merges the current offset into the base value and resets the offset to zero. The final output remains unchanged. 12349 12350##### `extractOffset()` 12351 12352```typescript 12353extractOffset(): void; 12354``` 12355 12356Transfers the current offset value to the base value, resetting the base value to zero. The final output remains unchanged. 12357 12358##### `addListener()` 12359 12360```typescript 12361addListener(callback: (value: { x: number; y: number }) => void): string; 12362``` 12363 12364Adds an asynchronous listener to observe updates from animations. This is useful as there's no way to synchronously read the value due to potential native driving. 12365 12366**Returns:**\ 12367A string identifier for the listener. 12368 12369**Parameters:** 12370 12371- **callback**: `function` (Required)\ 12372 A function that receives an object with a `value` key set to the new value. 12373 12374##### `removeListener()` 12375 12376```typescript 12377removeListener(id: string): void; 12378``` 12379 12380Unregisters a listener using the identifier returned by `addListener()`. 12381 12382**Parameters:** 12383 12384- **id**: `string` (Required)\ 12385 The identifier of the listener being removed. 12386 12387##### `removeAllListeners()` 12388 12389```typescript 12390removeAllListeners(): void; 12391``` 12392 12393Removes all registered listeners. 12394 12395##### `stopAnimation()` 12396 12397```typescript 12398stopAnimation(callback?: (value: { x: number; y: number }) => void): void; 12399``` 12400 12401Stops any running animation or tracking. The optional `callback` is invoked with the final value, useful for updating state to match the animation position. 12402 12403**Parameters:** 12404 12405- **callback**: `function` (Optional)\ 12406 A function that receives the final value after stopping the animation. 12407 12408##### `resetAnimation()` 12409 12410```typescript 12411resetAnimation(callback?: (value: { x: number; y: number }) => void): void; 12412``` 12413 12414Stops any running animation and resets the value to its original state. The optional `callback` is invoked with the original value. 12415 12416**Parameters:** 12417 12418- **callback**: `function` (Optional)\ 12419 A function that receives the original value after resetting the animation. 12420 12421##### `getLayout()` 12422 12423```typescript 12424getLayout(): { left: Animated.Value; top: Animated.Value }; 12425``` 12426 12427Converts `{x, y}` into `{left, top}` for use in style properties. For example: 12428 12429```typescript 12430style={this.state.anim.getLayout()} 12431``` 12432 12433##### `getTranslateTransform()` 12434 12435```typescript 12436getTranslateTransform(): [{ translateX: Animated.Value }, { translateY: Animated.Value }]; 12437``` 12438 12439Converts `{x, y}` into a usable translation transform. For example: 12440 12441```typescript 12442style={{ 12443 transform: this.state.anim.getTranslateTransform() 12444}} 12445``` 12446 12447## useColorScheme Hook 12448 12449The `useColorScheme` hook from 'react-native' is designed to provide and subscribe to updates regarding color schemes via the `Appearance` module. It returns the current user's preferred color scheme, which can change based on direct actions like theme selection in device settings or automatically according to a schedule (e.g., switching between light and dark themes with day/night cycles). 12450 12451### Supported Color Schemes 12452 12453- `"light"`: Indicates that the user prefers a light color theme. 12454- `"dark"`: Indicates that the user prefers a dark color theme. 12455- `null`: No preferred color scheme has been indicated by the user. 12456 12457### Example Usage 12458 12459A comprehensive example demonstrating how to use this hook, along with React context for supporting both light and dark themes in an application, can be found in `AppearanceExample.js`. 12460 12461## useWindowDimensions 12462 12463```typescript 12464import { useWindowDimensions } from "react-native" 12465``` 12466 12467`useWindowDimensions` is a hook that automatically updates its values when there are changes in screen size or font scale. It provides the current window's width and height, which can be accessed as follows: 12468 12469```typescript 12470const { height, width } = useWindowDimensions() 12471``` 12472 12473### Example 12474 12475### Properties 12476 12477#### `fontScale` 12478 12479```typescript 12480useWindowDimensions().fontScale 12481``` 12482 12483This property indicates the current font size scale. Some operating systems allow users to adjust their font sizes for better readability. This value reflects any such adjustments. 12484 12485*** 12486 12487#### `height` 12488 12489```typescript 12490useWindowDimensions().height 12491``` 12492 12493Represents the height in pixels of the window or screen that your application occupies. 12494 12495*** 12496 12497#### `scale` 12498 12499```typescript 12500useWindowDimensions().scale 12501``` 12502 12503This property provides the pixel ratio of the device. Possible values include: 12504 12505- `1`: One point equals one pixel (commonly PPI/DPI of 96, 76 on some platforms). 12506- `2` or `3`: Indicates a Retina or high DPI display. 12507 12508*** 12509 12510#### `width` 12511 12512```typescript 12513useWindowDimensions().width 12514``` 12515 12516Indicates the width in pixels of the window or screen that your application occupies. 12517 12518## Keyboard 12519 12520The `Keyboard` module provides functionality for controlling and responding to keyboard events in your application. It allows you to listen for native keyboard notifications, dismiss the keyboard, and synchronize layout animations with keyboard movements. 12521 12522### Usage 12523 12524- **Listening for Events**: Use the `addListener()` method to connect a JavaScript function to specific native keyboard notification events. 12525- **Dismissing Keyboard**: The `dismiss()` method can be used to hide the active keyboard and remove focus from input elements. 12526- **Synchronizing Layouts**: Utilize `scheduleLayoutAnimation` to align layout changes with keyboard movements, particularly useful for adjusting text inputs or accessory views. 12527- **Checking Visibility**: Use `isVisible()` to determine if the keyboard is currently visible. 12528- **Retrieving Metrics**: The `metrics()` method provides details about the soft-keyboard's size and position when it is visible. 12529 12530### Reference 12531 12532#### Methods 12533 12534##### `addListener()` 12535 12536```typescript 12537static addListener( 12538 eventType: KeyboardEventName, 12539 listener: KeyboardEventListener 12540): EmitterSubscription; 12541``` 12542 12543Connects a JavaScript function to a specified native keyboard notification event. Returns the reference to the listener. 12544 12545**Parameters:** 12546 12547|Name|Type|Description| 12548|-|-|-| 12549|`eventType`|string|Identifies the event you're listening for. See list below.| 12550|`listener`|function|The callback function executed when the event occurs.| 12551 12552**Supported Events:** 12553 12554- `keyboardWillShow` 12555- `keyboardDidShow` 12556- `keyboardWillHide` 12557- `keyboardDidHide` 12558- `keyboardWillChangeFrame` 12559- `keyboardDidChangeFrame` 12560 12561> **Note:** On Android, only `keyboardDidShow` and `keyboardDidHide` events are available. These events will not trigger on Android 10 or below if the activity's `android:windowSoftInputMode` is set to `adjustNothing`. 12562 12563##### `dismiss()` 12564 12565```typescript 12566static dismiss(); 12567``` 12568 12569Dismisses the active keyboard and removes focus from input elements. 12570 12571##### `scheduleLayoutAnimation` 12572 12573```typescript 12574static scheduleLayoutAnimation(event: KeyboardEvent); 12575``` 12576 12577Synchronizes layout changes with keyboard movements, useful for adjusting text inputs or other accessory views. 12578 12579##### `isVisible()` 12580 12581```typescript 12582static isVisible(): boolean; 12583``` 12584 12585Returns a boolean indicating whether the keyboard is currently visible. 12586 12587##### `metrics()` 12588 12589```typescript 12590static metrics(): KeyboardMetrics | undefined; 12591``` 12592 12593Provides the dimensions and position of the soft-keyboard if it is visible. Returns `undefined` if the keyboard is not visible. 12594 12595## PermissionsAndroid 12596 12597### Project with Native Code Required 12598 12599This section is applicable only for projects that include native code. If you are using the managed Expo workflow, refer to the Expo documentation's guide on Permissions for alternatives. 12600 12601`PermissionsAndroid` provides access to Android M's new permissions model. "Normal" permissions are granted by default upon application installation if they appear in `AndroidManifest.xml`. However, "dangerous" permissions require a dialog prompt. Use this module for those permissions. 12602 12603On devices with SDK versions below 23, permissions listed in the manifest are automatically granted. Thus, `check` will always return `true`, and `request` will resolve to `PermissionsAndroid.RESULTS.GRANTED`. 12604 12605If a user has previously denied a permission that you request, the OS advises your app to show a rationale for needing the permission. The optional `rationale` argument displays a dialog only if necessary; otherwise, the standard permission prompt appears. 12606 12607### Example 12608 12609#### Permissions Requiring User Prompt 12610 12611Available as constants under `PermissionsAndroid.PERMISSIONS`: 12612 12613- `READ_CALENDAR`: `'android.permission.READ_CALENDAR'` 12614- `WRITE_CALENDAR`: `'android.permission.WRITE_CALENDAR'` 12615- `CAMERA`: `'android.permission.CAMERA'` 12616- `READ_CONTACTS`: `'android.permission.READ_CONTACTS'` 12617- `WRITE_CONTACTS`: `'android.permission.WRITE_CONTACTS'` 12618- `GET_ACCOUNTS`: `'android.permission.GET_ACCOUNTS'` 12619- `ACCESS_FINE_LOCATION`: `'android.permission.ACCESS_FINE_LOCATION'` 12620- `ACCESS_COARSE_LOCATION`: `'android.permission.ACCESS_COARSE_LOCATION'` 12621- `ACCESS_BACKGROUND_LOCATION`: `'android.permission.ACCESS_BACKGROUND_LOCATION'` 12622- `RECORD_AUDIO`: `'android.permission.RECORD_AUDIO'` 12623- `READ_PHONE_STATE`: `'android.permission.READ_PHONE_STATE'` 12624- `CALL_PHONE`: `'android.permission.CALL_PHONE'` 12625- `READ_CALL_LOG`: `'android.permission.READ_CALL_LOG'` 12626- `WRITE_CALL_LOG`: `'android.permission.WRITE_CALL_LOG'` 12627- `ADD_VOICEMAIL`: `'com.android.voicemail.permission.ADD_VOICEMAIL'` 12628- `USE_SIP`: `'android.permission.USE_SIP'` 12629- `PROCESS_OUTGOING_CALLS`: `'android.permission.PROCESS_OUTGOING_CALLS'` 12630- `BODY_SENSORS`: `'android.permission.BODY_SENSORS'` 12631- `SEND_SMS`: `'android.permission.SEND_SMS'` 12632- `RECEIVE_SMS`: `'android.permission.RECEIVE_SMS'` 12633- `READ_SMS`: `'android.permission.READ_SMS'` 12634- `RECEIVE_WAP_PUSH`: `'android.permission.RECEIVE_WAP_PUSH'` 12635- `RECEIVE_MMS`: `'android.permission.RECEIVE_MMS'` 12636- `READ_EXTERNAL_STORAGE`: `'android.permission.READ_EXTERNAL_STORAGE'` 12637- `WRITE_EXTERNAL_STORAGE`: `'android.permission.WRITE_EXTERNAL_STORAGE'` 12638- `BLUETOOTH_CONNECT`: `'android.permission.BLUETOOTH_CONNECT'` 12639- `BLUETOOTH_SCAN`: `'android.permission.BLUETOOTH_SCAN'` 12640- `BLUETOOTH_ADVERTISE`: `'android.permission.BLUETOOTH_ADVERTISE'` 12641- `ACCESS_MEDIA_LOCATION`: `'android.permission.ACCESS_MEDIA_LOCATION'` 12642- `ACCEPT_HANDOVER`: `'android.permission.ACCEPT_HANDOVER'` 12643- `ACTIVITY_RECOGNITION`: `'android.permission.ACTIVITY_RECOGNITION'` 12644- `ANSWER_PHONE_CALLS`: `'android.permission.ANSWER_PHONE_CALLS'` 12645- `READ_PHONE_NUMBERS`: `'android.permission.READ_PHONE_NUMBERS'` 12646- `UWB_RANGING`: `'android.permission.UWB_RANGING'` 12647- `BODY_SENSORS_BACKGROUND`: `'android.permission.BODY_SENSORS_BACKGROUND'` 12648- `READ_MEDIA_IMAGES`: `'android.permission.READ_MEDIA_IMAGES'` 12649- `READ_MEDIA_VIDEO`: `'android.permission.READ_MEDIA_VIDEO'` 12650- `READ_MEDIA_AUDIO`: `'android.permission.READ_MEDIA_AUDIO'` 12651- `POST_NOTIFICATIONS`: `'android.permission.POST_NOTIFICATIONS'` 12652- `NEARBY_WIFI_DEVICES`: `'android.permission.NEARBY_WIFI_DEVICES'` 12653- `READ_VOICEMAIL`: `'com.android.voicemail.permission.READ_VOICEMAIL'` 12654- `WRITE_VOICEMAIL`: `'com.android.voicemail.permission.WRITE_VOICEMAIL'` 12655 12656#### Result Strings for Requesting Permissions 12657 12658Available as constants under `PermissionsAndroid.RESULTS`: 12659 12660- `GRANTED`: `'granted'` 12661- `DENIED`: `'denied'` 12662- `NEVER_ASK_AGAIN`: `'never_ask_again'` 12663 12664### Reference 12665 12666#### Methods 12667 12668##### `check()` 12669 12670```typescript 12671static check(permission: string): Promise<boolean>; 12672``` 12673 12674Returns a promise resolving to a boolean indicating whether the specified permission has been granted. 12675 12676**Parameters:** 12677 12678|Name|Type|Required|Description| 12679|-|-|-|-| 12680|permission|string|Yes|The permission to check for.| 12681 12682##### `request()` 12683 12684```typescript 12685static request( 12686 permission: string, 12687 rationale?: { 12688 title: string; 12689 message: string; 12690 buttonPositive: string; 12691 buttonNegative?: string; 12692 buttonNeutral?: string; 12693 } 12694): Promise<string>; 12695``` 12696 12697Prompts the user to enable a permission and returns a promise resolving to a string indicating whether the user allowed or denied the request, or does not want to be asked again. 12698 12699If `rationale` is provided, this function checks with the OS whether it is necessary to show a dialog explaining why the permission is needed (<https://developer.android.com/training/permissions/requesting.html#explain>) and then shows the system permission dialog. 12700 12701**Parameters:** 12702 12703|Name|Type|Required|Description| 12704|-|-|-|-| 12705|permission|string|Yes|The permission to request.| 12706|rationale|object|No|See `rationale` below.| 12707 12708**Rationale:** 12709 12710|Name|Type|Required|Description| 12711|-|-|-|-| 12712|title|string|Yes|The title of the dialog.| 12713|message|string|Yes|The message of the dialog.| 12714|buttonPositive|string|Yes|The text of the positive button.| 12715|buttonNegative|string|No|The text of the negative button.| 12716|buttonNeutral|string|No|The text of the neutral button.| 12717 12718##### `requestMultiple()` 12719 12720```typescript 12721static requestMultiple( 12722 permissions: string[] 12723): Promise<{ [key in string]: string }>; 12724``` 12725 12726Prompts the user to enable multiple permissions in the same dialog and returns an object with the permissions as keys and strings as values indicating whether the user allowed or denied the request, or does not want to be asked again. 12727 12728**Parameters:** 12729 12730|Name|Type|Required|Description| 12731|-|-|-|-| 12732|permissions|array|Yes|Array of permissions to request.| 12733 12734## Signing Your Android Application for Distribution 12735 12736Android mandates that applications must be digitally signed with a certificate before installation. For distribution via the Google Play Store, an app needs to be signed with a release key used for all future updates. Since 2017, Google Play can manage signing releases automatically through App Signing by Google Play. However, prior to uploading your application binary to Google Play, it must be signed with an upload key. 12737 12738### Generating an Upload Key 12739 12740#### Windows 12741 12742On Windows, `keytool` should be executed from `C:\Program Files\Java\jdkx.x.x_x\bin` as administrator: 12743 12744```shell 12745keytool -genkeypair -v -storetype PKCS12 -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 12746``` 12747 12748This command prompts for passwords and Distinguished Name fields, generating a keystore file named `my-upload-key.keystore`. The key is valid for 10,000 days. Remember the alias used. 12749 12750#### macOS 12751 12752On macOS, locate your JDK bin folder using: 12753 12754```shell 12755/usr/libexec/java_home 12756``` 12757 12758Navigate to that directory with `cd /your/jdk/path` and run: 12759 12760```shell 12761sudo keytool -genkey -v -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 12762``` 12763 12764**Caution:** Keep the keystore file private. If lost or compromised, follow recovery instructions. 12765 12766### Setting Up Gradle Variables 12767 127681. Place `my-upload-key.keystore` in the `android/app` directory. 127691. Edit `~/.gradle/gradle.properties` or `android/gradle.properties`, adding: 12770 12771```properties 12772MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore 12773MYAPP_UPLOAD_KEY_ALIAS=my-key-alias 12774MYAPP_UPLOAD_STORE_PASSWORD=***** 12775MYAPP_UPLOAD_KEY_PASSWORD=***** 12776``` 12777 12778These are global Gradle variables for signing the app. Use `~/.gradle/gradle.properties` to avoid checking them into git. 12779 12780### Adding Signing Config to Your App's Gradle Config 12781 12782Edit `android/app/build.gradle` and add: 12783 12784```groovy 12785... 12786android { 12787 ... 12788 defaultConfig { ... } 12789 signingConfigs { 12790 release { 12791 if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { 12792 storeFile file(MYAPP_UPLOAD_STORE_FILE) 12793 storePassword MYAPP_UPLOAD_STORE_PASSWORD 12794 keyAlias MYAPP_UPLOAD_KEY_ALIAS 12795 keyPassword MYAPP_UPLOAD_KEY_PASSWORD 12796 } 12797 } 12798 } 12799 buildTypes { 12800 release { 12801 ... 12802 signingConfig signingConfigs.release 12803 } 12804 } 12805} 12806... 12807``` 12808 12809### Generating the Release AAB 12810 12811Run: 12812 12813```shell 12814npx react-native build-android --mode=release 12815``` 12816 12817This bundles JavaScript into an Android App Bundle (AAB). Ensure `gradle.properties` does not include `org.gradle.configureondemand=true`. 12818 12819The generated AAB is located at `android/app/build/outputs/bundle/release/app-release.aab`, ready for Google Play upload. Configure App Signing by Google Play on the Google Play Console. 12820 12821### Testing the Release Build 12822 12823Uninstall any previous app versions and install using: 12824 12825```shell 12826npm run android -- --mode="release" 12827``` 12828 12829or 12830 12831```shell 12832yarn android --mode release 12833``` 12834 12835Ensure signing is set up as described above. Terminate running bundler instances since all code is bundled in the APK's assets. 12836 12837### Publishing to Other Stores 12838 12839The default APK includes native code for `x86`, `x86_64`, `ARMv7a`, and `ARM64-v8a`. For smaller APKs, create separate APKs per CPU: 12840 12841```groovy 12842android { 12843 splits { 12844 abi { 12845 reset() 12846 enable true 12847 universalApk false 12848 include "armeabi-v7a", "arm64-v8a", "x86", "x86_64" 12849 } 12850 } 12851} 12852``` 12853 12854Upload to markets supporting device targeting. For others, set `universalApk true` for a universal APK. 12855 12856### Enabling Proguard (Optional) 12857 12858Proguard reduces APK size by stripping unused React Native Java bytecode: 12859 12860```groovy 12861/** 12862 * Run Proguard to shrink the Java bytecode in release builds. 12863 */ 12864def enableProguardInReleaseBuilds = true 12865``` 12866 12867Test thoroughly if enabled, as it may require specific configurations for native libraries. 12868 12869### Migrating Old Android React Native Apps 12870 12871For apps not using App Signing by Google Play, generate a new upload key and update `android/app/build.gradle` to use this key. Follow Google Play Help instructions to send your original release key to Google Play. 12872 12873### Default Permissions 12874 12875The `INTERNET` permission is added by default. The `SYSTEM_ALERT_WINDOW` permission is included in debug mode but removed in production.