this repo has no description
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.