# React Native
> 
---
# Source: https://reactnative.dev/blog/2023/06/21/0.72-metro-package-exports-symlinks.md
# React Native 0.72 - Symlink Support, Better Errors, and more
June 21, 2023 ·
8 min read

Lorenzo Sciandra
Senior Software Engineer @ Microsoft
[](https://x.com/kelset "X")[](https://github.com/kelset "GitHub")

Marek Fořt
Software Engineer @ Shopify
[](https://x.com/marekfort "X")[](https://github.com/fortmarek "GitHub")

Riccardo Cipolleschi
Software Engineer @ Meta
[](https://x.com/CipolleschiR "X")[](https://github.com/cipolleschi "GitHub")

Luna Wei
Software Engineer @ Meta
[](https://x.com/lunaleaps "X")[](https://github.com/lunaleaps "GitHub")
Today we’re releasing 0.72!
This release adds highly requested features for Metro, better error handling, and other developer experience improvements. So much of this work was prioritized from your feedback on the [2022 community survey](https://github.com/react-native-community/discussions-and-proposals/discussions/528) -- thank you to all those that participated!
### Highlights[](#highlights "Direct link to Highlights")
* [New Metro Features](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#new-metro-features)
* [Developer Experience Improvements](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#developer-experience-improvements)
* [Moving New Architecture Updates](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#moving-new-architecture-updates)
### Breaking Changes[](#breaking-changes "Direct link to Breaking Changes")
* [Deprecated Component Removals](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#deprecated-component-removals)
* [Package Renames](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#package-renames)
## Highlights[](#highlights-1 "Direct link to Highlights")
### New Metro Features[](#new-metro-features "Direct link to New Metro Features")
#### Symlink Support (Beta)[](#symlink-support-beta "Direct link to Symlink Support (Beta)")
Symlink support continues to be one of the top-requested features in Metro and, in React Native 0.72, we are happy to announce beta support for it.
Symlink support enables React Native to work transparently with monorepo setups and pnpm, removing the need for workarounds. See [Enabling Beta Features](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#enabling-beta-features) to use in your app.
It is currently in beta to collect feedback on developer experience given varying workflows, see more details [here](https://twitter.com/robjhogan/status/1672293540632641554). We plan to default enable symlinks in 0.73.
#### Package Exports Support (Beta)[](#package-exports-support-beta "Direct link to Package Exports Support (Beta)")
[Package Exports](https://nodejs.org/api/packages.html#exports) is the modern alternative to the package.json `"main"` field and provides new capabilities for npm packages to define their public API and target React Native.
By enabling Package Exports support in your Metro config, your app will be compatible with the wider JavaScript ecosystem, including via the new ["react-native" community condition](https://nodejs.org/docs/latest-v19.x/api/packages.html#community-conditions-definitions). See [Enabling Beta Features](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#enabling-beta-features) to use in your app.
tip
See [Package Exports Support in React Native](/blog/2023/06/21/package-exports-support.md) to learn more about this feature and our plans for stable rollout.
#### Enabling Beta Features[](#enabling-beta-features "Direct link to Enabling Beta Features")
To enable these features in your project, update your app’s `metro.config.js` file and set either the `resolver.unstable_enableSymlinks` or `resolver.unstable_enablePackageExports` options.
```
const config = {
// ...
resolver: {
unstable_enableSymlinks: true,
unstable_enablePackageExports: true,
},
};
```
#### New `metro.config.js` Setup[](#new-metroconfigjs-setup "Direct link to new-metroconfigjs-setup")
In React Native 0.72, we’ve changed the config loading setup for Metro in React Native CLI. Please update your project’s `metro.config.js` file to match the [template’s version](https://github.com/facebook/react-native/blob/76a42c292de838a0dd537935db792eaa81410b9b/packages/react-native/template/metro.config.js).
info
Please update your config file to the following [format](https://github.com/facebook/react-native/blob/76a42c292de838a0dd537935db792eaa81410b9b/packages/react-native/template/metro.config.js). You can also follow the [upgrade-helper](https://react-native-community.github.io/upgrade-helper/?from=0.71.8\&to=0.72.0).
These format changes to `metro.config.js` will become required in 0.73. For 0.72, we will log a warning if not updated.
This moves control over extending the base React Native Metro config into your project, and we’ve cleaned up the leftover defaults. In addition, this means that standalone Metro CLI commands, such as `metro get-dependencies`, will now work.
### Developer Experience Improvements[](#developer-experience-improvements "Direct link to Developer Experience Improvements")
#### No more redboxes with invalid style properties[](#no-more-redboxes-with-invalid-style-properties "Direct link to No more redboxes with invalid style properties")
Prior to this release, providing an invalid style property in StyleSheet would result in a redbox. This is a high signal error that disrupts the developer workflow for a relatively low-risk error.
In 0.72, we’ve relaxed this expectation to fail silently, like providing an invalid CSS property in the browser, and have updated types such that some errors may be caught in build-time vs. run-time.
#### Better error readability for Hermes[](#better-error-readability-for-hermes "Direct link to Better error readability for Hermes")
Hermes has added a better error message when invoking an undefined callable.
```
var x = undefined; x();
// Before: undefined is not a function
// After: x is not a function (it is undefined)
```
In addition, LogBox stack traces now filter out internal Hermes bytecode frames that are not relevant to app users.
#### Improved error output of the React Native CLI[](#improved-error-output-of-the-react-native-cli "Direct link to Improved error output of the React Native CLI")
0.72 ships with React Native CLI v11 which includes improvements to reduce duplication, clarify wording, reduce verbose stack traces, and add deep links to relevant docs in the following commands `init`, `run-android`, and `run-ios`.
You can find other improvements in the [React Native CLI changelogs](https://github.com/react-native-community/cli/releases).
#### Faster Compilation and JSON Parsing in Hermes[](#faster-compilation-and-json-parsing-in-hermes "Direct link to Faster Compilation and JSON Parsing in Hermes")
Hermes has improved the compilation time of large object literals. For example, in one reported issue, [#852](https://github.com/facebook/hermes/issues/852), a user had an entire dataset written out as a large object literal. By improving the de-duplication algorithm Hermes uses, compilation sped up by 97% ([221c](https://github.com/facebook/hermes/commit/221ce21a209e2e32a3eaaa2d9e28ca81842fad20)). These improvements will benefit build times for apps that bundle many objects.
Multiple optimizations ([de9c](https://github.com/facebook/hermes/commit/de9cff2aa41fc1f297b568848143347823d73659), [6e2d](https://github.com/facebook/hermes/commit/6e2dd652c8d90c5d59737a81f66a259efffdcd00)) to JSON parsing have also landed, benefiting apps using libraries like redux-persist that rely heavily on JSON manipulation.
#### More ECMAScript Support in Hermes[](#more-ecmascript-support-in-hermes "Direct link to More ECMAScript Support in Hermes")
Support for the following specifications in Hermes has landed in React Native 0.72:
* `prototype.at` support for [Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at), [TypedArray](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/at) and [String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/at). See [#823](https://github.com/facebook/hermes/issues/823) ([ebe2](https://github.com/facebook/hermes/commit/ebe2915ac386a6b73dec39c2af4ac7063e68cd99)).
* Implement [well-formed JSON.stringify](https://github.com/tc39/proposal-well-formed-stringify) ([d41d](https://github.com/facebook/hermes/commit/d41decf244aa814b1e58827a9de982f3b71667de)) to prevent ill-formed Unicode strings
* Implement [AggregateError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) ([9b25](https://github.com/facebook/hermes/commit/9b25a2530eb515f6c4fbd397ae290b6c97c049b2)) that represents several errors wrapped in a single error. Useful for multiple errors like from [`Promise.any()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any) when all promises passed to it reject.
For users on JSC, these features are already available.
### Moving New Architecture Updates[](#moving-new-architecture-updates "Direct link to Moving New Architecture Updates")
The New Architecture is currently experimental. To keep updates focused to their target audience, we are moving New Architecture updates in 0.72, and future releases, to the dedicated [working group](https://github.com/reactwg/react-native-new-architecture/discussions). This change will also allow for more frequent updates, such as work that ships in our nightlies.
You can read the 0.72 updates for the New Architecture [here](https://github.com/reactwg/react-native-new-architecture/discussions/136). Subscribe to the working group GitHub notifications to stay informed on our progress on the New Architecture.
## Breaking Changes[](#breaking-changes-1 "Direct link to Breaking Changes")
### Deprecated Component Removals[](#deprecated-component-removals "Direct link to Deprecated Component Removals")
The following packages have been removed from React Native in 0.72. Please migrate to the recommended community package:
* [Slider](https://reactnative.dev/docs/0.72/slider) is superseded by [@react-native-community/slider](https://github.com/callstack/react-native-slider/tree/main/package)
* [DatePickerIOS](https://reactnative.dev/docs/0.72/datepickerios) is superseded by [@react-native-community/datetimepicker](https://github.com/react-native-datetimepicker/datetimepicker)
* [ProgressViewIOS](https://reactnative.dev/docs/0.72/progressviewios) is superseded by [@react-native-community/progress-view](https://github.com/react-native-progress-view/progress-view)
### Package Renames[](#package-renames "Direct link to Package Renames")
All packages published from the [`react-native`](https://github.com/facebook/react-native) core repository now live under `react-native/packages`, and are published under the [@react-native npm scope](https://www.npmjs.com/search?q=%40react-native) to ensure clear ownership.
There are no changes to the [react-native](https://www.npmjs.com/package/react-native) package.
| Old Package Name | New Package Name |
| --------------------------------------- | -------------------------------- |
| `@react-native-community/eslint-config` | `@react-native/eslint-config` |
| `@react-native-community/eslint-plugin` | `@react-native/eslint-plugin` |
| `@react-native/polyfills` | `@react-native/js-polyfills` |
| `@react-native/normalize-color` | `@react-native/normalize-colors` |
| `@react-native/assets` | `@react-native/assets-registry` |
| `react-native-codegen` | `@react-native/codegen` |
| `react-native-gradle-plugin` | `@react-native/gradle-plugin` |
This change will not affect you if you have no direct dependency on a renamed package. Otherwise, when upgrading to React Native 0.72, update any renamed dependency to its \~0.72 version.
You can read the motivation that led to these changes [in the dedicated RFC](https://github.com/react-native-community/discussions-and-proposals/pull/480).
## Acknowledgements[](#acknowledgements "Direct link to Acknowledgements")
A lot of this release came from the direct feedback from the community. From reports on [noisy redboxes](https://twitter.com/baconbrix/status/1623039650775371792), [bugs with Package Exports](https://github.com/facebook/metro/issues/965), [benchmarks for the New Architecture](https://github.com/reactwg/react-native-new-architecture/discussions/85) — all of it is valuable to hear and we appreciate the time it takes to share feedback.
0.72 contains over [1100 commits](https://github.com/facebook/react-native/compare/v0.71.8...v0.72.0) from 66 contributors. Thank you for all your hard work!
## Upgrade to 0.72[](#upgrade-to-072 "Direct link to Upgrade to 0.72")
Check out the list of needed changes in the [upgrade-helper](https://react-native-community.github.io/upgrade-helper/), or read the [upgrade documentation](/docs/upgrading.md) for how to update your existing project, or create a new project with `npx react-native@latest init MyProject`.
If you use Expo, React Native version 0.72 will be supported in the Expo SDK 49 release.
info
0.72 is now the latest stable version of React Native and 0.69.x version moves now to unsupported. For more information see [React Native’s support policy](https://github.com/reactwg/react-native-releases#releases-support-policy).
**Tags:**
* [announcement](/blog/tags/announcement)
* [release](/blog/tags/release)
---
# Source: https://reactnative.dev/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md
# React Native 0.73 - Debugging Improvements, Stable Symlink Support, and more
December 6, 2023 ·
13 min read

Marek Fořt
Software Engineer @ Shopify
[](https://x.com/marekfort "X")[](https://github.com/fortmarek "GitHub")

Thibault Malbranche
Lead Mobile Engineer @ Brigad
[](https://x.com/titozzz "X")[](https://github.com/titozzz "GitHub")

Hur Ali
Software Engineer @ Callstack
[](https://x.com/hurali97 "X")[](https://github.com/hurali97 "GitHub")

Luna Wei
Software Engineer @ Meta
[](https://x.com/lunaleaps "X")[](https://github.com/lunaleaps "GitHub")

Alex Hunt
Software Engineer @ Meta
[](https://x.com/huntie "X")[](https://github.com/huntie "GitHub")
Today we're releasing React Native 0.73! This release adds improvements to debugging with Hermes, stable symlink support, Android 14 support, and new experimental features. We are also deprecating legacy debugging features, and are releasing the next pillar of the New Architecture: Bridgeless Mode!
### Highlights[](#highlights "Direct link to Highlights")
* [Debugging Improvements](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#debugging-improvements)
* [Stable Symlink Support in Metro](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#stable-symlink-support-in-metro)
* [Kotlin Template on Android](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#kotlin-template-on-android)
* [Android 14 Support](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#android-14-support)
* [New Architecture Updates](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#new-architecture-updates)
* [Deprecated Debugging Features](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#deprecated-debugging-features)
### Breaking Changes[](#breaking-changes "Direct link to Breaking Changes")
* [Babel Package Renames](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#babel-package-renames)
* [Other Breaking Changes](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#other-breaking-changes)
* [React Native CLI Changes](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#react-native-cli-changes)
* [Deprecated @types/react-native](/blog/2023/12/06/0.73-debugging-improvements-stable-symlinks.md#deprecated-typesreact-native)
## Highlights[](#highlights-1 "Direct link to Highlights")
### Debugging Improvements[](#debugging-improvements "Direct link to Debugging Improvements")
The React Native and Hermes teams are committed to improving the debugging experience in React Native. In 0.73, we're happy to share some initial progress out of this ongoing investment.
#### Console Log History in Hermes[](#console-log-history-in-hermes "Direct link to Console Log History in Hermes")
`console.log()` is an ever popular way for developers to quickly debug their JavaScript code. In previous releases, console logs in React Native apps would not be recorded until a debugger was connected. This made it hard to observe logs that occur early during app load.
In React Native 0.73 we've addressed this issue. Hermes now captures all `console.log()` calls in the background, which will be sent to the Console tab when a debugger is first connected — matching the debugging experience in web browsers. This new behaviour works across Flipper, Chrome DevTools connected to Hermes, and the experimental New Debugger.
#### Updated Debugging Docs[](#updated-debugging-docs "Direct link to Updated Debugging Docs")
We've refreshed the [Debugging](/docs/debugging.md) section of our docs, which now includes up-to-date information on how to connect all supported debuggers, more info on React DevTools, and refreshed visuals.

#### Experimental New Debugger[](#experimental-new-debugger "Direct link to Experimental New Debugger")
The React Native team is working on a new JavaScript debugger experience, intended to replace Flipper, with a Technical Preview available as of React Native 0.73. The new debugger opens immediately, and features a stripped-back Chrome DevTools UI customized for debugging React Native with Hermes.
note
The new debugger is **experimental** and has some [known issues](https://github.com/react-native-community/discussions-and-proposals/discussions/733) we are actively working to solve in a future release of React Native. If you are trying it out, please use the [same discussion thread](https://github.com/react-native-community/discussions-and-proposals/discussions/733) to report feedback.

Learn more about enabling this experience [in the docs](/docs/next/debugging?js-debugger=new-debugger#opening-the-debugger).
### Stable Symlink Support in Metro[](#stable-symlink-support-in-metro "Direct link to Stable Symlink Support in Metro")
Support for resolving symlinks in Metro is now **enabled by default**. Symlink support enables React Native to work with monorepo setups when containing directories are configured with [`watchFolders`](https://metrobundler.dev/docs/configuration/#watchfolders).
Symlinks are deeply represented in Metro's internals, meaning they work with features such as [Fast Refresh](/docs/fast-refresh.md), and incur little performance overhead during bundling. Symlinks are supported on all desktop platforms, with and without Watchman.
info
#### Monorepo workarounds[](#monorepo-workarounds "Direct link to Monorepo workarounds")
We are aware there are still edge cases when using React Native in a monorepo layout. We have planned work to address some of these, which didn't quite make it into 0.73 — but which we aim to ship as soon as possible.
**For React Native template projects (`npx react-native init`)**, you will need to configure any [`watchFolders`](https://metrobundler.dev/docs/configuration/#watchfolders) outside of the project root in order for Metro to discover them ([more info](https://metrobundler.dev/docs/configuration/#unstable_enablesymlinks-experimental)). You may also need to update file paths if your `react-native` dependency is installed to a folder at a different level.
**For Expo apps**, support for Yarn (Classic) workspaces is configured out of the box. See also the [Work with monorepos](https://docs.expo.dev/guides/monorepos/) guide in the Expo docs.
### Kotlin Template on Android[](#kotlin-template-on-android "Direct link to Kotlin Template on Android")
We're excited to announce that, starting from 0.73, Kotlin is now the **recommended language** for Android apps built with React Native. This follows the direction that the Android ecosystem has been moving in for several years and allows you to write your app using a modern language.
We've updated React Native's template on Android to use Kotlin instead of Java. The new `MainActivity.kt` and `MainApplication.kt` files are 36% smaller in size.
The [Upgrade Helper](https://react-native-community.github.io/upgrade-helper/) has also been updated to make it easier to migrate your `.java` files to `.kt` files. If you've previously modified the Java files in your project and you need support migrating them to Kotlin, you can use the `Code > Convert Java file to Kotlin File` utility of Android Studio (also accessible with the shortcut `Cmd ⌘` + `Shift ⇧` + `Option ⌥` + `K`).
### Android 14 Support[](#android-14-support "Direct link to Android 14 Support")
We've updated React Native to fully support Android 14. Starting from 0.73, React Native developers can now target the latest Android SDK version, [API Level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element?hl=en#ApiLevels) (*Upside Down Cake*).
#### Java 17 and Android Gradle Plugin upgrade[](#java-17-and-android-gradle-plugin-upgrade "Direct link to Java 17 and Android Gradle Plugin upgrade")
In order to support Android 14, we've updated the version of Android Gradle Plugin (AGP) used to build Android apps from `7.4.x` to `8.1.x`.
This major version bump of AGP comes with a series of breaking changes that are available in the release notes from Google ([8.0.0](https://developer.android.com/build/releases/past-releases/agp-8-0-0-release-notes) and [8.1.0](https://developer.android.com/build/releases/past-releases/agp-8-1-0-release-notes)).
Most importantly, **Java 17** is now a requirement to build Android apps. You can update your Java version to 17 by running:
```
brew install --cask zulu@17
```
and by updating your `JAVA_HOME` as documented in the [Getting Started guide](https://reactnative.dev/docs/environment-setup).
If you're a library developer, your libraries should work with React Native 0.73 without changes. Earlier this year, [we published a note](https://github.com/react-native-community/discussions-and-proposals/issues/671) with a clarification on what the AGP bump means for you as a library author.
#### Grant partial access to photos and videos[](#grant-partial-access-to-photos-and-videos "Direct link to Grant partial access to photos and videos")
[Selected Photos Access](https://developer.android.com/about/versions/14/changes/partial-photo-video-access) allows Android 14 users to grant apps access to specific items in their media library, rather than access to all media. In 0.73, React Native apps now support this capability, by using the `READ_MEDIA_VISUAL_USER_SELECTED` permission in the [`PermissionsAndroid`](/docs/permissionsandroid.md) API.

#### Min SDK bump[](#min-sdk-bump "Direct link to Min SDK bump")
React Native 0.73 will be the final version which supports Android 5.0 (API Level 21). The next version of React Native will have a minimum SDK version of 23 (Android 6.0). Read more about the upcoming changes to min SDK bump [here](https://github.com/react-native-community/discussions-and-proposals/discussions/740).
### New Architecture Updates[](#new-architecture-updates "Direct link to New Architecture Updates")
We continue the rollout of React Native's New Architecture, to make it available to everyone in the Open Source community.
Since React Native 0.68, both the New Renderer (Fabric) and the New Native Module System (TurboModules) were available to users to experiment and evaluate. We want to thank the community for the feedback we've received so far.
Today we're releasing another piece of the New Architecture: [**Bridgeless Mode**](https://github.com/reactwg/react-native-new-architecture/discussions/154). Up until now, when you enable the New Architecture in your app, the Bridge would still be available to support backward compatibility with older components and modules. However, our vision is to fully sunset the bridge. Starting from React Native 0.73, you can enable Bridgeless Mode which will disable the creation of the bridge entirely.
Together with Bridgeless Mode, we're shipping a Native Module Interop Layer, that will allow you to reuse your old modules when in Bridgeless Mode. The [Renderer Interop Layer](https://github.com/reactwg/react-native-new-architecture/discussions/135) introduced in React Native 0.72 has also been adapted to work with Bridgeless Mode.
As with the rest of the New Architecture, Bridgeless Mode is initially experimental. We invite interested users to enable it and report any problems and incompatibilities you face in the [New Architecture working group](https://github.com/reactwg/react-native-new-architecture/discussions).
### Deprecated Debugging Features[](#deprecated-debugging-features "Direct link to Deprecated Debugging Features")
#### Flipper ↔ React Native integration[](#flipper--react-native-integration "Direct link to Flipper ↔ React Native integration")
We are gradually moving away from Flipper as the default tool for debugging React Native apps. In 0.73, this begins by deprecating the native Flipper integration included with React Native (bootstrap code which wires up Flipper's core plugins). We will be removing this integration and dependency in the next release — meaning parts of Flipper such as the Network plugin will cease to work.
**Unchanged**: Flipper as a standalone product for native app debugging will continue to exist. Even after its removal from new React Native projects in the future, developers will be able to [manually add Flipper to their app](https://fbflipper.com/docs/getting-started/android-native/) if they wish.
For more information on why we are moving away from Flipper, [view the RFC](https://github.com/react-native-community/discussions-and-proposals/blob/main/proposals/0641-decoupling-flipper-from-react-native-core.md).
#### Remote JavaScript Debugging[](#remote-javascript-debugging "Direct link to Remote JavaScript Debugging")
Remote JavaScript Debugging is a legacy debugging mode that connects an external web browser (Chrome) to your app and runs your JavaScript code inside a web page, i.e. `http://localhost:8081/debugger-ui`. This model could lead to inconsistent app behaviour while debugging, and is incompatible with native modules under the New Architecture.
In 0.73, [Remote JavaScript Debugging is deprecated](https://github.com/react-native-community/discussions-and-proposals/discussions/734) and has been removed from the Dev Menu. Enabling the remote debugger must now be done manually via the `NativeDevSettings` API. Doing this is covered in the [Other Debugging Methods docs](/docs/next/other-debugging-methods#remote-js-debugging).
info
Remote JavaScript Debugging was previously the default debugging experience for apps using JavaScriptCore (JSC). We recommend [Safari Developer Tools (direct JSC debugging)](/docs/next/other-debugging-methods#safari-developer-tools-direct-jsc-debugging) instead, for iOS apps.
We recommend using [Hermes](/docs/hermes.md) for a consistent debugging experience on all platforms.
## Breaking Changes[](#breaking-changes-1 "Direct link to Breaking Changes")
### Babel Package Renames[](#babel-package-renames "Direct link to Babel Package Renames")
We've relocated two Babel-related packages out of Metro and into React Native's repository and versioning scheme, enabling us to simplify maintenance and upgrades. The new versions of these packages support New Architecture features in 0.73, meaning these dependencies must be updated.
Please follow the [Upgrade Helper](https://react-native-community.github.io/upgrade-helper/) when upgrading, to ensure you have updated these dependencies. Some packages have been renamed:
| Old Package Name | New Package Name |
| -------------------------------------- | --------------------------------------- |
| `metro-react-native-babel-preset` | `@react-native/babel-preset` |
| `metro-react-native-babel-transformer` | `@react-native/metro-babel-transformer` |
info
`@react-native/babel-preset` now includes `@react-native/babel-plugin-codegen`, this no longer needs to be specified separately in your Babel config file.
### Other Breaking Changes[](#other-breaking-changes "Direct link to Other Breaking Changes")
These are some of the key breaking changes in 0.73. Please consult the [full changelog](https://github.com/facebook/react-native/blob/main/CHANGELOG.md) for the complete list of breaking changes.
* Raise minimum Node.js requirement to 18.x ([#37709](https://github.com/facebook/react-native/pull/37709)) (see also [Node.js 16 EOL](https://nodejs.org/en/blog/announcements/nodejs16-eol)).
* The template now uses TypeScript 5.0 ([#36862](https://github.com/facebook/react-native/pull/36862)).
* React Native types continue working on TypeScript 4.8.
* **Android**: Java 17 is now a requirement to build Android apps ([see above](#java-17-and-android-gradle-plugin-upgrade)).
* **Android**: Major bump of Fresco to 3.0 ([#38275](https://github.com/facebook/react-native/pull/38275)).
* **iOS**: Raise minimum iOS version to 13.4 ([#36795](https://github.com/facebook/react-native/pull/36795)).
* **iOS**: Metro will no longer be automatically started when running builds via Xcode ([#38242](https://github.com/facebook/react-native/pull/38242)).
For library authors:
* **Android**: Bump to AGP 8.1.1 ([discussion](https://github.com/react-native-community/discussions-and-proposals/issues/671))
### React Native CLI Changes[](#react-native-cli-changes "Direct link to React Native CLI Changes")
#### Highlighted breaking changes[](#highlighted-breaking-changes "Direct link to Highlighted breaking changes")
* Change default task prefix in `build-android` command. From now on, when you run `build-android`, the `bundle` task will be run instead of `assemble` ([#1913](https://github.com/react-native-community/cli/pull/1913)).
* Remove fallback flow for Metro config defaults ([#1972](https://github.com/react-native-community/cli/pull/1972)).
* The [updated `metro.config.js` format](/blog/2023/06/21/0.72-metro-package-exports-symlinks.md#new-metroconfigjs-setup) from 0.72 is now required in 0.73, as we have removed the fallback copy of these defaults from CLI.
* Remove `--configuration` option from `run-ios` (replaced with `--mode`) ([#2028](https://github.com/react-native-community/cli/pull/2028)).
* Remove `--variant` option from `build-android` command (replaced with `--mode`) ([#2026](https://github.com/react-native-community/cli/pull/2026)).
[See full changelog for v12.0.0](https://github.com/react-native-community/cli/releases/tag/v12.0.0).
### Deprecated `@types/react-native`[](#deprecated-typesreact-native "Direct link to deprecated-typesreact-native")
As mentioned in [First-class Support for TypeScript](/blog/2023/01/03/typescript-first.md#declarations-shipped-with-react-native), we have shipped TypeScript types with `react-native` since 0.71 and we are now deprecating `@types/react-native` for 0.73.
We will not ship any future patches for existing versions. The guidance is to migrate away from `@types/react-native`. See instructions on [how to migrate](/blog/2023/01/03/typescript-first.md#how-to-migrate).
## Acknowledgements[](#acknowledgements "Direct link to Acknowledgements")
React Native 0.73 contains over [2259 commits](https://github.com/facebook/react-native/compare/v0.72.7...v0.73.0) from 68 contributors. Thanks for all your hard work!
## Upgrade to 0.73[](#upgrade-to-073 "Direct link to Upgrade to 0.73")
Please use the [React Native Upgrade Helper](https://react-native-community.github.io/upgrade-helper/) to view code changes between React Native versions for existing projects, in addition to the [Upgrading docs](/docs/upgrading.md). You can also create a new project with `npx react-native@latest init MyProject`.
If you use Expo, React Native 0.73 will be supported in the Expo SDK 50 release.
info
0.73 is now the latest stable version of React Native and **0.70.x now moves to unsupported**. For more information see [React Native’s support policy](https://github.com/reactwg/react-native-releases#releases-support-policy).
**Tags:**
* [announcement](/blog/tags/announcement)
* [release](/blog/tags/release)
* [debugging](/blog/tags/debugging)
---
# Source: https://reactnative.dev/blog/2023/01/27/71rc1-android-outage-postmortem.md
# React Native 0.71-RC0 Android outage postmortem
January 27, 2023 ·
8 min read

Nicola Corti
Software Engineer @ Meta
[](https://x.com/cortinico "X")[](https://github.com/cortinico "GitHub")[](https://bsky.app/profile/cortini.co "Bluesky")

Lorenzo Sciandra
Senior Software Engineer @ Microsoft
[](https://x.com/kelset "X")[](https://github.com/kelset "GitHub")
Now that 0.71 is [available](/blog/2023/01/12/version-071.md), we want to share some key information about the incident that broke Android builds for all React Native versions while releasing the first 0.71 release candidate for React Native & Expo Android builds on November 4th, 2022.
The contributors who helped tackle the incident recently attended a post-mortem meeting to discuss in detail what happened, what we all learned from it, and what actions we are going to take to avoid similar outages in the future.
## What happened[](#what-happened "Direct link to What happened")
On November 4th 2022, we published the version `0.71.0-rc0` of React Native, the first release candidate for 0.71, on several public repositories.
A major change made in this release candidate helped to improve build times by publishing artifacts to Maven Central, instead of building them from source. More details on how this was done are available in [RFC#508](https://github.com/react-native-community/discussions-and-proposals/pull/508) and [related discussions](https://github.com/reactwg/react-native-new-architecture/discussions/105).
Unfortunately, because of the way we scaffolded new projects from the template, this caused build failures for any Android user on older versions because they would start downloading new artifacts for `0.71.0-rc0` instead of the version they were using in their project (like `0.68.0`).
## Why this happened[](#why-this-happened "Direct link to Why this happened")
The React Native template provides a `build.gradle` file to build Android apps. This file contains a dependency on the React Native Android library as follows: `implementation("com.facebook.react:react-native:+")`.
Importantly, the `+` part of this dependency (a [Gradle Dynamic version](https://docs.gradle.org/current/userguide/dynamic_versions.html)) tells Gradle to pick the highest available version of React Native. Using Gradle Dynamic versions is considered an antipattern as it exposes users to less-reproducible builds.
We were aware of the issues dynamic versions could cause, so in `0.71` we cleaned up the new app template and removed all the `+` dependencies. However, users on older versions of React Native were still using a `+` version.
This caused builds with React Native versions before `0.71.0-rc.0` to query all the repositories for the highest available versions of the React Native. Because the newly pushed 0.71.0-rc.0 on Maven Central became the highest version available, builds with React Native versions before 0.71.0-rc.0 started using artifacts from 0.71.0-rc.0. The React Native version mismatch between the local build (e.g `0.68.0`) and artifacts from Maven Central (`0.71.0-rc.0`) caused these builds to fail.
Further technical details on this event area are also available [on this GitHub issue](https://github.com/facebook/react-native/issues/35210).
## How we mitigated & resolved[](#how-we-mitigated--resolved "Direct link to How we mitigated & resolved")
As soon as we identified the issue on November 4th, the community found and shared a manual workaround to fix the issue which would pin React Native to a specific, correcting the mistake.
Then, over the weekend of November 5th and 6th, the release crew shipped patch releases for all previous React Native versions down to 0.63 which automatically applied the patch, so that users could update to a fixed version of React Native.
At the same time, we [reached out to Sonatype](https://issues.sonatype.org/browse/OSSRH-86006) to ask for the removal of the offending artifacts.
The issue was fully resolved on November 8th when the artifacts were fully removed from Maven Central.
## Timeline of events[](#timeline-of-events "Direct link to Timeline of events")
*This section contains a brief timeline of the events. All times are GMT/UTC +0*
* Nov 4th - 5:06 PM: [0.71-RC0 is released](https://github.com/facebook/react-native/releases/tag/v0.71.0-rc.0).
* Nov 4th - 6:20 PM: [First report of build issue is opened](https://github.com/facebook/react-native/issues/35204).
* Nov 4th - 7:45 PM: [Issue is identified by community](https://github.com/facebook/react-native/issues/35204#issuecomment-1304090948).
* Nov 4th - 9:39 PM: [Workarounds are communicated, Expo ](https://github.com/facebook/react-native/issues/35204#issuecomment-1304281740)deploys fix to all their users.
* Nov 5th - 03:04 AM: [New issue is open to communicate status and workarounds](https://github.com/facebook/react-native/issues/35210).
* Nov 6th - 04:11 PM: [Ticket to SonaType](https://issues.sonatype.org/browse/OSSRH-86006?focusedCommentId=1216303\&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-1216303) asking for removal of the artifacts is open.
* Nov 6th - 04:40 PM: [First tweet](https://twitter.com/reactnative/status/1589296764678705155) from @reactnative with ack + link to issue.
* Nov 6th - 07:05 PM: Decision to patch React Native versions back to 0.63.
* Nov 7th - 12:47 AM: Last patched release is released: [0.63.5](https://github.com/facebook/react-native/releases/tag/v0.63.5).
* Nov 8th - 08:04 PM: Artifacts on Maven Central are [fully removed](https://issues.sonatype.org/browse/OSSRH-86006?focusedCommentId=1216303\&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-1216303).
* Nov 10th - 11:51 AM: Issue about the [incident is closed](https://github.com/facebook/react-native/issues/35210#issuecomment-1310170361).
## Lessons Learned[](#lessons-learned "Direct link to Lessons Learned")
While in many ways the conditions to trigger this incident has existed since React Native 0.12.0, we want to ensure that the foundations on which we develop and release React Native moving forward are stronger. Here are some of the lessons learned and the actionables on how we’ll adapt our processes and infrastructure to respond faster and stronger in the future.
### Incident response strategy[](#incident-response-strategy "Direct link to Incident response strategy")
This incident highlighted gaps in our incident response strategy for open-source issues related to React Native.
The community quickly found a workaround in less than 2 hours. Due to our lack of visibility on the scope of the impact of this issue, as well as the complexity required to fix it for old versions, we relied on impacted people discovering the workaround on the GitHub issue.
It took us 48 hours to recognize the larger scope of this issue and that we couldn’t rely on everyone finding the GitHub issue. We needed to prioritize more complex active mitigations to automatically fix people’s projects.
We will be revisiting our processes for when to rely on developer-applied-workarounds vs fixes that we can deploy automatically. We will also take a look at our options for getting a better live pulse on the health of our ecosystem.
### Release Support Policy[](#release-support-policy "Direct link to Release Support Policy")
As visualized in the [rn-versions tool](https://rn-versions.github.io/), to cover more than 90% of the developer base of React Native at the time of the incident, we had to release patches all the way down to version 0.63.
We believe this is caused by the React Native upgrade experience which has historically been full of frictions. We are currently looking into ways to improve the upgrade experience to make it smoother and faster to mitigate this fragmentation of the ecosystem.
Releasing a newer version of React Native should never have an impact on users on older versions, and we want to apologize for the disruption we caused to your workflow.
Similarly, we want to also stress the importance of being up to date with the latest version of your dependencies and React Native to benefit from the improvements and the safeguards we introduced. This incident happened during a time in which an official [release support policy](https://github.com/reactwg/react-native-releases#releases-support-policy) was getting defined and wasn’t broadcasted or enforced yet.
In the future, we will communicate our support policy over our communication channels and we will consider [deprecating older versions of React Native on npm](https://docs.npmjs.com/deprecating-and-undeprecating-packages-or-package-versions).
### Improved testing and best practices for 3rd party libraries[](#improved-testing-and-best-practices-for-3rd-party-libraries "Direct link to Improved testing and best practices for 3rd party libraries")
This incident highlighted the importance of having better release testing and better guidance to 3rd party libraries.
On the testing side, releasing versions down to `0.63.x` proved to be challenging due to the lack of automation and testing we now have in place for stable releases. We recognize the importance of our release and testing infrastructure and we’re going to invest further in it in the future.
Specifically, we are now encouraging and supporting 3rd party library testing as part of the [release of react native](https://github.com/reactwg/react-native-releases/discussions/41). We’re also adding some new channels and roles in the [Core Contributors Discord Server](https://github.com/facebook/react-native/blob/main/ECOSYSTEM.md#core-contributors).
On top of this, we started a closer collaboration with Callstack, the maintainers of [create-react-native-library](https://github.com/callstack/react-native-builder-bob/tree/main/packages/create-react-native-library), to improve the library template and make sure it follows all the necessary best practices to integrate with React Native projects. The newer version of `create-react-native-library` is now fully compatible with 0.71 projects while still offering backward compatibility.
## Conclusions[](#conclusions "Direct link to Conclusions")
We want to apologize for the disruption this caused to the workflows of developers all around the world. As highlighted above, we have already started taking action to strengthen our foundation - and more work is due.
We hope that sharing these insights will help you all better understand this incident, and that you can leverage our learnings to apply better practices in your own tools and projects.
In closing, we want once again to thank Sonatype for helping us remove the artifacts, our community, and the release crew that worked tirelessly to address this as soon as possible.
**Tags:**
* [engineering](/blog/tags/engineering)
---
# Source: https://reactnative.dev/docs/accessibility.md
# Accessibility
Both Android and iOS provide APIs for integrating apps with assistive technologies like the bundled screen readers VoiceOver (iOS) and TalkBack (Android). React Native has complementary APIs that let your app accommodate all users.
info
Android and iOS differ slightly in their approaches, and thus the React Native implementations may vary by platform.
## Accessibility properties[](#accessibility-properties "Direct link to Accessibility properties")
### `accessible`[](#accessible "Direct link to accessible")
When `true`, indicates that the view is discoverable by assistive technologies such as screen readers and hardware keyboards. Note that this does not necessarily mean that the view will be focused by VoiceOver or TalkBack. There are a number of reasons for this, such as VoiceOver disallowing nested accessibility elements, or TalkBack opting to focus some parent element instead.
By default, all touchable elements are accessible.
On Android, `accessible` will be translated into native [`focusable`](https://developer.android.com/reference/android/view/View#setFocusable\(boolean\)). On iOS, it translates into native [`isAccessibilityElement`](https://developer.apple.com/documentation/uikit/uiaccessibilityelement/isaccessibilityelement?language=objc).
tsx
```
```
In the above example, accessibility focus is only available on the first child view with the `accessible` property, and not for the parent or sibling without `accessible`.
### `accessibilityLabel`[](#accessibilitylabel "Direct link to accessibilitylabel")
When a view is marked as accessible, it is a good practice to set an `accessibilityLabel` on the view, so that people who use VoiceOver or TalkBack know what element they have selected. A screen reader will verbalize this string when the associated element is selected.
To use, set the `accessibilityLabel` property to a custom string on your View, Text, or Touchable:
tsx
```
Press me!
```
In the above example, the `accessibilityLabel` on the TouchableOpacity element would default to "Press me!". The label is constructed by concatenating all Text node children separated by spaces.
### `accessibilityLabelledBy`Android[](#accessibilitylabelledby-android "Direct link to accessibilitylabelledby-android")
A reference to another element [nativeID](/docs/view.md#nativeid) used to build complex forms. The value of `accessibilityLabelledBy` should match the `nativeID` of the related element:
tsx
```
Label for Input Field
```
In the above example, the screen reader announces `Input, Edit Box for Label for Input Field` when focusing on the TextInput.
### `accessibilityHint`[](#accessibilityhint "Direct link to accessibilityhint")
An accessibility hint can be used to provide additional context to the user on the result of the action when it is not clear from the accessibility label alone.
Provide the `accessibilityHint` property a custom string on your View, Text, or Touchable:
tsx
```
Back
```
iOS
In the above example, VoiceOver will read the hint after the label, if the user has hints enabled in the device's VoiceOver settings. Read more about guidelines for `accessibilityHint` in the [iOS Developer Docs](https://developer.apple.com/documentation/objectivec/nsobject/1615093-accessibilityhint)
Android
In the above example, TalkBack will read the hint after the label. At this time, hints cannot be turned off on Android.
### `accessibilityLanguage`iOS[](#accessibilitylanguage-ios "Direct link to accessibilitylanguage-ios")
By using the `accessibilityLanguage` property, the screen reader will understand which language to use while reading the element's **label**, **value**, and **hint**. The provided string value must follow the [BCP 47 specification](https://www.rfc-editor.org/info/bcp47).
tsx
```
🍕
```
### `accessibilityIgnoresInvertColors`iOS[](#accessibilityignoresinvertcolors-ios "Direct link to accessibilityignoresinvertcolors-ios")
Inverting screen colors is an accessibility feature available in iOS and iPadOS for people with color blindness, low vision, or vision impairment. If there's a view you don't want to invert when this setting is on, possibly a photo, set this property to `true`.
### `accessibilityLiveRegion`Android[](#accessibilityliveregion-android "Direct link to accessibilityliveregion-android")
When components dynamically change, we want TalkBack to alert the end user. This is made possible by the `accessibilityLiveRegion` property. It can be set to `none`, `polite`, and `assertive`:
* **none** Accessibility services should not announce changes to this view.
* **polite** Accessibility services should announce changes to this view.
* **assertive** Accessibility services should interrupt ongoing speech to immediately announce changes to this view.
tsx
```
Click me
Clicked {count} times
```
In the above example method `addOne` changes the state variable `count`. When the TouchableWithoutFeedback is triggered, TalkBack reads the text in the Text view because of its `accessibilityLiveRegion="polite"` property.
### `accessibilityRole`[](#accessibilityrole "Direct link to accessibilityrole")
`accessibilityRole` communicates the purpose of a component to the user of assistive technology.
`accessibilityRole` can be one of the following:
* **adjustable** Used when an element can be "adjusted" (e.g. a slider).
* **alert** Used when an element contains important text to be presented to the user.
* **button** Used when the element should be treated as a button.
* **checkbox** Used when an element represents a checkbox that can be checked, unchecked, or have a mixed checked state.
* **combobox** Used when an element represents a combo box, which allows the user to select among several choices.
* **header** Used when an element acts as a header for a content section (e.g. the title of a navigation bar).
* **image** Used when the element should be treated as an image. Can be combined with a button or link.
* **imagebutton** Used when the element should be treated as a button and is also an image.
* **keyboardkey** Used when the element acts as a keyboard key.
* **link** Used when the element should be treated as a link.
* **menu** Used when the component is a menu of choices.
* **menubar** Used when a component is a container of multiple menus.
* **menuitem** Used to represent an item within a menu.
* **none** Used when the element has no role.
* **progressbar** Used to represent a component that indicates the progress of a task.
* **radio** Used to represent a radio button.
* **radiogroup** Used to represent a group of radio buttons.
* **scrollbar** Used to represent a scroll bar.
* **search** Used when a text field element should also be treated as a search field.
* **spinbutton** Used to represent a button that opens a list of choices.
* **summary** Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.
* **switch** Used to represent a switch that can be turned on and off.
* **tab** Used to represent a tab.
* **tablist** Used to represent a list of tabs.
* **text** Used when the element should be treated as static text that cannot change.
* **timer** Used to represent a timer.
* **togglebutton** Used to represent a toggle button. Should be used with accessibilityState checked to indicate if the button is toggled on or off.
* **toolbar** Used to represent a toolbar (a container of action buttons or components).
* **grid** Used with ScrollView, VirtualizedList, FlatList, or SectionList to represent a grid. Adds the in/out of grid announcements to Android's GridView.
### `accessibilityShowsLargeContentViewer`iOS[](#accessibilityshowslargecontentviewer-ios "Direct link to accessibilityshowslargecontentviewer-ios")
A boolean value that determines whether the large content viewer is shown when the user performs a long press on the element.
Available in iOS 13.0 and later.
### `accessibilityLargeContentTitle`iOS[](#accessibilitylargecontenttitle-ios "Direct link to accessibilitylargecontenttitle-ios")
A string that will be used as the title of the large content viewer when it is shown.
Requires `accessibilityShowsLargeContentViewer` to be set to `true`.
tsx
```
Home
```
### `accessibilityState`[](#accessibilitystate "Direct link to accessibilitystate")
Describes the current state of a component to the assistive technology user.
`accessibilityState` is an object. It contains the following fields:
| Name | Description | Type | Required |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | -------- |
| disabled | Indicates whether the element is disabled or not. | boolean | No |
| selected | Indicates whether a selectable element is currently selected or not. | boolean | No |
| checked | Indicates the state of a checkable element. This field can either take a boolean or the "mixed" string to represent mixed checkboxes. | boolean or 'mixed' | No |
| busy | Indicates whether an element is currently busy or not. | boolean | No |
| expanded | Indicates whether an expandable element is currently expanded or collapsed. | boolean | No |
To use, set the `accessibilityState` to an object with a specific definition.
### `accessibilityValue`[](#accessibilityvalue "Direct link to accessibilityvalue")
Represents the current value of a component. It can be a textual description of a component's value, or for range-based components, such as sliders and progress bars, it contains range information (minimum, current, and maximum).
`accessibilityValue` is an object. It contains the following fields:
| Name | Description | Type | Required |
| ---- | ---------------------------------------------------------------------------------------------- | ------- | ------------------------- |
| min | The minimum value of this component's range. | integer | Required if `now` is set. |
| max | The maximum value of this component's range. | integer | Required if `now` is set. |
| now | The current value of this component's range. | integer | No |
| text | A textual description of this component's value. Will override `min`, `now`, and `max` if set. | string | No |
### `accessibilityViewIsModal`iOS[](#accessibilityviewismodal-ios "Direct link to accessibilityviewismodal-ios")
A boolean value that indicates whether VoiceOver should ignore the elements within views that are siblings of the receiver.
For example, in a window that contains sibling views `A` and `B`, setting `accessibilityViewIsModal` to `true` on view `B` causes VoiceOver to ignore the elements in view `A`. On the other hand, if view `B` contains a child view `C` and you set `accessibilityViewIsModal` to `true` on view `C`, VoiceOver does not ignore the elements in view `A`.
### `accessibilityElementsHidden`iOS[](#accessibilityelementshidden-ios "Direct link to accessibilityelementshidden-ios")
A boolean value indicating whether the given accessibility element, and any accessibility elements it contains, are hidden.
For example, in a window that contains sibling views `A` and `B`, setting `accessibilityElementsHidden` to `true` on view `B` causes VoiceOver to ignore the `B` view and any elements it contains. This is similar to the Android property `importantForAccessibility="no-hide-descendants"`.
### `aria-valuemax`[](#aria-valuemax "Direct link to aria-valuemax")
Represents the maximum value for range-based components, such as sliders and progress bars.
### `aria-valuemin`[](#aria-valuemin "Direct link to aria-valuemin")
Represents the minimum value for range-based components, such as sliders and progress bars.
### `aria-valuenow`[](#aria-valuenow "Direct link to aria-valuenow")
Represents the current value for range-based components, such as sliders and progress bars.
### `aria-valuetext`[](#aria-valuetext "Direct link to aria-valuetext")
Represents the textual description of the component.
### `aria-busy`[](#aria-busy "Direct link to aria-busy")
Indicates an element is being modified and that assistive technologies may want to wait until the changes are complete before informing the user about the update.
| Type | Default |
| ------- | ------- |
| boolean | false |
### `aria-checked`[](#aria-checked "Direct link to aria-checked")
Indicates the state of a checkable element. This field can either take a boolean or the "mixed" string to represent mixed checkboxes.
| Type | Default |
| ---------------- | ------- |
| boolean, 'mixed' | false |
### `aria-disabled`[](#aria-disabled "Direct link to aria-disabled")
Indicates that the element is perceivable but disabled, so it is not editable or otherwise operable.
| Type | Default |
| ------- | ------- |
| boolean | false |
### `aria-expanded`[](#aria-expanded "Direct link to aria-expanded")
Indicates whether an expandable element is currently expanded or collapsed.
| Type | Default |
| ------- | ------- |
| boolean | false |
### `aria-hidden`[](#aria-hidden "Direct link to aria-hidden")
Indicates whether the element is hidden from assistive technologies.
For example, in a window that contains sibling views `A` and `B`, setting `aria-hidden` to `true` on view `B` causes VoiceOver to ignore the `B` element and its children.
| Type | Default |
| ------- | ------- |
| boolean | false |
### `aria-label`[](#aria-label "Direct link to aria-label")
Defines a string value that can be used to name an element.
| Type |
| ------ |
| string |
### `aria-labelledby`Android[](#aria-labelledby-android "Direct link to aria-labelledby-android")
Identifies the element that labels the element it is applied to. The value of `aria-labelledby` should match the [`nativeID`](/docs/view.md#nativeid) of the related element:
tsx
```
Label for Input Field
```
| Type |
| ------ |
| string |
### `aria-live`Android[](#aria-live-android "Direct link to aria-live-android")
Indicates that an element will be updated and describes the types of updates the user agents, assistive technologies, and user can expect from the live region.
* **off** Accessibility services should not announce changes to this view.
* **polite** Accessibility services should announce changes to this view.
* **assertive** Accessibility services should interrupt ongoing speech to immediately announce changes to this view.
| Type | Default |
| ---------------------------------------- | ------- |
| enum(`'assertive'`, `'off'`, `'polite'`) | `'off'` |
***
### `aria-modal`iOS[](#aria-modal-ios "Direct link to aria-modal-ios")
Boolean value indicating whether VoiceOver should ignore the elements within views that are siblings of the receiver.
| Type | Default |
| ------- | ------- |
| boolean | false |
### `aria-selected`[](#aria-selected "Direct link to aria-selected")
Indicates whether a selectable element is currently selected or not.
| Type |
| ------- |
| boolean |
### `experimental_accessibilityOrder`[](#experimental_accessibilityorder "Direct link to experimental_accessibilityorder")
Experimental 🧪
**This API is experimental.** Experimental APIs may contain bugs and are likely to change in a future version of React Native. Don't use them in production.
note
For the sake of brevity, layout is excluded in the following examples even though it dictates the default focus order. Assume the document order matches the layout order.
`experimental_accessibilityOrder` lets you define the order in which assistive technologies focus descendant components. It is an array of [`nativeIDs`](/docs/view.md#nativeid) that are set on the components whose order you are controlling. For example:
```
```
Assistive technologies will focus the `View` with `nativeID` of `B`, then `C`, then `A`.
`experimental_accessibilityOrder` will not “turn on” accessibility for the components it references, that still needs to be done. So if we remove `accessible={true}` on `C` above like so
```
```
then the new order will be `B` then `A`, even though `C` is still in `experimental_accessibilityOrder`.
`experimental_accessibilityOrder` will “turn off” accessibility of components it doesn’t reference, however.
```
```
The order of the above example would be `B`, `C`, `A`. `D` will never get focused. In this sense `experimental_accessibilityOrder` is *exhaustive*.
There are still valid reasons to include an non-accessible component in `experimental_accessibilityOrder`. Consider
```
```
The focus order will be `B`, `D`, `E`, `F`, `A`. Even though `D`, `E`, and `F` are not directly referenced in `experimental_accessibilityOrder`, `C` is directly referenced. In this instance `C` in an *accessibility container* - it contains accessible elements, but is not accessible itself. If an accessibility container is referenced in `experimental_accessibilityOrder` then the default order of the elements it contains is applied. In this sense `experimental_accessibilityOrder` is *nestable*.
`experimental_accessibilityOrder` can also reference another component with `experimental_accessibilityOrder`
```
```
The focus order will be `B`, `F`, `E`, `D`, `A`.
A component cannot be both an accessibility container and an accessibility element (`accessible={true}`). So if we have
```
```
The focus order would be `B`, `C`, `A`. `D`, `E`, and `F` are no longer in a container, so the exhaustive nature of `experimental_accessibilityOrder` means they will be excluded.
### `importantForAccessibility`Android[](#importantforaccessibility-android "Direct link to importantforaccessibility-android")
In the case of two overlapping UI components with the same parent, default accessibility focus can have unpredictable behavior. The `importantForAccessibility` property will resolve this by controlling if a view fires accessibility events and if it is reported to accessibility services. It can be set to `auto`, `yes`, `no` and `no-hide-descendants` (the last value will force accessibility services to ignore the component and all of its children).
tsx
```
First layoutSecond layout
```
In the above example, the `yellow` layout and its descendants are completely invisible to TalkBack and all other accessibility services. So we can use overlapping views with the same parent without confusing TalkBack.
### `onAccessibilityEscape`iOS[](#onaccessibilityescape-ios "Direct link to onaccessibilityescape-ios")
Assign this property to a custom function which will be called when someone performs the "escape" gesture, which is a two finger Z shaped gesture. An escape function should move back hierarchically in the user interface. This can mean moving up or back in a navigation hierarchy or dismissing a modal user interface. If the selected element does not have an `onAccessibilityEscape` function, the system will attempt to traverse up the view hierarchy until it finds a view that does or bonk to indicate it was unable to find one.
### `onAccessibilityTap`iOS[](#onaccessibilitytap-ios "Direct link to onaccessibilitytap-ios")
Use this property to assign a custom function to be called when someone activates an accessible element by double tapping on it while it's selected.
### `onMagicTap`iOS[](#onmagictap-ios "Direct link to onmagictap-ios")
Assign this property to a custom function which will be called when someone performs the "magic tap" gesture, which is a double-tap with two fingers. A magic tap function should perform the most relevant action a user could take on a component. In the Phone app on iPhone, a magic tap answers a phone call or ends the current one. If the selected element does not have an `onMagicTap` function, the system will traverse up the view hierarchy until it finds a view that does.
### `role`[](#role "Direct link to role")
`role` communicates the purpose of a component and has precedence over the [`accessibilityRole`](/docs/accessibility.md#accessibilityrole) prop.
`role` can be one of the following:
* **alert** Used when an element contains important text to be presented to the user.
* **button** Used when the element should be treated as a button.
* **checkbox** Used when an element represents a checkbox that can be checked, unchecked, or have a mixed checked state.
* **combobox** Used when an element represents a combo box, which allows the user to select among several choices.
* **grid** Used with ScrollView, VirtualizedList, FlatList, or SectionList to represent a grid. Adds the in/out of grid announcements to the android GridView.
* **heading** Used when an element acts as a header for a content section (e.g. the title of a navigation bar).
* **img** Used when the element should be treated as an image. Can be combined with a button or link, for example.
* **link** Used when the element should be treated as a link.
* **list** Used to identify a list of items.
* **listitem** Used to itentify an item in a list.
* **menu** Used when the component is a menu of choices.
* **menubar** Used when a component is a container of multiple menus.
* **menuitem** Used to represent an item within a menu.
* **none** Used when the element has no role.
* **presentation** Used when the element has no role.
* **progressbar** Used to represent a component that indicates the progress of a task.
* **radio** Used to represent a radio button.
* **radiogroup** Used to represent a group of radio buttons.
* **scrollbar** Used to represent a scroll bar.
* **searchbox** Used when the text field element should also be treated as a search field.
* **slider** Used when an element can be "adjusted" (e.g. a slider).
* **spinbutton** Used to represent a button that opens a list of choices.
* **summary** Used when an element can be used to provide a quick summary of current conditions in the app when the app first launches.
* **switch** Used to represent a switch that can be turned on and off.
* **tab** Used to represent a tab.
* **tablist** Used to represent a list of tabs.
* **timer** Used to represent a timer.
* **toolbar** Used to represent a toolbar (a container of action buttons or components).
## Accessibility Actions[](#accessibility-actions "Direct link to Accessibility Actions")
Accessibility actions allow assistive technology to programmatically invoke the action(s) of a component. To support accessibility actions, a component must do two things:
* Define the list of actions it supports via the `accessibilityActions` property.
* Implement an `onAccessibilityAction` function to handle action requests.
The `accessibilityActions` property should contain a list of action objects. Each action object should contain the following fields:
| Name | Type | Required |
| ----- | ------ | -------- |
| name | string | Yes |
| label | string | No |
Actions either represent standard actions, such as clicking a button or adjusting a slider, or custom actions specific to a given component such as deleting an email message. The `name` field is required for both standard and custom actions, but `label` is optional for standard actions.
When adding support for standard actions, `name` must be one of the following:
* `'magicTap'` - iOS only - While VoiceOver focus is on or inside the component, the user double tapped with two fingers.
* `'escape'` - iOS only - While VoiceOver focus is on or inside the component, the user performed a two-finger scrub gesture (left, right, left).
* `'activate'` - Activate the component. This should perform the same action with, or without, assistive technology. Engaged when a screen reader user double taps the component.
* `'increment'` - Increment an adjustable component. On iOS, VoiceOver generates this action when the component has a role of `'adjustable'` and the user places focus on it and swipes upward. On Android, TalkBack generates this action when the user places accessibility focus on the component and presses the volume-up button.
* `'decrement'` - Decrement an adjustable component. On iOS, VoiceOver generates this action when the component has a role of `'adjustable'` and the user places focus on it and swipes downward. On Android, TalkBack generates this action when the user places accessibility focus on the component and presses the volume-down button.
* `'longpress'` - Android only - This action is generated when the user places accessibility focus on the component, then double-taps and holds one finger on the screen. This should perform the same action with, or without, assistive technology.
* `'expand'` - Android only - This action "expands" the component so that TalkBack will announce an "expanded" hint.
* `'collapse'` - Android only - This action "collapses" the component so that TalkBack will announce a "collapsed" hint.
The `label` field is optional for standard actions and is often unused by assistive technologies. For custom actions, it is a localized string containing a description of the action to be presented to the user.
To handle action requests, a component must implement an `onAccessibilityAction` function. The only argument to this function is an event containing the name of the action to perform. The below example from RNTester shows how to create a component that defines and handles several custom actions.
tsx
```
{
switch (event.nativeEvent.actionName) {
case 'cut':
Alert.alert('Alert', 'cut action success');
break;
case 'copy':
Alert.alert('Alert', 'copy action success');
break;
case 'paste':
Alert.alert('Alert', 'paste action success');
break;
}
}}
/>
```
## Checking if a Screen Reader is Enabled[](#checking-if-a-screen-reader-is-enabled "Direct link to Checking if a Screen Reader is Enabled")
The `AccessibilityInfo` API allows you to determine whether or not a screen reader is currently active. See the [AccessibilityInfo documentation](/docs/accessibilityinfo.md) for details.
## Sending Accessibility EventsAndroid[](#sending-accessibility-events-android "Direct link to sending-accessibility-events-android")
Sometimes it is useful to trigger an accessibility event on a UI component (i.e. when a custom view appears on a screen or set accessibility focus to a view). Native UIManager module exposes a method ‘sendAccessibilityEvent’ for this purpose. It takes two arguments: a view tag and a type of event. The supported event types are `typeWindowStateChanged`, `typeViewFocused`, and `typeViewClicked`.
tsx
```
import {Platform, UIManager, findNodeHandle} from 'react-native';
if (Platform.OS === 'android') {
UIManager.sendAccessibilityEvent(
findNodeHandle(this),
UIManager.AccessibilityEventTypes.typeViewFocused,
);
}
```
## Testing TalkBack SupportAndroid[](#testing-talkback-support-android "Direct link to testing-talkback-support-android")
To enable TalkBack, go to the Settings app on your Android device or emulator. Tap Accessibility, then TalkBack. Toggle the "Use service" switch to enable or disable it.
Android emulators don't have TalkBack installed by default. You can install TalkBack on your emulator via the Google Play Store. Make sure to choose an emulator with the Google Play store installed. These are available in Android Studio.
You can use the volume key shortcut to toggle TalkBack. To turn on the volume key shortcut, go to the Settings app, then Accessibility. At the top, turn on the volume key shortcut.
To use the volume key shortcut, press both volume keys for 3 seconds to start an accessibility tool.
Additionally, if you prefer, you can toggle TalkBack via the command line with:
shell
```
# disable
adb shell settings put secure enabled_accessibility_services com.android.talkback/com.google.android.marvin.talkback.TalkBackService
# enable
adb shell settings put secure enabled_accessibility_services com.google.android.marvin.talkback/com.google.android.marvin.talkback.TalkBackService
```
## Testing VoiceOver SupportiOS[](#testing-voiceover-support-ios "Direct link to testing-voiceover-support-ios")
To enable VoiceOver on your iOS or iPadOS device, go to the Settings app, tap General, then Accessibility. There you will find many tools available for people to enable their devices to be more usable, including VoiceOver. To enable VoiceOver, tap on VoiceOver under "Vision" and toggle the switch that appears at the top.
At the very bottom of the Accessibility settings, there is an "Accessibility Shortcut". You can use this to toggle VoiceOver by triple-clicking the Home button.
VoiceOver isn't available via the simulator, but you can use Accessibility Inspector from Xcode to use the macOS VoiceOver through an application. Note it's always best to test with a device as macOS's VoiceOver may result in varied experiences.
## Additional Resources[](#additional-resources "Direct link to Additional Resources")
* [Making React Native Apps Accessible](https://engineering.fb.com/ios/making-react-native-apps-accessible/)
---
# Source: https://reactnative.dev/docs/accessibilityinfo.md
# AccessibilityInfo
Sometimes it's useful to know whether or not the device has a screen reader that is currently active. The `AccessibilityInfo` API is designed for this purpose. You can use it to query the current state of the screen reader as well as to register to be notified when the state of the screen reader changes.
## Example[](#example "Direct link to Example")
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `addEventListener()`[](#addeventlistener "Direct link to addeventlistener")
tsx
```
static addEventListener(
eventName: AccessibilityChangeEventName | AccessibilityAnnouncementEventName,
handler: (
event: AccessibilityChangeEvent | AccessibilityAnnouncementFinishedEvent,
) => void,
): EmitterSubscription;
```
Add an event handler. Supported events:
| Event name | Description |
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `accessibilityServiceChanged` Android | Fires when some services such as TalkBack, other Android assistive technologies, and third-party accessibility services are enabled. The argument to the event handler is a boolean. The boolean is `true` when a some accessibility services is enabled and `false` otherwise. |
| `announcementFinished` iOS | Fires when the screen reader has finished making an announcement. The argument to the event handler is a dictionary with these keys:- `announcement`: The string announced by the screen reader. - `success`: A boolean indicating whether the announcement was successfully made. |
| `boldTextChanged` iOS | Fires when the state of the bold text toggle changes. The argument to the event handler is a boolean. The boolean is `true` when bold text is enabled and `false` otherwise. |
| `grayscaleChanged` iOS | Fires when the state of the gray scale toggle changes. The argument to the event handler is a boolean. The boolean is `true` when a gray scale is enabled and `false` otherwise. |
| `invertColorsChanged` iOS | Fires when the state of the invert colors toggle changes. The argument to the event handler is a boolean. The boolean is `true` when invert colors is enabled and `false` otherwise. |
| `reduceMotionChanged` | Fires when the state of the reduce motion toggle changes. The argument to the event handler is a boolean. The boolean is `true` when a reduce motion is enabled (or when "Transition Animation Scale" in "Developer options" is "Animation off") and `false` otherwise. |
| `reduceTransparencyChanged` iOS | Fires when the state of the reduce transparency toggle changes. The argument to the event handler is a boolean. The boolean is `true` when reduce transparency is enabled and `false` otherwise. |
| `screenReaderChanged` | Fires when the state of the screen reader changes. The argument to the event handler is a boolean. The boolean is `true` when a screen reader is enabled and `false` otherwise. |
***
### `announceForAccessibility()`[](#announceforaccessibility "Direct link to announceforaccessibility")
tsx
```
static announceForAccessibility(announcement: string);
```
Post a string to be announced by the screen reader.
***
### `announceForAccessibilityWithOptions()`[](#announceforaccessibilitywithoptions "Direct link to announceforaccessibilitywithoptions")
tsx
```
static announceForAccessibilityWithOptions(
announcement: string,
options: {queue?: boolean},
);
```
Post a string to be announced by the screen reader with modification options. By default announcements will interrupt any existing speech, but on iOS they can be queued behind existing speech by setting `queue` to `true` in the options object.
**Parameters:**
| Name | Type | Description |
| -------------------- | ------ | ---------------------------------------------------------- |
| announcementRequired | string | The string to be announced |
| optionsRequired | object | `queue` - queue the announcement behind existing speechiOS |
***
### `getRecommendedTimeoutMillis()`Android[](#getrecommendedtimeoutmillis-android "Direct link to getrecommendedtimeoutmillis-android")
tsx
```
static getRecommendedTimeoutMillis(originalTimeout: number): Promise;
```
Gets the timeout in millisecond that the user needs. This value is set in "Time to take action (Accessibility timeout)" of "Accessibility" settings.
**Parameters:**
| Name | Type | Description |
| ----------------------- | ------ | ------------------------------------------------------------------------------------- |
| originalTimeoutRequired | number | The timeout to return if "Accessibility timeout" is not set. Specify in milliseconds. |
***
### `isAccessibilityServiceEnabled()`Android[](#isaccessibilityserviceenabled-android "Direct link to isaccessibilityserviceenabled-android")
tsx
```
static isAccessibilityServiceEnabled(): Promise;
```
Check whether any accessibility service is enabled. This includes TalkBack but also any third-party accessibility app that may be installed. To only check whether TalkBack is enabled, use [isScreenReaderEnabled](#isscreenreaderenabled). Returns a promise which resolves to a boolean. The result is `true` when some accessibility services is enabled and `false` otherwise.
note
Please use [`isScreenReaderEnabled`](#isscreenreaderenabled) if you only want to check the status of TalkBack.
***
### `isBoldTextEnabled()`iOS[](#isboldtextenabled-ios "Direct link to isboldtextenabled-ios")
tsx
```
static isBoldTextEnabled(): Promise:
```
Query whether a bold text is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when bold text is enabled and `false` otherwise.
***
### `isGrayscaleEnabled()`iOS[](#isgrayscaleenabled-ios "Direct link to isgrayscaleenabled-ios")
tsx
```
static isGrayscaleEnabled(): Promise;
```
Query whether grayscale is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when grayscale is enabled and `false` otherwise.
***
### `isInvertColorsEnabled()`iOS[](#isinvertcolorsenabled-ios "Direct link to isinvertcolorsenabled-ios")
tsx
```
static isInvertColorsEnabled(): Promise;
```
Query whether invert colors is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when invert colors is enabled and `false` otherwise.
***
### `isReduceMotionEnabled()`[](#isreducemotionenabled "Direct link to isreducemotionenabled")
tsx
```
static isReduceMotionEnabled(): Promise;
```
Query whether reduce motion is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when reduce motion is enabled and `false` otherwise.
***
### `isReduceTransparencyEnabled()`iOS[](#isreducetransparencyenabled-ios "Direct link to isreducetransparencyenabled-ios")
tsx
```
static isReduceTransparencyEnabled(): Promise;
```
Query whether reduce transparency is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when a reduce transparency is enabled and `false` otherwise.
***
### `isScreenReaderEnabled()`[](#isscreenreaderenabled "Direct link to isscreenreaderenabled")
tsx
```
static isScreenReaderEnabled(): Promise;
```
Query whether a screen reader is currently enabled. Returns a promise which resolves to a boolean. The result is `true` when a screen reader is enabled and `false` otherwise.
***
### `prefersCrossFadeTransitions()`iOS[](#preferscrossfadetransitions-ios "Direct link to preferscrossfadetransitions-ios")
tsx
```
static prefersCrossFadeTransitions(): Promise;
```
Query whether reduce motion and prefer cross-fade transitions settings are currently enabled. Returns a promise which resolves to a boolean. The result is `true` when prefer cross-fade transitions is enabled and `false` otherwise.
***
### 🗑️ `setAccessibilityFocus()`[](#️-setaccessibilityfocus "Direct link to ️-setaccessibilityfocus")
Deprecated
Prefer using `sendAccessibilityEvent` with eventType `focus` instead.
tsx
```
static setAccessibilityFocus(reactTag: number);
```
Set accessibility focus to a React component.
On Android, this calls `UIManager.sendAccessibilityEvent` method with passed `reactTag` and `UIManager.AccessibilityEventTypes.typeViewFocused` arguments.
note
Make sure that any `View` you want to receive the accessibility focus has `accessible={true}`.
***
### `sendAccessibilityEvent()`[](#sendaccessibilityevent "Direct link to sendaccessibilityevent")
tsx
```
static sendAccessibilityEvent(host: HostInstance, eventType: AccessibilityEventTypes);
```
Imperatively trigger an accessibility event on a React component, like changing the focused element for a screen reader.
note
Make sure that any `View` you want to receive the accessibility focus has `accessible={true}`.
| Name | Type | Description |
| ----------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| hostRequired | HostInstance | The component ref to send the event to. |
| eventTypeRequired | AccessibilityEventTypes | One of `'click'` (Android only), `'focus'`, `'viewHoverEnter'` (Android only), or `'windowStateChange'` (Android only) |
---
# Source: https://reactnative.dev/docs/actionsheetios.md
# ActionSheetIOS
Displays native to iOS [Action Sheet](https://developer.apple.com/design/human-interface-guidelines/action-sheets) component.
## Example[](#example "Direct link to Example")
# Reference
## Methods[](#methods "Direct link to Methods")
### `showActionSheetWithOptions()`[](#showactionsheetwithoptions "Direct link to showactionsheetwithoptions")
tsx
```
static showActionSheetWithOptions: (
options: ActionSheetIOSOptions,
callback: (buttonIndex: number) => void,
);
```
Display an iOS action sheet. The `options` object must contain one or more of:
* `options` (array of strings) - a list of button titles (required)
* `cancelButtonIndex` (int) - index of cancel button in `options`
* `cancelButtonTintColor` (string) - the [color](/docs/colors.md) used for the change the text color of the cancel button
* `destructiveButtonIndex` (int or array of ints) - indices of destructive buttons in `options`
* `title` (string) - a title to show above the action sheet
* `message` (string) - a message to show below the title
* `anchor` (number) - the node to which the action sheet should be anchored (used for iPad)
* `tintColor` (string) - the [color](/docs/colors.md) used for non-destructive button titles
* `disabledButtonIndices` (array of numbers) - a list of button indices which should be disabled
* `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
The 'callback' function takes one parameter, the zero-based index of the selected item.
Minimal example:
tsx
```
ActionSheetIOS.showActionSheetWithOptions(
{
options: ['Cancel', 'Remove'],
destructiveButtonIndex: 1,
cancelButtonIndex: 0,
},
buttonIndex => {
if (buttonIndex === 1) {
/* destructive action */
}
},
);
```
***
### `dismissActionSheet()`[](#dismissactionsheet "Direct link to dismissactionsheet")
tsx
```
static dismissActionSheet();
```
Dismisses the most upper iOS action sheet presented, if no action sheet is present a warning is displayed.
***
### `showShareActionSheetWithOptions()`[](#showshareactionsheetwithoptions "Direct link to showshareactionsheetwithoptions")
tsx
```
static showShareActionSheetWithOptions: (
options: ShareActionSheetIOSOptions,
failureCallback: (error: Error) => void,
successCallback: (success: boolean, method: string) => void,
);
```
Display the iOS share sheet. The `options` object should contain one or both of `message` and `url` and can additionally have a `subject` or `excludedActivityTypes`:
* `url` (string) - a URL to share
* `message` (string) - a message to share
* `subject` (string) - a subject for the message
* `excludedActivityTypes` (array) - the activities to exclude from the ActionSheet
note
If `url` points to a local file, or is a base64-encoded uri, the file it points to will be loaded and shared directly. In this way, you can share images, videos, PDF files, etc. If `url` points to a remote file or address it must conform to URL format as described in [RFC 2396](https://www.ietf.org/rfc/rfc2396.txt). For example, a web URL without a proper protocol (HTTP/HTTPS) will not be shared.
The 'failureCallback' function takes one parameter, an error object. The only property defined on this object is an optional `stack` property of type `string`.
The 'successCallback' function takes two parameters:
* a boolean value signifying success or failure
* a string that, in the case of success, indicates the method of sharing
---
# Source: https://reactnative.dev/docs/activityindicator.md
# ActivityIndicator
Displays a circular loading indicator.
## Example[](#example "Direct link to Example")
# Reference
## Props[](#props "Direct link to Props")
### [View Props](/docs/view.md#props)[](#view-props "Direct link to view-props")
Inherits [View Props](/docs/view.md#props).
***
### `animating`[](#animating "Direct link to animating")
Whether to show the indicator (`true`) or hide it (`false`).
| Type | Default |
| ---- | ------- |
| bool | `true` |
***
### `color`[](#color "Direct link to color")
The foreground color of the spinner.
| Type | Default |
| ------------------------ | ------------------------------------------------------------ |
| [color](/docs/colors.md) | `null` (system accent default color)Android***`'#999999'`iOS |
***
### `hidesWhenStopped`iOS[](#hideswhenstopped-ios "Direct link to hideswhenstopped-ios")
Whether the indicator should hide when not animating.
| Type | Default |
| ---- | ------- |
| bool | `true` |
***
### `ref`[](#ref "Direct link to ref")
A ref setter that will be assigned an [element node](/docs/element-nodes.md) when mounted.
***
### `size`[](#size "Direct link to size")
Size of the indicator.
| Type | Default |
| ------------------------------------------ | --------- |
| enum(`'small'`, `'large'`)***numberAndroid | `'small'` |
---
# Source: https://reactnative.dev/docs/the-new-architecture/advanced-topics-components.md
# Advanced Topics on Native Modules Development
This document contains a set of advanced topics to implement more complex functionalities of Native Components. It is recommended to first read the [Codegen](/docs/the-new-architecture/what-is-codegen.md) section and the guides on [Native Components](/docs/fabric-native-components-introduction.md).
This guide will cover the following topics:
* [Direct Manipulation](/docs/the-new-architecture/direct-manipulation-new-architecture.md)
* [Measuring the Layout](/docs/the-new-architecture/layout-measurements.md)
* [Invoking native functions on your native component](/docs/next/the-new-architecture/fabric-component-native-commands)
---
# Source: https://reactnative.dev/docs/the-new-architecture/advanced-topics-modules.md
# Advanced Topics on Native Modules Development
This document contains a set of advanced topics to implement more complex functionalities of Native Modules. It is recommended to first read the [Codegen](/docs/the-new-architecture/what-is-codegen.md) section and the guides on [Native Modules](/docs/turbo-native-modules-introduction.md).
This guide will cover the following topics:
* [Add custom C++ types to your C++ modules](/docs/the-new-architecture/custom-cxx-types.md)
* [Use Swift in your Module](/docs/next/the-new-architecture/turbo-modules-with-swift)
* [Emit custom events from your Native Modules](/docs/next/the-new-architecture/native-modules-custom-events)
* [Native Modules Lifecycle](/docs/next/the-new-architecture/native-modules-lifecycle)
---
# Source: https://reactnative.dev/docs/alert.md
# Alert
Launches an alert dialog with the specified title and message.
Optionally provide a list of buttons. Tapping any button will fire the respective onPress callback and dismiss the alert. By default, the only button will be an 'OK' button.
This is an API that works both on Android and iOS and can show static alerts. Alert that prompts the user to enter some information is available on iOS only.
## Example[](#example "Direct link to Example")
## iOS[](#ios "Direct link to iOS")
On iOS you can specify any number of buttons. Each button can optionally specify a style or be emphasized, available options are represented by the [AlertButtonStyle](#alertbuttonstyle-ios) enum and the `isPreferred` field on [AlertButton](/docs/alert.md#alertbutton).
## Android[](#android "Direct link to Android")
On Android at most three buttons can be specified. Android has a concept of a neutral, negative and a positive button:
* If you specify one button, it will be the 'positive' one (such as 'OK')
* Two buttons mean 'negative', 'positive' (such as 'Cancel', 'OK')
* Three buttons mean 'neutral', 'negative', 'positive' (such as 'Later', 'Cancel', 'OK')
Alerts on Android can be dismissed by tapping outside of the alert box. It is disabled by default and can be enabled by providing an optional [AlertOptions](/docs/alert.md#alertoptions) parameter with the cancelable property set to `true` i.e. `{cancelable: true}`.
The cancel event can be handled by providing an `onDismiss` callback property inside the `options` parameter.
### ExampleAndroid[](#example-android "Direct link to example-android")
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `alert()`[](#alert "Direct link to alert")
tsx
```
static alert (
title: string,
message?: string,
buttons?: AlertButton[],
options?: AlertOptions,
);
```
**Parameters:**
| Name | Type | Description |
| ------------- | -------------------------------------------- | ----------------------------------------------------------------------- |
| titleRequired | string | The dialog's title. Passing `null` or empty string will hide the title. |
| message | string | An optional message that appears below the dialog's title. |
| buttons | [AlertButton](/docs/alert.md#alertbutton)\[] | An optional array containing buttons configuration. |
| options | [AlertOptions](/docs/alert.md#alertoptions) | An optional Alert configuration. |
***
### `prompt()`iOS[](#prompt-ios "Direct link to prompt-ios")
tsx
```
static prompt: (
title: string,
message?: string,
callbackOrButtons?: ((text: string) => void) | AlertButton[],
type?: AlertType,
defaultValue?: string,
keyboardType?: string,
);
```
Create and display a prompt to enter some text in form of Alert.
**Parameters:**
| Name | Type | Description |
| ----------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| titleRequired | string | The dialog's title. |
| message | string | An optional message that appears above the text input. |
| callbackOrButtons | function***[AlertButton](/docs/alert.md#alertButton)\[] | If passed a function, it will be called with the prompt's value `(text: string) => void`, when the user taps 'OK'.***If passed an array, buttons will be configured based on the array content. |
| type | [AlertType](/docs/alert.md#alerttype-ios) | This configures the text input. |
| defaultValue | string | The default text in text input. |
| keyboardType | string | The keyboard type of first text field (if exists). One of TextInput [keyboardTypes](/docs/textinput.md#keyboardtype). |
| options | [AlertOptions](/docs/alert.md#alertoptions) | An optional Alert configuration. |
***
## Type Definitions[](#type-definitions "Direct link to Type Definitions")
### AlertButtonStyleiOS[](#alertbuttonstyle-ios "Direct link to alertbuttonstyle-ios")
An iOS Alert button style.
| Type |
| ---- |
| enum |
**Constants:**
| Value | Description |
| --------------- | ------------------------- |
| `'default'` | Default button style. |
| `'cancel'` | Cancel button style. |
| `'destructive'` | Destructive button style. |
***
### AlertTypeiOS[](#alerttype-ios "Direct link to alerttype-ios")
An iOS Alert type.
| Type |
| ---- |
| enum |
**Constants:**
| Value | Description |
| ------------------ | ---------------------------- |
| `'default'` | Default alert with no inputs |
| `'plain-text'` | Plain text input alert |
| `'secure-text'` | Secure text input alert |
| `'login-password'` | Login and password alert |
***
### AlertButton[](#alertbutton "Direct link to AlertButton")
An object describing the configuration of a button in the alert.
| Type |
| ---------------- |
| array of objects |
**Objects properties:**
| Name | Type | Description |
| -------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------ |
| text | string | Button label. |
| onPress | function | Callback function when button is pressed. |
| styleiOS | [AlertButtonStyle](/docs/alert.md#alertbuttonstyle-ios) | Button style, on Android this property will be ignored. |
| isPreferrediOS | boolean | Whether button should be emphasized, on Android this property will be ignored. |
***
### AlertOptions[](#alertoptions "Direct link to AlertOptions")
| Type |
| ------ |
| object |
**Properties:**
| Name | Type | Description |
| --------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| cancelableAndroid | boolean | Defines if alert can be dismissed by tapping outside of the alert box. |
| userInterfaceStyleiOS | string | The interface style used for the alert, can be set to `light` or `dark`, otherwise the default system style will be used. |
| onDismissAndroid | function | Callback function fired when alert has been dismissed. |
---
# Source: https://reactnative.dev/docs/alertios.md
# ❌ AlertIOS
Removed from React Native
Use [`Alert`](/docs/alert.md) instead.
---
# Source: https://reactnative.dev/docs/animated.md
# Animated
The `Animated` library is designed to make animations fluid, powerful, and painless to build and maintain. `Animated` focuses on declarative relationships between inputs and outputs, configurable transforms in between, and `start`/`stop` methods to control time-based animation execution.
The core workflow for creating an animation is to create an `Animated.Value`, hook it up to one or more style attributes of an animated component, and then drive updates via animations using `Animated.timing()`.
note
Don't modify the animated value directly. You can use the [`useRef` Hook](https://react.dev/reference/react/useRef) to return a mutable ref object. This ref object's `current` property is initialized as the given argument and persists throughout the component lifecycle.
## Example[](#example "Direct link to Example")
The following example contains a `View` which will fade in and fade out based on the animated value `fadeAnim`
Refer to the [Animations](/docs/animations.md#animated-api) guide to see additional examples of `Animated` in action.
## Overview[](#overview "Direct link to Overview")
There are two value types you can use with `Animated`:
* [`Animated.Value()`](/docs/animated.md#value) for single values
* [`Animated.ValueXY()`](/docs/animated.md#valuexy) for vectors
`Animated.Value` can bind to style properties or other props, and can be interpolated as well. A single `Animated.Value` can drive any number of properties.
### Configuring animations[](#configuring-animations "Direct link to Configuring animations")
`Animated` provides three types of animation types. Each animation type provides a particular animation curve that controls how your values animate from their initial value to the final value:
* [`Animated.decay()`](/docs/animated.md#decay) starts with an initial velocity and gradually slows to a stop.
* [`Animated.spring()`](/docs/animated.md#spring) provides a basic spring physics model.
* [`Animated.timing()`](/docs/animated.md#timing) animates a value over time using [easing functions](/docs/easing.md).
In most cases, you will be using `timing()`. By default, it uses a symmetric easeInOut curve that conveys the gradual acceleration of an object to full speed and concludes by gradually decelerating to a stop.
### Working with animations[](#working-with-animations "Direct link to Working with animations")
Animations are started by calling `start()` on your animation. `start()` takes a completion callback that will be called when the animation is done. If the animation finished running normally, the completion callback will be invoked with `{finished: true}`. If the animation is done because `stop()` was called on it before it could finish (e.g. because it was interrupted by a gesture or another animation), then it will receive `{finished: false}`.
tsx
```
Animated.timing({}).start(({finished}) => {
/* completion callback */
});
```
### Using the native driver[](#using-the-native-driver "Direct link to Using the native driver")
By using the native driver, we send everything about the animation to native before starting the animation, allowing native code to perform the animation on the UI thread without having to go through the bridge on every frame. Once the animation has started, the JS thread can be blocked without affecting the animation.
You can use the native driver by specifying `useNativeDriver: true` in your animation configuration. See the [Animations](/docs/animations.md#using-the-native-driver) guide to learn more.
### Animatable components[](#animatable-components "Direct link to Animatable components")
Only animatable components can be animated. These unique components do the magic of binding the animated values to the properties, and do targeted native updates to avoid the cost of the React render and reconciliation process on every frame. They also handle cleanup on unmount so they are safe by default.
* [`createAnimatedComponent()`](/docs/animated.md#createanimatedcomponent) can be used to make a component animatable.
`Animated` exports the following animatable components using the above wrapper:
* `Animated.Image`
* `Animated.ScrollView`
* `Animated.Text`
* `Animated.View`
* `Animated.FlatList`
* `Animated.SectionList`
### Composing animations[](#composing-animations "Direct link to Composing animations")
Animations can also be combined in complex ways using composition functions:
* [`Animated.delay()`](/docs/animated.md#delay) starts an animation after a given delay.
* [`Animated.parallel()`](/docs/animated.md#parallel) starts a number of animations at the same time.
* [`Animated.sequence()`](/docs/animated.md#sequence) starts the animations in order, waiting for each to complete before starting the next.
* [`Animated.stagger()`](/docs/animated.md#stagger) starts animations in order and in parallel, but with successive delays.
Animations can also be chained together by setting the `toValue` of one animation to be another `Animated.Value`. See [Tracking dynamic values](/docs/animations.md#tracking-dynamic-values) in the Animations guide.
By default, if one animation is stopped or interrupted, then all other animations in the group are also stopped.
### Combining animated values[](#combining-animated-values "Direct link to Combining animated values")
You can combine two animated values via addition, subtraction, multiplication, division, or modulo to make a new animated value:
* [`Animated.add()`](/docs/animated.md#add)
* [`Animated.subtract()`](/docs/animated.md#subtract)
* [`Animated.divide()`](/docs/animated.md#divide)
* [`Animated.modulo()`](/docs/animated.md#modulo)
* [`Animated.multiply()`](/docs/animated.md#multiply)
### Interpolation[](#interpolation "Direct link to Interpolation")
The `interpolate()` function allows input ranges to map to different output ranges. By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value. It uses linear interpolation by default but also supports easing functions.
* [`interpolate()`](/docs/animatedvalue.md#interpolate)
Read more about interpolation in the [Animation](/docs/animations.md#interpolation) guide.
### Handling gestures and other events[](#handling-gestures-and-other-events "Direct link to Handling gestures and other events")
Gestures, like panning or scrolling, and other events can map directly to animated values using `Animated.event()`. This is done with a structured map syntax so that values can be extracted from complex event objects. The first level is an array to allow mapping across multiple args, and that array contains nested objects.
* [`Animated.event()`](/docs/animated.md#event)
For example, when working with horizontal scrolling gestures, you would do the following in order to map `event.nativeEvent.contentOffset.x` to `scrollX` (an `Animated.Value`):
tsx
```
onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}
```
***
# Reference
## Methods[](#methods "Direct link to Methods")
When the given value is a ValueXY instead of a Value, each config option may be a vector of the form `{x: ..., y: ...}` instead of a scalar.
### `decay()`[](#decay "Direct link to decay")
tsx
```
static decay(value, config): CompositeAnimation;
```
Animates a value from an initial velocity to zero based on a decay coefficient.
Config is an object that may have the following options:
* `velocity`: Initial velocity. Required.
* `deceleration`: Rate of decay. Default 0.997.
* `isInteraction`: Whether or not this animation creates an "interaction handle" on the `InteractionManager`. Default true.
* `useNativeDriver`: Uses the native driver when true. Required.
***
### `timing()`[](#timing "Direct link to timing")
tsx
```
static timing(value, config): CompositeAnimation;
```
Animates a value along a timed easing curve. The [`Easing`](/docs/easing.md) module has tons of predefined curves, or you can use your own function.
Config is an object that may have the following options:
* `duration`: Length of animation (milliseconds). Default 500.
* `easing`: Easing function to define curve. Default is `Easing.inOut(Easing.ease)`.
* `delay`: Start the animation after delay (milliseconds). Default 0.
* `isInteraction`: Whether or not this animation creates an "interaction handle" on the `InteractionManager`. Default true.
* `useNativeDriver`: Uses the native driver when true. Required.
***
### `spring()`[](#spring "Direct link to spring")
tsx
```
static spring(value, config): CompositeAnimation;
```
Animates a value according to an analytical spring model based on [damped harmonic oscillation](https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator). Tracks velocity state to create fluid motions as the `toValue` updates, and can be chained together.
Config is an object that may have the following options.
Note that you can only define one of bounciness/speed, tension/friction, or stiffness/damping/mass, but not more than one:
The friction/tension or bounciness/speed options match the spring model in [`Facebook Pop`](https://github.com/facebook/pop), [Rebound](https://github.com/facebookarchive/rebound), and [Origami](https://origami.design/).
* `friction`: Controls "bounciness"/overshoot. Default 7.
* `tension`: Controls speed. Default 40.
* `speed`: Controls speed of the animation. Default 12.
* `bounciness`: Controls bounciness. Default 8.
Specifying stiffness/damping/mass as parameters makes `Animated.spring` use an analytical spring model based on the motion equations of a [damped harmonic oscillator](https://en.wikipedia.org/wiki/Harmonic_oscillator#Damped_harmonic_oscillator). This behavior is slightly more precise and faithful to the physics behind spring dynamics, and closely mimics the implementation in iOS's CASpringAnimation.
* `stiffness`: The spring stiffness coefficient. Default 100.
* `damping`: Defines how the spring’s motion should be damped due to the forces of friction. Default 10.
* `mass`: The mass of the object attached to the end of the spring. Default 1.
Other configuration options are as follows:
* `velocity`: The initial velocity of the object attached to the spring. Default 0 (object is at rest).
* `overshootClamping`: Boolean indicating whether the spring should be clamped and not bounce. Default false.
* `restDisplacementThreshold`: The threshold of displacement from rest below which the spring should be considered at rest. Default 0.001.
* `restSpeedThreshold`: The speed at which the spring should be considered at rest in pixels per second. Default 0.001.
* `delay`: Start the animation after delay (milliseconds). Default 0.
* `isInteraction`: Whether or not this animation creates an "interaction handle" on the `InteractionManager`. Default true.
* `useNativeDriver`: Uses the native driver when true. Required.
***
### `add()`[](#add "Direct link to add")
tsx
```
static add(a: Animated, b: Animated): AnimatedAddition;
```
Creates a new Animated value composed from two Animated values added together.
***
### `subtract()`[](#subtract "Direct link to subtract")
tsx
```
static subtract(a: Animated, b: Animated): AnimatedSubtraction;
```
Creates a new Animated value composed by subtracting the second Animated value from the first Animated value.
***
### `divide()`[](#divide "Direct link to divide")
tsx
```
static divide(a: Animated, b: Animated): AnimatedDivision;
```
Creates a new Animated value composed by dividing the first Animated value by the second Animated value.
***
### `multiply()`[](#multiply "Direct link to multiply")
tsx
```
static multiply(a: Animated, b: Animated): AnimatedMultiplication;
```
Creates a new Animated value composed from two Animated values multiplied together.
***
### `modulo()`[](#modulo "Direct link to modulo")
tsx
```
static modulo(a: Animated, modulus: number): AnimatedModulo;
```
Creates a new Animated value that is the (non-negative) modulo of the provided Animated value
***
### `diffClamp()`[](#diffclamp "Direct link to diffclamp")
tsx
```
static diffClamp(a: Animated, min: number, max: number): AnimatedDiffClamp;
```
Create a new Animated value that is limited between 2 values. It uses the difference between the last value so even if the value is far from the bounds it will start changing when the value starts getting closer again. (`value = clamp(value + diff, min, max)`).
This is useful with scroll events, for example, to show the navbar when scrolling up and to hide it when scrolling down.
***
### `delay()`[](#delay "Direct link to delay")
tsx
```
static delay(time: number): CompositeAnimation;
```
Starts an animation after the given delay.
***
### `sequence()`[](#sequence "Direct link to sequence")
tsx
```
static sequence(animations: CompositeAnimation[]): CompositeAnimation;
```
Starts an array of animations in order, waiting for each to complete before starting the next. If the current running animation is stopped, no following animations will be started.
***
### `parallel()`[](#parallel "Direct link to parallel")
tsx
```
static parallel(
animations: CompositeAnimation[],
config?: ParallelConfig
): CompositeAnimation;
```
Starts an array of animations all at the same time. By default, if one of the animations is stopped, they will all be stopped. You can override this with the `stopTogether` flag.
***
### `stagger()`[](#stagger "Direct link to stagger")
tsx
```
static stagger(
time: number,
animations: CompositeAnimation[]
): CompositeAnimation;
```
Array of animations may run in parallel (overlap), but are started in sequence with successive delays. Nice for doing trailing effects.
***
### `loop()`[](#loop "Direct link to loop")
tsx
```
static loop(
animation: CompositeAnimation[],
config?: LoopAnimationConfig
): CompositeAnimation;
```
Loops a given animation continuously, so that each time it reaches the end, it resets and begins again from the start. Will loop without blocking the JS thread if the child animation is set to `useNativeDriver: true`. In addition, loops can prevent `VirtualizedList`-based components from rendering more rows while the animation is running. You can pass `isInteraction: false` in the child animation config to fix this.
Config is an object that may have the following options:
* `iterations`: Number of times the animation should loop. Default `-1` (infinite).
***
### `event()`[](#event "Direct link to event")
tsx
```
static event(
argMapping: Mapping[],
config?: EventConfig
): (...args: any[]) => void;
```
Takes an array of mappings and extracts values from each arg accordingly, then calls `setValue` on the mapped outputs. e.g.
tsx
```
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {x: this._scrollX}}}],
{listener: (event: ScrollEvent) => console.log(event)}, // Optional async listener
)}
...
onPanResponderMove: Animated.event(
[
null, // raw event arg ignored
{dx: this._panX},
], // gestureState arg
{
listener: (
event: GestureResponderEvent,
gestureState: PanResponderGestureState
) => console.log(event, gestureState),
} // Optional async listener
);
```
Config is an object that may have the following options:
* `listener`: Optional async listener.
* `useNativeDriver`: Uses the native driver when true. Required.
***
### `forkEvent()`[](#forkevent "Direct link to forkevent")
jsx
```
static forkEvent(event: AnimatedEvent, listener: Function): AnimatedEvent;
```
Advanced imperative API for snooping on animated events that are passed in through props. It permits to add a new javascript listener to an existing `AnimatedEvent`. If `animatedEvent` is a javascript listener, it will merge the 2 listeners into a single one, and if `animatedEvent` is null/undefined, it will assign the javascript listener directly. Use values directly where possible.
***
### `unforkEvent()`[](#unforkevent "Direct link to unforkevent")
jsx
```
static unforkEvent(event: AnimatedEvent, listener: Function);
```
***
### `start()`[](#start "Direct link to start")
tsx
```
static start(callback?: (result: {finished: boolean}) => void);
```
Animations are started by calling start() on your animation. start() takes a completion callback that will be called when the animation is done or when the animation is done because stop() was called on it before it could finish.
**Parameters:**
| Name | Type | Required | Description |
| -------- | --------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| callback | `(result: {finished: boolean}) => void` | No | Function that will be called after the animation finished running normally or when the animation is done because stop() was called on it before it could finish |
Start example with callback:
tsx
```
Animated.timing({}).start(({finished}) => {
/* completion callback */
});
```
***
### `stop()`[](#stop "Direct link to stop")
tsx
```
static stop();
```
Stops any running animation.
***
### `reset()`[](#reset "Direct link to reset")
tsx
```
static reset();
```
Stops any running animation and resets the value to its original.
## Properties[](#properties "Direct link to Properties")
### `Value`[](#value "Direct link to value")
Standard value class for driving animations. Typically initialized with `useAnimatedValue(0);` or `new Animated.Value(0);` in class components.
You can read more about `Animated.Value` API on the separate [page](/docs/animatedvalue.md).
***
### `ValueXY`[](#valuexy "Direct link to valuexy")
2D value class for driving 2D animations, such as pan gestures.
You can read more about `Animated.ValueXY` API on the separate [page](/docs/animatedvaluexy.md).
***
### `Interpolation`[](#interpolation-1 "Direct link to interpolation-1")
Exported to use the Interpolation type in flow.
***
### `Node`[](#node "Direct link to node")
Exported for ease of type checking. All animated values derive from this class.
***
### `createAnimatedComponent`[](#createanimatedcomponent "Direct link to createanimatedcomponent")
Make any React component Animatable. Used to create `Animated.View`, etc.
***
### `attachNativeEvent`[](#attachnativeevent "Direct link to attachnativeevent")
Imperative API to attach an animated value to an event on a view. Prefer using `Animated.event` with `useNativeDriver: true` if possible.
---
# Source: https://reactnative.dev/docs/animatedvalue.md
# Animated.Value
Standard value for driving animations. One `Animated.Value` can drive multiple properties in a synchronized fashion, but can only be driven by one mechanism at a time. Using a new mechanism (e.g. starting a new animation, or calling `setValue`) will stop any previous ones.
Typically initialized with `useAnimatedValue(0);` or `new Animated.Value(0);` in class components.
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `setValue()`[](#setvalue "Direct link to setvalue")
tsx
```
setValue(value: number);
```
Directly set the value. This will stop any animations running on the value and update all the bound properties.
**Parameters:**
| Name | Type | Required | Description |
| ----- | ------ | -------- | ----------- |
| value | number | Yes | Value |
***
### `setOffset()`[](#setoffset "Direct link to setoffset")
tsx
```
setOffset(offset: number);
```
Sets an offset that is applied on top of whatever value is set, whether via `setValue`, an animation, or `Animated.event`. Useful for compensating things like the start of a pan gesture.
**Parameters:**
| Name | Type | Required | Description |
| ------ | ------ | -------- | ------------ |
| offset | number | Yes | Offset value |
***
### `flattenOffset()`[](#flattenoffset "Direct link to flattenoffset")
tsx
```
flattenOffset();
```
Merges the offset value into the base value and resets the offset to zero. The final output of the value is unchanged.
***
### `extractOffset()`[](#extractoffset "Direct link to extractoffset")
tsx
```
extractOffset();
```
Sets the offset value to the base value, and resets the base value to zero. The final output of the value is unchanged.
***
### `addListener()`[](#addlistener "Direct link to addlistener")
tsx
```
addListener(callback: (state: {value: number}) => void): string;
```
Adds an asynchronous listener to the value so you can observe updates from animations. This is useful because there is no way to synchronously read the value because it might be driven natively.
Returns a string that serves as an identifier for the listener.
**Parameters:**
| Name | Type | Required | Description |
| -------- | -------- | -------- | ------------------------------------------------------------------------------------------- |
| callback | function | Yes | The callback function which will receive an object with a `value` key set to the new value. |
***
### `removeListener()`[](#removelistener "Direct link to removelistener")
tsx
```
removeListener(id: string);
```
Unregister a listener. The `id` param shall match the identifier previously returned by `addListener()`.
**Parameters:**
| Name | Type | Required | Description |
| ---- | ------ | -------- | ---------------------------------- |
| id | string | Yes | Id for the listener being removed. |
***
### `removeAllListeners()`[](#removealllisteners "Direct link to removealllisteners")
tsx
```
removeAllListeners();
```
Remove all registered listeners.
***
### `stopAnimation()`[](#stopanimation "Direct link to stopanimation")
tsx
```
stopAnimation(callback?: (value: number) => void);
```
Stops any running animation or tracking. `callback` is invoked with the final value after stopping the animation, which is useful for updating state to match the animation position with layout.
**Parameters:**
| Name | Type | Required | Description |
| -------- | -------- | -------- | --------------------------------------------- |
| callback | function | No | A function that will receive the final value. |
***
### `resetAnimation()`[](#resetanimation "Direct link to resetanimation")
tsx
```
resetAnimation(callback?: (value: number) => void);
```
Stops any animation and resets the value to its original.
**Parameters:**
| Name | Type | Required | Description |
| -------- | -------- | -------- | ------------------------------------------------ |
| callback | function | No | A function that will receive the original value. |
***
### `interpolate()`[](#interpolate "Direct link to interpolate")
tsx
```
interpolate(config: InterpolationConfigType);
```
Interpolates the value before updating the property, e.g. mapping 0-1 to 0-10.
See `AnimatedInterpolation.js`
**Parameters:**
| Name | Type | Required | Description |
| ------ | ------ | -------- | ----------- |
| config | object | Yes | See below. |
The `config` object is composed of the following keys:
* `inputRange`: an array of numbers
* `outputRange`: an array of numbers or strings
* `easing` (optional): a function that returns a number, given an input number
* `extrapolate` (optional): a string such as 'extend', 'identity', or 'clamp'
* `extrapolateLeft` (optional): a string such as 'extend', 'identity', or 'clamp'
* `extrapolateRight` (optional): a string such as 'extend', 'identity', or 'clamp'
***
### `animate()`[](#animate "Direct link to animate")
tsx
```
animate(animation, callback);
```
Typically only used internally, but could be used by a custom Animation class.
**Parameters:**
| Name | Type | Required | Description |
| --------- | --------- | -------- | ------------------- |
| animation | Animation | Yes | See `Animation.js`. |
| callback | function | Yes | Callback function. |
---
# Source: https://reactnative.dev/docs/animatedvaluexy.md
# Animated.ValueXY
2D Value for driving 2D animations, such as pan gestures. Almost identical API to normal [`Animated.Value`](/docs/animatedvalue.md), but multiplexed. Contains two regular `Animated.Value`s under the hood.
## Example[](#example "Direct link to Example")
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `setValue()`[](#setvalue "Direct link to setvalue")
tsx
```
setValue(value: {x: number; y: number});
```
Directly set the value. This will stop any animations running on the value and update all the bound properties.
**Parameters:**
| Name | Type | Required | Description |
| ----- | ------------------------ | -------- | ----------- |
| value | `{x: number; y: number}` | Yes | Value |
***
### `setOffset()`[](#setoffset "Direct link to setoffset")
tsx
```
setOffset(offset: {x: number; y: number});
```
Sets an offset that is applied on top of whatever value is set, whether via `setValue`, an animation, or `Animated.event`. Useful for compensating things like the start of a pan gesture.
**Parameters:**
| Name | Type | Required | Description |
| ------ | ------------------------ | -------- | ------------ |
| offset | `{x: number; y: number}` | Yes | Offset value |
***
### `flattenOffset()`[](#flattenoffset "Direct link to flattenoffset")
tsx
```
flattenOffset();
```
Merges the offset value into the base value and resets the offset to zero. The final output of the value is unchanged.
***
### `extractOffset()`[](#extractoffset "Direct link to extractoffset")
tsx
```
extractOffset();
```
Sets the offset value to the base value, and resets the base value to zero. The final output of the value is unchanged.
***
### `addListener()`[](#addlistener "Direct link to addlistener")
tsx
```
addListener(callback: (value: {x: number; y: number}) => void);
```
Adds an asynchronous listener to the value so you can observe updates from animations. This is useful because there is no way to synchronously read the value because it might be driven natively.
Returns a string that serves as an identifier for the listener.
**Parameters:**
| Name | Type | Required | Description |
| -------- | -------- | -------- | ------------------------------------------------------------------------------------------- |
| callback | function | Yes | The callback function which will receive an object with a `value` key set to the new value. |
***
### `removeListener()`[](#removelistener "Direct link to removelistener")
tsx
```
removeListener(id: string);
```
Unregister a listener. The `id` param shall match the identifier previously returned by `addListener()`.
**Parameters:**
| Name | Type | Required | Description |
| ---- | ------ | -------- | ---------------------------------- |
| id | string | Yes | Id for the listener being removed. |
***
### `removeAllListeners()`[](#removealllisteners "Direct link to removealllisteners")
tsx
```
removeAllListeners();
```
Remove all registered listeners.
***
### `stopAnimation()`[](#stopanimation "Direct link to stopanimation")
tsx
```
stopAnimation(callback?: (value: {x: number; y: number}) => void);
```
Stops any running animation or tracking. `callback` is invoked with the final value after stopping the animation, which is useful for updating state to match the animation position with layout.
**Parameters:**
| Name | Type | Required | Description |
| -------- | -------- | -------- | --------------------------------------------- |
| callback | function | No | A function that will receive the final value. |
***
### `resetAnimation()`[](#resetanimation "Direct link to resetanimation")
tsx
```
resetAnimation(callback?: (value: {x: number; y: number}) => void);
```
Stops any animation and resets the value to its original.
**Parameters:**
| Name | Type | Required | Description |
| -------- | -------- | -------- | ------------------------------------------------ |
| callback | function | No | A function that will receive the original value. |
***
### `getLayout()`[](#getlayout "Direct link to getlayout")
tsx
```
getLayout(): {left: Animated.Value, top: Animated.Value};
```
Converts `{x, y}` into `{left, top}` for use in style, e.g.
tsx
```
style={this.state.anim.getLayout()}
```
***
### `getTranslateTransform()`[](#gettranslatetransform "Direct link to gettranslatetransform")
tsx
```
getTranslateTransform(): [
{translateX: Animated.Value},
{translateY: Animated.Value},
];
```
Converts `{x, y}` into a useable translation transform, e.g.
tsx
```
style={{
transform: this.state.anim.getTranslateTransform()
}}
```
---
# Source: https://reactnative.dev/docs/animations.md
# Animations
Animations are very important to create a great user experience. Stationary objects must overcome inertia as they start moving. Objects in motion have momentum and rarely come to a stop immediately. Animations allow you to convey physically believable motion in your interface.
React Native provides two complementary animation systems: [`Animated`](/docs/animations.md#animated-api) for granular and interactive control of specific values, and [`LayoutAnimation`](/docs/animations.md#layoutanimation-api) for animated global layout transactions.
## `Animated` API[](#animated-api "Direct link to animated-api")
The [`Animated`](/docs/animated.md) API is designed to concisely express a wide variety of interesting animation and interaction patterns in a very performant way. `Animated` focuses on declarative relationships between inputs and outputs, with configurable transforms in between, and `start`/`stop` methods to control time-based animation execution.
`Animated` exports six animatable component types: `View`, `Text`, `Image`, `ScrollView`, `FlatList` and `SectionList`, but you can also create your own using `Animated.createAnimatedComponent()`.
For example, a container view that fades in when it is mounted may look like this:
* TypeScript
* JavaScript
Let's break down what's happening here. In the `FadeInView` render method, a new `Animated.Value` called `fadeAnim` is initialized with `useRef`. The opacity property on the `View` is mapped to this animated value. Behind the scenes, the numeric value is extracted and used to set opacity.
When the component mounts, the opacity is set to 0. Then, an easing animation is started on the `fadeAnim` animated value, which will update all of its dependent mappings (in this case, only the opacity) on each frame as the value animates to the final value of 1.
This is done in an optimized way that is faster than calling `setState` and re-rendering. Because the entire configuration is declarative, we will be able to implement further optimizations that serialize the configuration and runs the animation on a high-priority thread.
### Configuring animations[](#configuring-animations "Direct link to Configuring animations")
Animations are heavily configurable. Custom and predefined easing functions, delays, durations, decay factors, spring constants, and more can all be tweaked depending on the type of animation.
`Animated` provides several animation types, the most commonly used one being [`Animated.timing()`](/docs/animated.md#timing). It supports animating a value over time using one of various predefined easing functions, or you can use your own. Easing functions are typically used in animation to convey gradual acceleration and deceleration of objects.
By default, `timing` will use an easeInOut curve that conveys gradual acceleration to full speed and concludes by gradually decelerating to a stop. You can specify a different easing function by passing an `easing` parameter. Custom `duration` or even a `delay` before the animation starts is also supported.
For example, if we want to create a 2-second long animation of an object that slightly backs up before moving to its final position:
tsx
```
Animated.timing(this.state.xPosition, {
toValue: 100,
easing: Easing.back(),
duration: 2000,
useNativeDriver: true,
}).start();
```
Take a look at the [Configuring animations](/docs/animated.md#configuring-animations) section of the `Animated` API reference to learn more about all the config parameters supported by the built-in animations.
### Composing animations[](#composing-animations "Direct link to Composing animations")
Animations can be combined and played in sequence or in parallel. Sequential animations can play immediately after the previous animation has finished, or they can start after a specified delay. The `Animated` API provides several methods, such as `sequence()` and `delay()`, each of which take an array of animations to execute and automatically calls `start()`/`stop()` as needed.
For example, the following animation coasts to a stop, then it springs back while twirling in parallel:
tsx
```
Animated.sequence([
// decay, then spring to start and twirl
Animated.decay(position, {
// coast to a stop
velocity: {x: gestureState.vx, y: gestureState.vy}, // velocity from gesture release
deceleration: 0.997,
useNativeDriver: true,
}),
Animated.parallel([
// after decay, in parallel:
Animated.spring(position, {
toValue: {x: 0, y: 0}, // return to start
useNativeDriver: true,
}),
Animated.timing(twirl, {
// and twirl
toValue: 360,
useNativeDriver: true,
}),
]),
]).start(); // start the sequence group
```
If one animation is stopped or interrupted, then all other animations in the group are also stopped. `Animated.parallel` has a `stopTogether` option that can be set to `false` to disable this.
You can find a full list of composition methods in the [Composing animations](/docs/animated.md#composing-animations) section of the `Animated` API reference.
### Combining animated values[](#combining-animated-values "Direct link to Combining animated values")
You can [combine two animated values](/docs/animated.md#combining-animated-values) via addition, multiplication, division, or modulo to make a new animated value.
There are some cases where an animated value needs to invert another animated value for calculation. An example is inverting a scale (2x --> 0.5x):
tsx
```
const a = new Animated.Value(1);
const b = Animated.divide(1, a);
Animated.spring(a, {
toValue: 2,
useNativeDriver: true,
}).start();
```
### Interpolation[](#interpolation "Direct link to Interpolation")
Each property can be run through an interpolation first. An interpolation maps input ranges to output ranges, typically using a linear interpolation but also supports easing functions. By default, it will extrapolate the curve beyond the ranges given, but you can also have it clamp the output value.
A basic mapping to convert a 0-1 range to a 0-100 range would be:
tsx
```
value.interpolate({
inputRange: [0, 1],
outputRange: [0, 100],
});
```
For example, you may want to think about your `Animated.Value` as going from 0 to 1, but animate the position from 150px to 0px and the opacity from 0 to 1. This can be done by modifying `style` from the example above like so:
tsx
```
style={{
opacity: this.state.fadeAnim, // Binds directly
transform: [{
translateY: this.state.fadeAnim.interpolate({
inputRange: [0, 1],
outputRange: [150, 0] // 0 : 150, 0.5 : 75, 1 : 0
}),
}],
}}
```
[`interpolate()`](/docs/animated.md#interpolate) supports multiple range segments as well, which is handy for defining dead zones and other handy tricks. For example, to get a negation relationship at -300 that goes to 0 at -100, then back up to 1 at 0, and then back down to zero at 100 followed by a dead-zone that remains at 0 for everything beyond that, you could do:
tsx
```
value.interpolate({
inputRange: [-300, -100, 0, 100, 101],
outputRange: [300, 0, 1, 0, 0],
});
```
Which would map like so:
```
Input | Output
------|-------
-400| 450
-300| 300
-200| 150
-100| 0
-50| 0.5
0| 1
50| 0.5
100| 0
101| 0
200| 0
```
`interpolate()` also supports mapping to strings, allowing you to animate colors as well as values with units. For example, if you wanted to animate a rotation you could do:
tsx
```
value.interpolate({
inputRange: [0, 360],
outputRange: ['0deg', '360deg'],
});
```
`interpolate()` also supports arbitrary easing functions, many of which are already implemented in the [`Easing`](/docs/easing.md) module. `interpolate()` also has configurable behavior for extrapolating the `outputRange`. You can set the extrapolation by setting the `extrapolate`, `extrapolateLeft`, or `extrapolateRight` options. The default value is `extend` but you can use `clamp` to prevent the output value from exceeding `outputRange`.
### Tracking dynamic values[](#tracking-dynamic-values "Direct link to Tracking dynamic values")
Animated values can also track other values by setting the `toValue` of an animation to another animated value instead of a plain number. For example, a "Chat Heads" animation like the one used by Messenger on Android could be implemented with a `spring()` pinned on another animated value, or with `timing()` and a `duration` of 0 for rigid tracking. They can also be composed with interpolations:
tsx
```
Animated.spring(follower, {toValue: leader}).start();
Animated.timing(opacity, {
toValue: pan.x.interpolate({
inputRange: [0, 300],
outputRange: [1, 0],
}),
useNativeDriver: true,
}).start();
```
The `leader` and `follower` animated values would be implemented using `Animated.ValueXY()`. `ValueXY` is a handy way to deal with 2D interactions, such as panning or dragging. It is a basic wrapper that contains two `Animated.Value` instances and some helper functions that call through to them, making `ValueXY` a drop-in replacement for `Value` in many cases. It allows us to track both x and y values in the example above.
### Tracking gestures[](#tracking-gestures "Direct link to Tracking gestures")
Gestures, like panning or scrolling, and other events can map directly to animated values using [`Animated.event`](/docs/animated.md#event). This is done with a structured map syntax so that values can be extracted from complex event objects. The first level is an array to allow mapping across multiple args, and that array contains nested objects.
For example, when working with horizontal scrolling gestures, you would do the following in order to map `event.nativeEvent.contentOffset.x` to `scrollX` (an `Animated.Value`):
tsx
```
onScroll={Animated.event(
// scrollX = e.nativeEvent.contentOffset.x
[{nativeEvent: {
contentOffset: {
x: scrollX
}
}
}]
)}
```
The following example implements a horizontal scrolling carousel where the scroll position indicators are animated using the `Animated.event` used in the `ScrollView`
#### ScrollView with Animated Event Example[](#scrollview-with-animated-event-example "Direct link to ScrollView with Animated Event Example")
When using `PanResponder`, you could use the following code to extract the x and y positions from `gestureState.dx` and `gestureState.dy`. We use a `null` in the first position of the array, as we are only interested in the second argument passed to the `PanResponder` handler, which is the `gestureState`.
tsx
```
onPanResponderMove={Animated.event(
[null, // ignore the native event
// extract dx and dy from gestureState
// like 'pan.x = gestureState.dx, pan.y = gestureState.dy'
{dx: pan.x, dy: pan.y}
])}
```
#### PanResponder with Animated Event Example[](#panresponder-with-animated-event-example "Direct link to PanResponder with Animated Event Example")
### Responding to the current animation value[](#responding-to-the-current-animation-value "Direct link to Responding to the current animation value")
You may notice that there is no clear way to read the current value while animating. This is because the value may only be known in the native runtime due to optimizations. If you need to run JavaScript in response to the current value, there are two approaches:
* `spring.stopAnimation(callback)` will stop the animation and invoke `callback` with the final value. This is useful when making gesture transitions.
* `spring.addListener(callback)` will invoke `callback` asynchronously while the animation is running, providing a recent value. This is useful for triggering state changes, for example snapping a bobble to a new option as the user drags it closer, because these larger state changes are less sensitive to a few frames of lag compared to continuous gestures like panning which need to run at 60 fps.
`Animated` is designed to be fully serializable so that animations can be run in a high performance way, independent of the normal JavaScript event loop. This does influence the API, so keep that in mind when it seems a little trickier to do something compared to a fully synchronous system. Check out `Animated.Value.addListener` as a way to work around some of these limitations, but use it sparingly since it might have performance implications in the future.
### Using the native driver[](#using-the-native-driver "Direct link to Using the native driver")
The `Animated` API is designed to be serializable. By using the [native driver](/blog/2017/02/14/using-native-driver-for-animated), we send everything about the animation to native before starting the animation, allowing native code to perform the animation on the UI thread without having to go through the bridge on every frame. Once the animation has started, the JS thread can be blocked without affecting the animation.
Using the native driver for normal animations can be accomplished by setting `useNativeDriver: true` in animation config when starting it. Animations without a `useNativeDriver` property will default to false for legacy reasons, but emit a warning (and typechecking error in TypeScript).
tsx
```
Animated.timing(this.state.animatedValue, {
toValue: 1,
duration: 500,
useNativeDriver: true, // <-- Set this to true
}).start();
```
Animated values are only compatible with one driver so if you use native driver when starting an animation on a value, make sure every animation on that value also uses the native driver.
The native driver also works with `Animated.event`. This is especially useful for animations that follow the scroll position as without the native driver, the animation will always run a frame behind the gesture due to the async nature of React Native.
tsx
```
{content}
```
You can see the native driver in action by running the [RNTester app](https://github.com/facebook/react-native/blob/main/packages/rn-tester/), then loading the Native Animated Example. You can also take a look at the [source code](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/NativeAnimation/NativeAnimationsExample.js) to learn how these examples were produced.
#### Caveats[](#caveats "Direct link to Caveats")
Not everything you can do with `Animated` is currently supported by the native driver. The main limitation is that you can only animate non-layout properties: things like `transform` and `opacity` will work, but Flexbox and position properties will not. When using `Animated.event`, it will only work with direct events and not bubbling events. This means it does not work with `PanResponder` but does work with things like `ScrollView#onScroll`.
When an animation is running, it can prevent `VirtualizedList` components from rendering more rows. If you need to run a long or looping animation while the user is scrolling through a list, you can use `isInteraction: false` in your animation's config to prevent this issue.
### Bear in mind[](#bear-in-mind "Direct link to Bear in mind")
While using transform styles such as `rotateY`, `rotateX`, and others ensure the transform style `perspective` is in place. At this time some animations may not render on Android without it. Example below.
tsx
```
```
### Additional examples[](#additional-examples "Direct link to Additional examples")
The RNTester app has various examples of `Animated` in use:
* [AnimatedGratuitousApp](https://github.com/facebook/react-native/tree/main/packages/rn-tester/js/examples/AnimatedGratuitousApp)
* [NativeAnimationsExample](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/NativeAnimation/NativeAnimationsExample.js)
## `LayoutAnimation` API[](#layoutanimation-api "Direct link to layoutanimation-api")
`LayoutAnimation` allows you to globally configure `create` and `update` animations that will be used for all views in the next render/layout cycle. This is useful for doing Flexbox layout updates without bothering to measure or calculate specific properties in order to animate them directly, and is especially useful when layout changes may affect ancestors, for example a "see more" expansion that also increases the size of the parent and pushes down the row below which would otherwise require explicit coordination between the components in order to animate them all in sync.
Note that although `LayoutAnimation` is very powerful and can be quite useful, it provides much less control than `Animated` and other animation libraries, so you may need to use another approach if you can't get `LayoutAnimation` to do what you want.
Note that in order to get this to work on **Android** you need to set the following flags via `UIManager`:
tsx
```
UIManager.setLayoutAnimationEnabledExperimental(true);
```
This example uses a preset value, you can customize the animations as you need, see [LayoutAnimation.js](https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/LayoutAnimation/LayoutAnimation.js) for more information.
## Additional notes[](#additional-notes "Direct link to Additional notes")
### `requestAnimationFrame`[](#requestanimationframe "Direct link to requestanimationframe")
`requestAnimationFrame` is a polyfill from the browser that you might be familiar with. It accepts a function as its only argument and calls that function before the next repaint. It is an essential building block for animations that underlies all of the JavaScript-based animation APIs. In general, you shouldn't need to call this yourself - the animation APIs will manage frame updates for you.
### `setNativeProps`[](#setnativeprops "Direct link to setnativeprops")
As mentioned [in the Direct Manipulation section](/docs/legacy/direct-manipulation.md), `setNativeProps` allows us to modify properties of native-backed components (components that are actually backed by native views, unlike composite components) directly, without having to `setState` and re-render the component hierarchy.
We could use this in the Rebound example to update the scale - this might be helpful if the component that we are updating is deeply nested and hasn't been optimized with `shouldComponentUpdate`.
If you find your animations with dropping frames (performing below 60 frames per second), look into using `setNativeProps` or `shouldComponentUpdate` to optimize them. Or you could run the animations on the UI thread rather than the JavaScript thread [with the useNativeDriver option](/blog/2017/02/14/using-native-driver-for-animated). You may also want to defer any computationally intensive work until after animations are complete, using the [InteractionManager](/docs/interactionmanager.md). You can monitor the frame rate by using the In-App Dev Menu "FPS Monitor" tool.
---
# Source: https://reactnative.dev/docs/app-extensions.md
# App Extensions
App extensions let you provide custom functionality and content outside of your main app. There are different types of app extensions on iOS, and they are all covered in the [App Extension Programming Guide](https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/index.html#//apple_ref/doc/uid/TP40014214-CH20-SW1). In this guide, we'll briefly cover how you may take advantage of app extensions on iOS.
## Memory use in extensions[](#memory-use-in-extensions "Direct link to Memory use in extensions")
As these extensions are loaded outside of the regular app sandbox, it's highly likely that several of these app extensions will be loaded simultaneously. As you might expect, these extensions have small memory usage limits. Keep these in mind when developing your app extensions. It's always highly recommended to test your application on an actual device, and more so when developing app extensions: too frequently, developers find that their extension works fine in the iOS Simulator, only to get user reports that their extension is not loading on actual devices.
### Today widget[](#today-widget "Direct link to Today widget")
The memory limit of a Today widget is 16 MB. As it happens, Today widget implementations using React Native may work unreliably because the memory usage tends to be too high. You can tell if your Today widget is exceeding the memory limit if it yields the message 'Unable to Load':

Always make sure to test your app extensions in a real device, but be aware that this may not be sufficient, especially when dealing with Today widgets. Debug-configured builds are more likely to exceed the memory limits, while release-configured builds don't fail right away. We highly recommend that you use [Xcode's Instruments](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/index.html) to analyze your real world memory usage, as it's very likely that your release-configured build is very close to the 16 MB limit. In situations like these, you can quickly go over the 16 MB limit by performing common operations, such as fetching data from an API.
To experiment with the limits of React Native Today widget implementations, try extending the example project in [react-native-today-widget](https://github.com/matejkriz/react-native-today-widget/).
### Other app extensions[](#other-app-extensions "Direct link to Other app extensions")
Other types of app extensions have greater memory limits than the Today widget. For instance, Custom Keyboard extensions are limited to 48 MB, and Share extensions are limited to 120 MB. Implementing such app extensions with React Native is more viable. One proof of concept example is [react-native-ios-share-extension](https://github.com/andrewsardone/react-native-ios-share-extension).
---
# Source: https://reactnative.dev/docs/appearance.md
# Appearance
tsx
```
import {Appearance} from 'react-native';
```
The `Appearance` module exposes information about the user's appearance preferences, such as their preferred color scheme (light or dark).
#### Developer notes[](#developer-notes "Direct link to Developer notes")
* Android
* iOS
* Web
info
The `Appearance` API is inspired by the [Media Queries draft](https://drafts.csswg.org/mediaqueries-5/) from the W3C. The color scheme preference is modeled after the [`prefers-color-scheme` CSS media feature](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme).
info
The color scheme preference will map to the user's Light or [Dark theme](https://developer.android.com/guide/topics/ui/look-and-feel/darktheme) preference on Android 10 (API level 29) devices and higher.
info
The color scheme preference will map to the user's Light or [Dark Mode](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/dark-mode/) preference on iOS 13 devices and higher.
note
When taking a screenshot, by default, the color scheme may flicker between light and dark mode. It happens because the iOS takes snapshots on both color schemes and updating the user interface with color scheme is asynchronous.
## Example[](#example "Direct link to Example")
You can use the `Appearance` module to determine if the user prefers a dark color scheme:
tsx
```
const colorScheme = Appearance.getColorScheme();
if (colorScheme === 'dark') {
// Use dark color scheme
}
```
Although the color scheme is available immediately, this may change (e.g. scheduled color scheme change at sunrise or sunset). Any rendering logic or styles that depend on the user preferred color scheme should try to call this function on every render, rather than caching the value. For example, you may use the [`useColorScheme`](/docs/usecolorscheme.md) React hook as it provides and subscribes to color scheme updates, or you may use inline styles rather than setting a value in a `StyleSheet`.
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `getColorScheme()`[](#getcolorscheme "Direct link to getcolorscheme")
tsx
```
static getColorScheme(): 'light' | 'dark' | null;
```
Indicates the current user preferred color scheme. The value may be updated later, either through direct user action (e.g. theme selection in device settings or application-level selected user interface style via `setColorScheme`) or on a schedule (e.g. light and dark themes that follow the day/night cycle).
Supported color schemes:
* `'light'`: The user prefers a light color theme.
* `'dark'`: The user prefers a dark color theme.
* `null`: The user has not indicated a preferred color theme.
See also: `useColorScheme` hook.
note
`getColorScheme()` will always return `light` when debugging with Chrome.
***
### `setColorScheme()`[](#setcolorscheme "Direct link to setcolorscheme")
tsx
```
static setColorScheme('light' | 'dark' | null): void;
```
Force the application to always adopt a light or dark interface style. The default value is `null` which causes the application to inherit the system's interface style. If you assign a different value, the new style applies to the application and all native elements within the application (Alerts, Pickers etc).
Supported color schemes:
* `light`: Apply light user interface style.
* `dark`: Apply dark user interface style.
* null: Follow the system's interface style.
note
The change will not affect the system's selected interface style or any style set in other applications.
***
### `addChangeListener()`[](#addchangelistener "Direct link to addchangelistener")
tsx
```
static addChangeListener(
listener: (preferences: {colorScheme: 'light' | 'dark' | null}) => void,
): NativeEventSubscription;
```
Add an event handler that is fired when appearance preferences change.
---
# Source: https://reactnative.dev/docs/appendix.md
# Appendix
## I. Terminology[](#i-terminology "Direct link to I. Terminology")
* **Spec** - TypeScript or Flow code that describes the API for a Turbo Native Module or Fabric Native component. Used by **Codegen** to generate boilerplate code.
* **Native Modules** - Native libraries that have no User Interface (UI) for the user. Examples would be persistent storage, notifications, network events. These are accessible to your JavaScript application code as functions and objects.
* **Native Component** - Native platform views that are available to your application JavaScript code through React Components.
* **Legacy Native Components** - Components which are running on the old React Native architecture.
* **Legacy Native Modules** - Modules which are running on the old React Native architecture.
## II. Codegen Typings[](#ii-codegen-typings "Direct link to II. Codegen Typings")
You may use the following table as a reference for which types are supported and what they map to in each platform:
| Flow | TypeScript | Flow Nullable Support | TypeScript Nullable Support | Android (Java) | iOS (ObjC) |
| --------------------------------------------- | ------------------------------------ | -------------------------- | ------------------------------- | ------------------------------------ | -------------------------------------------------------------- |
| `string` | `string` | `?string` | `string \| null` | `string` | `NSString` |
| `boolean` | `boolean` | `?boolean` | `boolean \| null` | `Boolean` | `NSNumber` |
| Object Literal `{\| foo: string, ...\|}` | `{ foo: string, ...} as const` | `?{\| foo: string, ...\|}` | `?{ foo: string, ...} as const` | - | - |
| Object \[[1](#notes)] | Object \[[1](#notes)] | `?Object` | `Object \| null` | `ReadableMap` | `@` (untyped dictionary) |
| `Array` | `Array` | `?Array` | `Array \| null` | `ReadableArray` | `NSArray` (or `RCTConvertVecToArray` when used inside objects) |
| `Function` | `Function` | `?Function` | `Function \| null` | - | - |
| `Promise` | `Promise` | `?Promise` | `Promise \| null` | `com.facebook.react.bridge.Promise` | `RCTPromiseResolve` and `RCTPromiseRejectBlock` |
| Type Unions `'SUCCESS'\|'FAIL'` | Type Unions `'SUCCESS'\|'FAIL'` | Only as callbacks | | - | - |
| Callbacks `() =>` | Callbacks `() =>` | Yes | | `com.facebook.react.bridge.Callback` | `RCTResponseSenderBlock` |
| `number` | `number` | No | | `double` | `NSNumber` |
### Notes:[](#notes "Direct link to Notes:")
**\[1]** We strongly recommend using Object literals instead of Objects.
info
You may also find it useful to refer to the JavaScript specifications for the core modules in React Native. These are located inside the `Libraries/` directory in the React Native repository.
---
# Source: https://reactnative.dev/docs/appregistry.md
# AppRegistry
### Project with Native Code Required
If you are using the managed Expo workflow there is only ever one entry component registered with `AppRegistry` and it is handled automatically (or through [registerRootComponent](https://docs.expo.dev/versions/latest/sdk/register-root-component/)). You do not need to use this API.
`AppRegistry` is the JS entry point to running all React Native apps. App root components should register themselves with `AppRegistry.registerComponent`, then the native system can load the bundle for the app and then actually run the app when it's ready by invoking `AppRegistry.runApplication`.
tsx
```
import {Text, AppRegistry} from 'react-native';
const App = () => (
App1
);
AppRegistry.registerComponent('Appname', () => App);
```
To "stop" an application when a view should be destroyed, call `AppRegistry.unmountApplicationComponentAtRootTag` with the tag that was passed into `runApplication`. These should always be used as a pair.
`AppRegistry` should be required early in the `require` sequence to make sure the JS execution environment is setup before other modules are required.
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `getAppKeys()`[](#getappkeys "Direct link to getappkeys")
tsx
```
static getAppKeys(): string[];
```
Returns an array of strings.
***
### `getRegistry()`[](#getregistry "Direct link to getregistry")
tsx
```
static getRegistry(): {sections: string[]; runnables: Runnable[]};
```
Returns a [Registry](/docs/appregistry.md#registry) object.
***
### `getRunnable()`[](#getrunnable "Direct link to getrunnable")
tsx
```
static getRunnable(appKey: string): : Runnable | undefined;
```
Returns a [Runnable](/docs/appregistry.md#runnable) object.
**Parameters:**
| Name | Type |
| -------------- | ------ |
| appKeyRequired | string |
***
### `getSectionKeys()`[](#getsectionkeys "Direct link to getsectionkeys")
tsx
```
static getSectionKeys(): string[];
```
Returns an array of strings.
***
### `getSections()`[](#getsections "Direct link to getsections")
tsx
```
static getSections(): Record;
```
Returns a [Runnables](/docs/appregistry.md#runnables) object.
***
### `registerCancellableHeadlessTask()`[](#registercancellableheadlesstask "Direct link to registercancellableheadlesstask")
tsx
```
static registerCancellableHeadlessTask(
taskKey: string,
taskProvider: TaskProvider,
taskCancelProvider: TaskCancelProvider,
);
```
Register a headless task which can be cancelled. A headless task is a bit of code that runs without a UI.
**Parameters:**
| Name | Type | Description |
| -------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| taskKey Required | string | The native id for this task instance that was used when startHeadlessTask was called. |
| taskProvider Required | [TaskProvider](/docs/appregistry.md#taskprovider) | A promise returning function that takes some data passed from the native side as the only argument. When the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. |
| taskCancelProvider Required | [TaskCancelProvider](/docs/appregistry.md#taskcancelprovider) | a void returning function that takes no arguments; when a cancellation is requested, the function being executed by taskProvider should wrap up and return ASAP. |
***
### `registerComponent()`[](#registercomponent "Direct link to registercomponent")
tsx
```
static registerComponent(
appKey: string,
getComponentFunc: ComponentProvider,
section?: boolean,
): string;
```
**Parameters:**
| Name | Type |
| ------------------------- | ----------------- |
| appKeyRequired | string |
| componentProviderRequired | ComponentProvider |
| section | boolean |
***
### `registerConfig()`[](#registerconfig "Direct link to registerconfig")
tsx
```
static registerConfig(config: AppConfig[]);
```
**Parameters:**
| Name | Type |
| -------------- | ---------------------------------------------- |
| configRequired | [AppConfig](/docs/appregistry.md#appconfig)\[] |
***
### `registerHeadlessTask()`[](#registerheadlesstask "Direct link to registerheadlesstask")
tsx
```
static registerHeadlessTask(
taskKey: string,
taskProvider: TaskProvider,
);
```
Register a headless task. A headless task is a bit of code that runs without a UI.
This is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music.
**Parameters:**
| Name | Type | Description |
| -------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| taskKeyRequired | string | The native id for this task instance that was used when startHeadlessTask was called. |
| taskProviderRequired | [TaskProvider](/docs/appregistry.md#taskprovider) | A promise returning function that takes some data passed from the native side as the only argument. When the promise is resolved or rejected the native side is notified of this event and it may decide to destroy the JS context. |
***
### `registerRunnable()`[](#registerrunnable "Direct link to registerrunnable")
tsx
```
static registerRunnable(appKey: string, func: Runnable): string;
```
**Parameters:**
| Name | Type |
| -------------- | -------- |
| appKeyRequired | string |
| runRequired | function |
***
### `registerSection()`[](#registersection "Direct link to registersection")
tsx
```
static registerSection(
appKey: string,
component: ComponentProvider,
);
```
**Parameters:**
| Name | Type |
| ----------------- | ----------------- |
| appKeyRequired | string |
| componentRequired | ComponentProvider |
***
### `runApplication()`[](#runapplication "Direct link to runapplication")
tsx
```
static runApplication(appKey: string, appParameters: any): void;
```
Loads the JavaScript bundle and runs the app.
**Parameters:**
| Name | Type |
| --------------------- | ------ |
| appKeyRequired | string |
| appParametersRequired | any |
***
### `setComponentProviderInstrumentationHook()`[](#setcomponentproviderinstrumentationhook "Direct link to setcomponentproviderinstrumentationhook")
tsx
```
static setComponentProviderInstrumentationHook(
hook: ComponentProviderInstrumentationHook,
);
```
**Parameters:**
| Name | Type |
| ------------ | -------- |
| hookRequired | function |
A valid `hook` function accepts the following as arguments:
| Name | Type |
| ------------------------------- | ------------------ |
| componentRequired | ComponentProvider |
| scopedPerformanceLoggerRequired | IPerformanceLogger |
The function must also return a React Component.
***
### `setWrapperComponentProvider()`[](#setwrappercomponentprovider "Direct link to setwrappercomponentprovider")
tsx
```
static setWrapperComponentProvider(
provider: WrapperComponentProvider,
);
```
**Parameters:**
| Name | Type |
| ---------------- | ----------------- |
| providerRequired | ComponentProvider |
***
### `startHeadlessTask()`[](#startheadlesstask "Direct link to startheadlesstask")
tsx
```
static startHeadlessTask(
taskId: number,
taskKey: string,
data: any,
);
```
Only called from native code. Starts a headless task.
**Parameters:**
| Name | Type | Description |
| --------------- | ------ | -------------------------------------------------------------------- |
| taskIdRequired | number | The native id for this task instance to keep track of its execution. |
| taskKeyRequired | string | The key for the task to start. |
| dataRequired | any | The data to pass to the task. |
***
### `unmountApplicationComponentAtRootTag()`[](#unmountapplicationcomponentatroottag "Direct link to unmountapplicationcomponentatroottag")
tsx
```
static unmountApplicationComponentAtRootTag(rootTag: number);
```
Stops an application when a view should be destroyed.
**Parameters:**
| Name | Type |
| --------------- | ------ |
| rootTagRequired | number |
## Type Definitions[](#type-definitions "Direct link to Type Definitions")
### AppConfig[](#appconfig "Direct link to AppConfig")
Application configuration for the `registerConfig` method.
| Type |
| ------ |
| object |
**Properties:**
| Name | Type |
| -------------- | ----------------- |
| appKeyRequired | string |
| component | ComponentProvider |
| run | function |
| section | boolean |
note
Every config is expected to set either `component` or `run` function.
### Registry[](#registry "Direct link to Registry")
| Type |
| ------ |
| object |
**Properties:**
| Name | Type |
| --------- | --------------------------------------------------- |
| runnables | array of [Runnables](/docs/appregistry.md#runnable) |
| sections | array of strings |
### Runnable[](#runnable "Direct link to Runnable")
| Type |
| ------ |
| object |
**Properties:**
| Name | Type |
| --------- | ----------------- |
| component | ComponentProvider |
| run | function |
### Runnables[](#runnables "Direct link to Runnables")
An object with key of `appKey` and value of type of [`Runnable`](/docs/appregistry.md#runnable).
| Type |
| ------ |
| object |
### Task[](#task "Direct link to Task")
A `Task` is a function that accepts any data as argument and returns a Promise that resolves to `undefined`.
| Type |
| -------- |
| function |
### TaskCanceller[](#taskcanceller "Direct link to TaskCanceller")
A `TaskCanceller` is a function that accepts no argument and returns void.
| Type |
| -------- |
| function |
### TaskCancelProvider[](#taskcancelprovider "Direct link to TaskCancelProvider")
A valid `TaskCancelProvider` is a function that returns a [`TaskCanceller`](/docs/appregistry.md#taskcanceller).
| Type |
| -------- |
| function |
### TaskProvider[](#taskprovider "Direct link to TaskProvider")
A valid `TaskProvider` is a function that returns a [`Task`](/docs/appregistry.md#task).
| Type |
| -------- |
| function |
---
# Source: https://reactnative.dev/docs/appstate.md
# AppState
`AppState` can tell you if the app is in the foreground or background, and notify you when the state changes.
AppState is frequently used to determine the intent and proper behavior when handling push notifications.
### App States[](#app-states "Direct link to App States")
* `active` - The app is running in the foreground
* `background` - The app is running in the background. The user is either:
* in another app
* on the home screen
* \[Android] on another `Activity` (even if it was launched by your app)
* \[iOS] `inactive` - This is a state that occurs when transitioning between foreground & background, and during periods of inactivity such as entering the multitasking view, opening the Notification Center or in the event of an incoming call.
For more information, see [Apple's documentation](https://developer.apple.com/documentation/uikit/app_and_scenes/managing_your_app_s_life_cycle)
## Basic Usage[](#basic-usage "Direct link to Basic Usage")
To see the current state, you can check `AppState.currentState`, which will be kept up-to-date. However, `currentState` will be null at launch while `AppState` retrieves it over the bridge.
This example will only ever appear to say "Current state is: active" because the app is only visible to the user when in the `active` state, and the null state will happen only momentarily. If you want to experiment with the code we recommend to use your own device instead of embedded preview.
***
# Reference
## Events[](#events "Direct link to Events")
### `change`[](#change "Direct link to change")
This event is received when the app state has changed. The listener is called with one of [the current app state values](/docs/appstate.md#app-states).
### `memoryWarning`iOS[](#memorywarning-ios "Direct link to memorywarning-ios")
Fires when the app receives a memory warning from the operating system.
### `focus`Android[](#focus-android "Direct link to focus-android")
Received when the app gains focus (the user is interacting with the app).
### `blur`Android[](#blur-android "Direct link to blur-android")
Received when the user is not actively interacting with the app. Useful in situations when the user pulls down the [notification drawer](https://developer.android.com/guide/topics/ui/notifiers/notifications#bar-and-drawer). `AppState` won't change but the `blur` event will get fired.
## Methods[](#methods "Direct link to Methods")
### `addEventListener()`[](#addeventlistener "Direct link to addeventlistener")
tsx
```
static addEventListener(
type: AppStateEvent,
listener: (state: AppStateStatus) => void,
): NativeEventSubscription;
```
Sets up a function that will be called whenever the specified event type on AppState occurs. Valid values for `eventType` are [listed above](#events). Returns the `EventSubscription`.
## Properties[](#properties "Direct link to Properties")
### `currentState`[](#currentstate "Direct link to currentstate")
tsx
```
static currentState: AppStateStatus;
```
---
# Source: https://reactnative.dev/docs/asyncstorage.md
# ❌ AsyncStorage
Removed from React Native
Use one of the [community packages](https://reactnative.directory/?search=storage) instead.
---
# Source: https://reactnative.dev/docs/backhandler.md
# BackHandler
The Backhandler API detects hardware button presses for back navigation, lets you register event listeners for the system's back action, and lets you control how your application responds. It is Android-only.
The event subscriptions are called in reverse order (i.e. the last registered subscription is called first).
* **If one subscription returns true,** then subscriptions registered earlier will not be called.
* **If no subscription returns true or none are registered,** it programmatically invokes the default back button functionality to exit the app.
Warning for modal users
If your app shows an opened `Modal`, `BackHandler` will not publish any events ([see `Modal` docs](/docs/modal.md#onrequestclose)).
## Pattern[](#pattern "Direct link to Pattern")
tsx
```
const subscription = BackHandler.addEventListener(
'hardwareBackPress',
function () {
/**
* this.onMainScreen and this.goBack are just examples,
* you need to use your own implementation here.
*
* Typically you would use the navigator here to go to the last state.
*/
if (!this.onMainScreen()) {
this.goBack();
/**
* When true is returned the event will not be bubbled up
* & no other back action will execute
*/
return true;
}
/**
* Returning false will let the event to bubble up & let other event listeners
* or the system's default back action to be executed.
*/
return false;
},
);
// Unsubscribe the listener on unmount
subscription.remove();
```
## Example[](#example "Direct link to Example")
The following example implements a scenario where you confirm if the user wants to exit the app:
`BackHandler.addEventListener` creates an event listener & returns a `NativeEventSubscription` object which should be cleared using `NativeEventSubscription.remove` method.
## Usage with React Navigation[](#usage-with-react-navigation "Direct link to Usage with React Navigation")
If you are using React Navigation to navigate across different screens, you can follow their guide on [Custom Android back button behaviour](https://reactnavigation.org/docs/custom-android-back-button-handling/)
## Backhandler hook[](#backhandler-hook "Direct link to Backhandler hook")
[React Native Hooks](https://github.com/react-native-community/hooks#usebackhandler) has a nice `useBackHandler` hook which will simplify the process of setting up event listeners.
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `addEventListener()`[](#addeventlistener "Direct link to addeventlistener")
tsx
```
static addEventListener(
eventName: BackPressEventName,
handler: () => boolean | null | undefined,
): NativeEventSubscription;
```
***
### `exitApp()`[](#exitapp "Direct link to exitapp")
tsx
```
static exitApp();
```
---
# Source: https://reactnative.dev/blog.md
## [React Native 0.83 - React 19.2, New DevTools features, no breaking changes](/blog/2025/12/10/react-native-0.83.md)
December 10, 2025 ·
12 min read

Alex Hunt
Software Engineer @ Meta
[](https://x.com/huntie "X")[](https://github.com/huntie "GitHub")

Riccardo Cipolleschi
Software Engineer @ Meta
[](https://x.com/CipolleschiR "X")[](https://github.com/cipolleschi "GitHub")

Gabriel Donadel Dall'Agnol
Software Engineer @ Expo
[](https://x.com/donadeldev "X")[](https://github.com/gabrieldonadel "GitHub")

Alan Hughes
Software Engineer @ Expo
[](https://github.com/alanjhughes "GitHub")
Today we are excited to release React Native 0.83!
This release includes React 19.2, significant new features for React Native DevTools, and support for the Web Performance and Intersection Observer APIs (Canary). This is also the first React Native release with no user facing breaking changes.
### Highlights[](#highlights "Direct link to Highlights")
* [React 19.2](/blog/2025/12/10/react-native-0.83.md#react-192)
* [New DevTools features](/blog/2025/12/10/react-native-0.83.md#new-devtools-features)
* [Intersection Observers (Canary)](/blog/2025/12/10/react-native-0.83.md#intersection-observers-canary)
* [Web Performance APIs as stable](/blog/2025/12/10/react-native-0.83.md#web-performance-apis-as-stable)
**Tags:**
* [announcement](/blog/tags/announcement)
* [release](/blog/tags/release)
[**Read more**](/blog/2025/12/10/react-native-0.83.md)
---
# Source: https://reactnative.dev/contributing/bots-reference.md
# Bots Reference
## pull-bot[](#pull-bot "Direct link to pull-bot")
This pull request linter bot performs basic sanity checks whenever a pull request is created. It might leave a comment on a pull request if it is unable to find a test plan or a changelog in the description, or if it notices that the pull request was not opened against the `main` branch. This bot uses [Danger](https://danger.systems), and its configuration can be found in the [`dangerfile.js`](https://github.com/facebook/react-native/blob/main/packages/react-native-bots/dangerfile.js).
## analysis-bot[](#analysis-bot "Direct link to analysis-bot")
The code analysis bot collects feedback from tools such as Prettier, eslint, and Flow whenever a commit is added to a pull request. If any of these tools finds issues with the code, the bot will add these as inline review comments on the pull request. Its configuration can be found in the [`analyze_code.sh`](https://github.com/facebook/react-native/blob/main/scripts/circleci/analyze_code.sh) file in core repository.
## label-actions[](#label-actions "Direct link to label-actions")
A bot that acts on an issue or pull request based on a label. Configured in [`.github/workflows/on-issue-labeled.yml`](https://github.com/facebook/react-native/blob/main/.github/workflows/on-issue-labeled.yml).
## github-actions[](#github-actions "Direct link to github-actions")
A bot that performs actions defined in a GitHub workflow. Workflows are configured in [`.github/workflows`](https://github.com/facebook/react-native/tree/main/.github/workflows).
## facebook-github-bot[](#facebook-github-bot "Direct link to facebook-github-bot")
The Facebook GitHub Bot is used across several open source projects at Meta. In the case of React Native, you will most likely encounter it when it pushes a merge commit to `main` after a pull request is successfully imported to Facebook's internal source control. It will also let authors know if they are missing a Contributor License Agreement.
## react-native-bot[](#react-native-bot "Direct link to react-native-bot")
The React Native bot is a tool that helps us automate several processes described in this wiki. Configured in [`hramos/react-native-bot`](https://github.com/hramos/react-native-bot).
---
# Source: https://reactnative.dev/docs/boxshadowvalue.md
# BoxShadowValue Object Type
The `BoxShadowValue` object is taken by the [`boxShadow`](/docs/view-style-props.md#boxshadow) style prop. It is comprised of 2-4 lengths, an optional color, and an optional `inset` boolean. These values collectively define the box shadow's color, position, size, and blurriness.
## Example[](#example "Direct link to Example")
js
```
{
offsetX: 10,
offsetY: -3,
blurRadius: '15px',
spreadDistance: '10px',
color: 'red',
inset: true,
}
```
## Keys and values[](#keys-and-values "Direct link to Keys and values")
### `offsetX`[](#offsetx "Direct link to offsetx")
The offset on the x-axis. This can be positive or negative. A positive value indicates right and negative indicates left.
| Type | Optional |
| ---------------- | -------- |
| number \| string | No |
### `offsetY`[](#offsety "Direct link to offsety")
The offset on the y-axis. This can be positive or negative. A positive value indicates up and negative indicates down.
| Type | Optional |
| ---------------- | -------- |
| number \| string | No |
### `blurRadius`[](#blurradius "Direct link to blurradius")
Represents the radius used in the [Gaussian blur](https://en.wikipedia.org/wiki/Gaussian_blur) algorithm. The larger the value the blurrier the shadow is. Only non-negative values are valid. The default is 0.
| Type | Optional |
| ---------------- | -------- |
| number \| string | Yes |
### `spreadDistance`[](#spreaddistance "Direct link to spreaddistance")
How much larger or smaller the shadow grows or shrinks. A positive value will grow the shadow, a negative value will shrink the shadow.
| Type | Optional |
| ---------------- | -------- |
| number \| string | Yes |
### `color`[](#color "Direct link to color")
The color of the shadow. The default is `black`.
| Type | Optional |
| ------------------------ | -------- |
| [color](/docs/colors.md) | Yes |
### `inset`[](#inset "Direct link to inset")
Whether the shadow is inset or not. Inset shadows will appear around the inside of the element's border box as opposed to the outside.
| Type | Optional |
| ------- | -------- |
| boolean | Yes |
## Used by[](#used-by "Direct link to Used by")
* [`boxShadow`](/docs/view-style-props.md#boxshadow)
---
# Source: https://reactnative.dev/docs/build-speed.md
# Speeding up your Build phase
Building your React Native app could be **expensive** and take several minutes of developers time. This can be problematic as your project grows and generally in bigger organizations with multiple React Native developers.
To mitigate this performance hit, this page shares some suggestions on how to **improve your build time**.
info
Please note that those suggestions are advanced feature that requires some amount of understanding of how the native build tools work.
## Build only one ABI during development (Android-only)[](#build-only-one-abi-during-development-android-only "Direct link to Build only one ABI during development (Android-only)")
When building your android app locally, by default you build all the 4 [Application Binary Interfaces (ABIs)](https://developer.android.com/ndk/guides/abis) : `armeabi-v7a`, `arm64-v8a`, `x86` & `x86_64`.
However, you probably don't need to build all of them if you're building locally and testing your emulator or on a physical device.
This should reduce your **native build time** by a \~75% factor.
If you're using the React Native CLI, you can add the `--active-arch-only` flag to the `run-android` command. This flag will make sure the correct ABI is picked up from either the running emulator or the plugged in phone. To confirm that this approach is working fine, you'll see a message like `info Detected architectures arm64-v8a` on console.
```
$ yarn react-native run-android --active-arch-only
[ ... ]
info Running jetifier to migrate libraries to AndroidX. You can disable it using "--no-jetifier" flag.
Jetifier found 1037 file(s) to forward-jetify. Using 32 workers...
info JS server already running.
info Detected architectures arm64-v8a
info Installing the app...
```
This mechanism relies on the `reactNativeArchitectures` Gradle property.
Therefore, if you're building directly with Gradle from the command line and without the CLI, you can specify the ABI you want to build as follows:
```
$ ./gradlew :app:assembleDebug -PreactNativeArchitectures=x86,x86_64
```
This can be useful if you wish to build your Android App on a CI and use a matrix to parallelize the build of the different architectures.
If you wish, you can also override this value locally, using the `gradle.properties` file you have in the [top-level folder](https://github.com/facebook/react-native/blob/19cf70266eb8ca151aa0cc46ac4c09cb987b2ceb/template/android/gradle.properties#L30-L33) of your project:
```
# Use this property to specify which architecture you want to build.
# You can also override it from the CLI using
# ./gradlew -PreactNativeArchitectures=x86_64
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
```
Once you build a **release version** of your app, don't forget to remove those flags as you want to build an apk/app bundle that works for all the ABIs and not only for the one you're using in your daily development workflow.
## Enable Configuration Caching (Android-only)[](#enable-configuration-caching-android-only "Direct link to Enable Configuration Caching (Android-only)")
Since React Native 0.79, you can also enable Gradle Configuration Caching.
When you’re running an Android build with `yarn android`, you will be executing a Gradle build that is composed by two steps ([source](https://docs.gradle.org/current/userguide/build_lifecycle.html)):
* Configuration phase, when all the `.gradle` files are evaluated.
* Execution phase, when the tasks are actually executed so the Java/Kotlin code is compiled and so on.
You will now be able to enable Configuration Caching, which will allow you to skip the Configuration phase on subsequent builds.
This is beneficial when making frequent changes to the native code as it improves build times.
For example here you can see how rebuilding faster it is to rebuild RN-Tester after a change in the native code:

You can enable Gradle Configuration Caching by adding the following line in your `android/gradle.properties` file:
```
org.gradle.configuration-cache=true
```
Please refer to the [official Gradle documentation](https://docs.gradle.org/current/userguide/configuration_cache.html) for more resources on Configuration Caching.
## Using a Maven Mirror (Android-only)[](#using-a-maven-mirror-android-only "Direct link to Using a Maven Mirror (Android-only)")
When building Android apps, your Gradle builds will need to download the necessary dependencies from Maven Central and other repositories from the internet.
If your organization is running a Maven repository mirror, you should consider using it as it will speed up your build, by downloading the artifacts from the mirror rather than from the internet.
You can configure a mirror by specifying the `exclusiveEnterpriseRepository` property in your `android/gradle.properties` file:
diff
```
# Use this property to enable or disable the Hermes JS engine.
# If set to false, you will be using JSC instead.
hermesEnabled=true
# Use this property to configure a Maven enterprise repository
# that will be used exclusively to fetch all of your dependencies.
+exclusiveEnterpriseRepository=https://my.internal.proxy.net/
```
By setting this property, your build will fetch dependencies **exclusively** from your specified repository and not from others.
## Use a compiler cache[](#use-a-compiler-cache "Direct link to Use a compiler cache")
If you're running frequent native builds (either C++ or Objective-C), you might benefit from using a **compiler cache**.
Specifically you can use two type of caches: local compiler caches and distributed compiler caches.
### Local caches[](#local-caches "Direct link to Local caches")
info
The following instructions will work for **both Android & iOS**. If you're building only Android apps, you should be good to go. If you're building also iOS apps, please follow the instructions in the [Xcode Specific Setup](#xcode-specific-setup) section below.
We suggest to use [**ccache**](https://ccache.dev/) to cache the compilation of your native builds. Ccache works by wrapping the C++ compilers, storing the compilation results, and skipping the compilation if an intermediate compilation result was originally stored.
Ccache is available in the package manager for most operating systems. On macOS, we can install ccache with `brew install ccache`. Or you can follow the [official installation instructions](https://github.com/ccache/ccache/blob/master/doc/install.md) to install from source.
You can then do two clean builds (e.g. on Android you can first run `yarn react-native run-android`, delete the `android/app/build` folder and run the first command once more). You will notice that the second build was way faster than the first one (it should take seconds rather than minutes). While building, you can verify that `ccache` works correctly and check the cache hits/miss rate `ccache -s`
```
$ ccache -s
Summary:
Hits: 196 / 3068 (6.39 %)
Direct: 0 / 3068 (0.00 %)
Preprocessed: 196 / 3068 (6.39 %)
Misses: 2872
Direct: 3068
Preprocessed: 2872
Uncacheable: 1
Primary storage:
Hits: 196 / 6136 (3.19 %)
Misses: 5940
Cache size (GB): 0.60 / 20.00 (3.00 %)
```
Note that `ccache` aggregates the stats over all builds. You can use `ccache --zero-stats` to reset them before a build to verify the cache-hit ratio.
Should you need to wipe your cache, you can do so with `ccache --clear`
#### Xcode Specific Setup[](#xcode-specific-setup "Direct link to Xcode Specific Setup")
To make sure `ccache` works correctly with iOS and Xcode, you need to enable React Native support for ccache in `ios/Podfile`.
Open `ios/Podfile` in your editor and uncomment the `ccache_enabled` line.
ruby
```
post_install do |installer|
# https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202
react_native_post_install(
installer,
config[:reactNativePath],
:mac_catalyst_enabled => false,
# TODO: Uncomment the line below
:ccache_enabled => true
)
end
```
#### Using this approach on a CI[](#using-this-approach-on-a-ci "Direct link to Using this approach on a CI")
Ccache uses the `/Users/$USER/Library/Caches/ccache` folder on macOS to store the cache. Therefore you could save & restore the corresponding folder also on CI to speedup your builds.
However, there are a couple of things to be aware:
1. On CI, we recommend to do a full clean build, to avoid poisoned cache problems. If you follow the approach mentioned in the previous paragraph, you should be able to parallelize the native build on 4 different ABIs and you will most likely not need `ccache` on CI.
2. `ccache` relies on timestamps to compute a cache hit. This doesn't work well on CI as files are re-downloaded at every CI run. To overcome this, you'll need to use the `compiler_check content` option which relies instead on [hashing the content of the file](https://ccache.dev/manual/4.3.html).
### Distributed caches[](#distributed-caches "Direct link to Distributed caches")
Similar to local caches, you might want to consider using a distributed cache for your native builds. This could be specifically useful in bigger organizations that are doing frequent native builds.
We recommend to use [sccache](https://github.com/mozilla/sccache) to achieve this. We defer to the sccache [distributed compilation quickstart](https://github.com/mozilla/sccache/blob/main/docs/DistributedQuickstart.md) for instructions on how to setup and use this tool.
---
# Source: https://reactnative.dev/docs/building-for-tv.md
# 🗑️ Building For TV Devices
TV devices support has been implemented with the intention of making existing React Native applications work on Apple TV and Android TV, with few or no changes needed in the JavaScript code for the applications.
Deprecated
TV support has moved to the [React Native for TV](https://github.com/react-native-tvos/react-native-tvos#readme) repository. Please see the **README** there for information on projects for Apple TV or Android TV.
---
# Source: https://reactnative.dev/architecture/bundled-hermes.md
# Bundled Hermes
This page gives an overview of **how** Hermes and React Native **are built**.
If you're looking into instructions on how to use Hermes in your app, you can find instructions on this other page: [using Hermes](/docs/hermes.md)
caution
Please note that this page serves as a technical deep dive and is targeted for users which are building extensions on top of Hermes or React Native. General users of React Native should not need to know in-depth information on how React Native and Hermes interact.
## What is 'Bundled Hermes'[](#what-is-bundled-hermes "Direct link to What is 'Bundled Hermes'")
Starting with React Native 0.69.0, every version of React Native will be **built alongside** to a Hermes version. We call this distribution model **Bundled Hermes**.
From 0.69 on, you will always have a JS engine that has been built and tested alongside each React Native version that you can use.
## Why we moved to 'Bundled Hermes'[](#why-we-moved-to-bundled-hermes "Direct link to Why we moved to 'Bundled Hermes'")
Historically, React Native and Hermes followed two **distinct release processes** with distinct versioning. Having distinct releases with distinct numbers created confusion in the OSS ecosystem, where it was not clear if a specific version of Hermes was compatible with a specific version of React Native (i.e. you needed to know that Hermes 0.11.0 was compatible only with React Native 0.68.0, etc.)
Both Hermes and React Native, share the JSI code ([Hermes here](https://github.com/facebook/hermes/tree/main/API/jsi/jsi) and [React Native here](https://github.com/facebook/react-native/tree/main/packages/react-native/ReactCommon/jsi/jsi)). If the two JSI copies of JSI get out of sync, a build of Hermes won't be compatible with a build of React Native. You can read more about this [ABI incompatibility problem here](https://github.com/react-native-community/discussions-and-proposals/issues/257).
To overcome this problem, we've extended the React Native release process to download and build Hermes and made sure only one copy of JSI is used when building Hermes.
Thanks to this, we can release a version of Hermes whenever we release a version of React Native, and be sure that the Hermes engine we built is **fully compatible** with the React Native version we're releasing. We're shipping this version of Hermes alongside the React Native version we're doing, hence the name *Bundled Hermes*.
## How this will impact app developers[](#how-this-will-impact-app-developers "Direct link to How this will impact app developers")
As mentioned in the introduction, if you're an app developer, this change **should not affect** you directly.
The following paragraphs describe which changes we did under the hood and explains some of the rationales, for the sake of transparency.
### iOS Users[](#ios-users "Direct link to iOS Users")
On iOS, we've moved the `hermes-engine` you're using.
Prior to React Native 0.69, users would download a pod (here you can find the [podspec](https://github.com/CocoaPods/Specs/blob/master/Specs/5/d/0/hermes-engine/0.11.0/hermes-engine.podspec.json)).
On React Native 0.69, users would instead use a podspec that is defined inside the `sdks/hermes-engine/hermes-engine.podspec` file in the `react-native` NPM package. That podspec relies on a pre-built tarball of Hermes that we upload to Maven and to the React Native GitHub Release, as part of the React Native release process (i.e. [see the assets of this release](https://github.com/facebook/react-native/releases/tag/v0.70.4)).
### Android Users[](#android-users "Direct link to Android Users")
On Android, we're going to update the [`android/app/build.gradle`](https://github.com/facebook/react-native/blob/main/template/android/app/build.gradle) file in the default template the following way:
diff
```
dependencies {
// ...
if (enableHermes) {
+ implementation("com.facebook.react:hermes-engine:+") {
+ exclude group:'com.facebook.fbjni'
+ }
- def hermesPath = "../../node_modules/hermes-engine/android/";
- debugImplementation files(hermesPath + "hermes-debug.aar")
- releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
}
```
Prior to React Native 0.69, users will be consuming `hermes-debug.aar` and `hermes-release.aar` from the `hermes-engine` NPM package.
On React Native 0.69, users will be consuming the Android multi-variant artifacts available inside the `android/com/facebook/react/hermes-engine/` folder in the `react-native` NPM package. Please also note that we're going to [remove the dependency](https://github.com/facebook/react-native/blob/c418bf4c8fe8bf97273e3a64211eaa38d836e0a0/package.json#L105) on `hermes-engine` entirely in one of the future version of React Native.
#### Android Users on New Architecture[](#android-users-on-new-architecture "Direct link to Android Users on New Architecture")
Due to the nature of our native code build setup (i.e. how we use the NDK), users on the New Architecture will be **building Hermes from source**.
This aligns the build mechanism of React Native and Hermes for users on the New Architecture (they will build both framework from source). This means that such Android users might experience a performance hit at build time on their first build.
You can find instructions to optimize your build time and reduce the impact on your build on this page: [Speeding up your Build phase](/docs/next/build-speed).
#### Android Users on New Architecture building on Windows[](#android-users-on-new-architecture-building-on-windows "Direct link to Android Users on New Architecture building on Windows")
Users building React Native App, with the New Architecture, on Windows machines need to follow those extra steps to let the build work correctly:
* Make sure the [environment is configured properly](https://reactnative.dev/docs/environment-setup), with Android SDK & node.
* Install [cmake](https://community.chocolatey.org/packages/cmake) with Chocolatey
* Install either:
* [Build Tools for Visual Studio 2022](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022).
* [Visual Studio 22 Community Edition](https://visualstudio.microsoft.com/vs/community/) - Picking only the C++ desktop development is sufficient.
* Make sure the [Visual Studio Command Prompt](https://docs.microsoft.com/en-us/visualstudio/ide/reference/command-prompt-powershell?view=vs-2022) is configured correctly. This is required as the proper C++ compiler environment variable is configured in those command prompt.
* Run the app with `npx react-native run-android` inside a Visual Studio Command Prompt.
### Can users still use another engine?[](#can-users-still-use-another-engine "Direct link to Can users still use another engine?")
Yes, users are free to enable/disable Hermes (with the `enableHermes` variable on Android, `hermes_enabled` on iOS). The 'Bundled Hermes' change will impact only **how Hermes is built and bundled** for you.
Starting with React Native 0.70, the default for `enableHermes`/`hermes_enabled` is `true`.
## How this will impact contributor and extension developers[](#how-this-will-impact-contributor-and-extension-developers "Direct link to How this will impact contributor and extension developers")
If you're a React Native contributor or you're building an extension on top of React Native or Hermes, please read further as we explain how Bundled Hermes works.
### How is Bundled Hermes working under the hood?[](#how-is-bundled-hermes-working-under-the-hood "Direct link to How is Bundled Hermes working under the hood?")
This mechanism relies on **downloading a tarball** with the Hermes source code from the `facebook/hermes` repository inside the `facebook/react-native` repository. We have a similar mechanism in place for other native dependencies (Folly, Glog, etc.) and we aligned Hermes to follow the same setup.
When building React Native from `main`, we will be fetching a tarball of `main` of facebook/hermes and building it as part of the build process of React Native.
When building React Native from a release branch (say `0.69-stable`), we will instead use a **tag** on the Hermes repo to **synchronize the code** between the two repos. The specific tag name used will then be stored inside the `sdks/.hermesversion` file inside React Native in the release branch (e.g. [this is the file](https://github.com/facebook/react-native/blob/0.69-stable/sdks/.hermesversion) on the 0.69 release branch).
In a sense, you can think of this approach similarly to a **git submodule**.
If you're building on top of Hermes, you can rely on those tags to understand which version of Hermes was used when building React Native, as the version of React Native is specified in the tag name (e.g. `hermes-2022-05-20-RNv0.69.0-ee8941b8874132b8f83e4486b63ed5c19fc3f111`).
#### Android implementation details[](#android-implementation-details "Direct link to Android implementation details")
To implement this on Android, we've added a new build inside the `/ReactAndroid/hermes-engine` of React Native that will take care of building Hermes and packaging for consumption ([See here for more context](https://github.com/facebook/react-native/pull/33396)).
You can now trigger a build of Hermes engine by invoking:
bash
```
// Build a debug version of Hermes
./gradlew :ReactAndroid:hermes-engine:assembleDebug
// Build a release version of Hermes
./gradlew :ReactAndroid:hermes-engine:assembleRelease
```
from the React Native `main` branch.
You won't need to install extra tools (such as `cmake`, `ninja` or `python3`) in your machine as we configured the build to use the NDK versions of those tools.
On the Gradle consumer side, we also shipped a small improvement on the consumer side: we moved from `releaseImplementation` & `debugImplementation` to `implementation`. This is possible because the newer `hermes-engine` Android artifact is **variant aware** and will properly match a debug build of the engine with a debug build of your app. You don't need any custom configuration here (even if you use `staging` or other build types/flavors).
However, this made this line necessary in the template:
```
exclude group:'com.facebook.fbjni'
```
This is needed as React Native is consuming `fbjni` using the non-prefab approach (i.e. unzipping the `.aar` and extracting `.so` files). Hermes-engine, and other libraries, are using prefab instead to consume fbjni. We're looking into [addressing this issue](https://github.com/facebook/react-native/pull/33397) in the future so the Hermes import will be a oneliner.
#### iOS implementation details[](#ios-implementation-details "Direct link to iOS implementation details")
The iOS implementation relies on a series of scripts that lives in the following locations:
* [`/scripts/hermes`](https://github.com/facebook/react-native/tree/main/scripts/hermes). Those scripts contain logic to download the Hermes tarball, unzip it, and configure the iOS build. They're invoked at `pod install` time if you have the `hermes_enabled` field set to `true`.
* [`/sdks/hermes-engine`](https://github.com/facebook/react-native/tree/main/sdks/hermes-engine). Those scripts contain the build logic that is effectively building Hermes. They were copied and adapted from the `facebook/hermes` repo to properly work within React Native. Specifically, the scripts inside the `utils` folder are responsible of building Hermes for all the Mac platforms.
Hermes is built as part of the `build_hermes_macos` Job on CircleCI. The job will produce as artifact a tarball which will be downloaded by the `hermes-engine` podspec when using a published React Native release ([here is an example of the artifacts created for React Native 0.69 in `build_hermes_macos`](https://app.circleci.com/pipelines/github/facebook/react-native/13679/workflows/5172f8e4-6b02-4ccb-ab97-7cb954911fae/jobs/258701/artifacts)).
##### Prebuilt Hermes[](#prebuilt-hermes "Direct link to Prebuilt Hermes")
If there are no prebuilt artifacts for the React Native version that is being used (i.e. you may be working with React Native from the `main` branch), then Hermes will need to be built from source. First, the Hermes compiler, `hermesc`, will be built for macOS during `pod install`, then Hermes itself will be built as part of the Xcode build pipeline using the `build-hermes-xcode.sh` script.
##### Building Hermes from source[](#building-hermes-from-source "Direct link to Building Hermes from source")
Hermes is always built from source when using React Native from the `main` branch. If you are using a stable React Native version, you can force Hermes to be built from source by setting the `CI` envvar to `true` when using CocoaPods: `CI=true pod install`.
##### Debug symbols[](#debug-symbols "Direct link to Debug symbols")
The prebuilt artifacts for Hermes do not contain debug symbols (dSYMs) by default. We're planning on distributing these debug symbols for each release in the future. Until then, if you need the debug symbols for Hermes, you will need to build Hermes from source. A `hermes.framework.dSYM` will be created in the build directory alongside each of the Hermes frameworks.
### I'm afraid this change is impacting me[](#im-afraid-this-change-is-impacting-me "Direct link to I'm afraid this change is impacting me")
We'd like to stress that this is essentially an organizational change on *where* Hermes is built and *how* the code is synchronized between the two repositories. The change should be fully transparent to our users.
Historically, we used to cut a release of Hermes for a specific version of React Native (e.g. [`v0.11.0 for RN0.68.x`](https://github.com/facebook/hermes/releases/tag/v0.11.0)).
With 'Bundled Hermes', you can instead rely on a tag that will represent the version used when a specific version of React Native was cut.
---
# Source: https://reactnative.dev/docs/button.md
# Button
A basic button component that should render nicely on any platform. Supports a minimal level of customization.
If this button doesn't look right for your app, you can build your own button using [Pressable](/docs/pressable.md). For inspiration, look at the [source code for the Button component](https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Components/Button.js).
tsx
```
```
## Example[](#example "Direct link to Example")
***
# Reference
## Props[](#props "Direct link to Props")
### Required**`onPress`**[](#requiredonpress "Direct link to requiredonpress")
Handler to be called when the user taps the button.
| Type |
| ----------------------------- |
| `({nativeEvent: PressEvent})` |
***
### Required**`title`**[](#requiredtitle "Direct link to requiredtitle")
Text to display inside the button. On Android the given title will be converted to the uppercased form.
| Type |
| ------ |
| string |
***
### `accessibilityLabel`[](#accessibilitylabel "Direct link to accessibilitylabel")
Text to display for blindness accessibility features.
| Type |
| ------ |
| string |
***
### `accessibilityLanguage`iOS[](#accessibilitylanguage-ios "Direct link to accessibilitylanguage-ios")
A value indicating which language should be used by the screen reader when the user interacts with the element. It should follow the [BCP 47 specification](https://www.rfc-editor.org/info/bcp47).
See the [iOS `accessibilityLanguage` doc](https://developer.apple.com/documentation/objectivec/nsobject/1615192-accessibilitylanguage) for more information.
| Type |
| ------ |
| string |
***
### `accessibilityActions`[](#accessibilityactions "Direct link to accessibilityactions")
Accessibility actions allow an assistive technology to programmatically invoke the actions of a component. The `accessibilityActions` property should contain a list of action objects. Each action object should contain the field name and label.
See the [Accessibility guide](/docs/accessibility.md#accessibility-actions) for more information.
| Type | Required |
| ----- | -------- |
| array | No |
***
### `onAccessibilityAction`[](#onaccessibilityaction "Direct link to onaccessibilityaction")
Invoked when the user performs the accessibility actions. The only argument to this function is an event containing the name of the action to perform.
See the [Accessibility guide](/docs/accessibility.md#accessibility-actions) for more information.
| Type | Required |
| -------- | -------- |
| function | No |
***
### `color`[](#color "Direct link to color")
Color of the text (iOS), or background color of the button (Android).
| Type | Default |
| ------------------------ | ----------------------------------- |
| [color](/docs/colors.md) | `'#2196F3'`Android***`'#007AFF'`iOS |
***
### `disabled`[](#disabled "Direct link to disabled")
If `true`, disable all interactions for this component.
| Type | Default |
| ---- | ------- |
| bool | `false` |
***
### `hasTVPreferredFocus`TV[](#hastvpreferredfocus-tv "Direct link to hastvpreferredfocus-tv")
TV preferred focus.
| Type | Default |
| ---- | ------- |
| bool | `false` |
***
### `nextFocusDown`AndroidTV[](#nextfocusdown-androidtv "Direct link to nextfocusdown-androidtv")
Designates the next view to receive focus when the user navigates down. See the [Android documentation](https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusDown).
| Type |
| ------ |
| number |
***
### `nextFocusForward`AndroidTV[](#nextfocusforward-androidtv "Direct link to nextfocusforward-androidtv")
Designates the next view to receive focus when the user navigates forward. See the [Android documentation](https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusForward).
| Type |
| ------ |
| number |
***
### `nextFocusLeft`AndroidTV[](#nextfocusleft-androidtv "Direct link to nextfocusleft-androidtv")
Designates the next view to receive focus when the user navigates left. See the [Android documentation](https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusLeft).
| Type |
| ------ |
| number |
***
### `nextFocusRight`AndroidTV[](#nextfocusright-androidtv "Direct link to nextfocusright-androidtv")
Designates the next view to receive focus when the user navigates right. See the [Android documentation](https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusRight).
| Type |
| ------ |
| number |
***
### `nextFocusUp`AndroidTV[](#nextfocusup-androidtv "Direct link to nextfocusup-androidtv")
Designates the next view to receive focus when the user navigates up. See the [Android documentation](https://developer.android.com/reference/android/view/View.html#attr_android:nextFocusUp).
| Type |
| ------ |
| number |
***
### `testID`[](#testid "Direct link to testid")
Used to locate this view in end-to-end tests.
| Type |
| ------ |
| string |
***
### `touchSoundDisabled`Android[](#touchsounddisabled-android "Direct link to touchsounddisabled-android")
If `true`, doesn't play system sound on touch.
| Type | Default |
| ------- | ------- |
| boolean | `false` |
---
# Source: https://reactnative.dev/contributing/changelogs-in-pull-requests.md
# Changelogs in Pull Requests
The changelog entry in your pull request serves as a sort of "tl;dr:" for your changes: do they affect Android? are these breaking changes? is something new being added?
Providing a changelog using a standardized format helps release coordinators write release notes. Please include a changelog as part of your pull request description. Your pull request description will be used as the commit message should the pull request get merged.
### Format[](#format "Direct link to Format")
A changelog entry has the following format
```
## Changelog:
[Category] [Type] - Message
```
The "Category" field may be one of:
* **Android**, for changes that affect Android.
* **iOS**, for changes that affect iOS.
* **General**, for changes that do not fit any of the other categories.
* **Internal**, for changes that would not be relevant to developers consuming the release notes.
The "Type" field may be one of:
* **Breaking**, for breaking changes.
* **Added**, for new features.
* **Changed**, for changes in existing functionality.
* **Deprecated**, for soon-to-be removed features.
* **Removed**, for now removed features.
* **Fixed**, for any bug fixes.
* **Security**, in case of vulnerabilities.
Finally, the "Message" field may answer "what and why" on a feature level. Use this to briefly tell React Native users about notable changes.
For more detail, see [How do I make a good changelog?](https://keepachangelog.com/en/1.0.0/#how) and [Why keep a changelog?](https://keepachangelog.com/en/1.0.0/#why)
### Examples[](#examples "Direct link to Examples")
* `[General] [Added] - Add snapToOffsets prop to ScrollView component`
* `[General] [Fixed] - Fix various issues in snapToInterval on ScrollView component`
* `[iOS] [Fixed] - Fix crash in RCTImagePicker`
### FAQ[](#faq "Direct link to FAQ")
#### What if my pull request contains changes to both Android and JavaScript?[](#what-if-my-pull-request-contains-changes-to-both-android-and-javascript "Direct link to What if my pull request contains changes to both Android and JavaScript?")
Use the Android category.
#### What if my pull request contains changes to both Android and iOS?[](#what-if-my-pull-request-contains-changes-to-both-android-and-ios "Direct link to What if my pull request contains changes to both Android and iOS?")
Use the General category if the change is made in a single pull request.
#### What if my pull request contains changes to Android, iOS, and JavaScript?[](#what-if-my-pull-request-contains-changes-to-android-ios-and-javascript "Direct link to What if my pull request contains changes to Android, iOS, and JavaScript?")
Use the General category if the change is made in a single pull request.
#### What if...?[](#what-if "Direct link to What if...?")
Any changelog entry is better than none. If you are unsure if you have picked the right category, use the "message" field to succinctly describe your change.
These entries are used by the [`@rnx-kit/rn-changelog-generator`](https://github.com/microsoft/rnx-kit/tree/main/incubator/rn-changelog-generator) script to build a rough draft, which is then edited by a release coordinator.
Your notes will be used to add your change to the correct location in the final release notes.
---
# Source: https://reactnative.dev/docs/checkbox.md
# ❌ CheckBox
Removed from React Native
Use one of the [community packages](https://reactnative.directory/?search=checkbox) instead.
---
# Source: https://reactnative.dev/docs/clipboard.md
# ❌ Clipboard
Removed from React Native
Use one of the [community packages](https://reactnative.directory/?search=clipboard) instead.
---
# Source: https://reactnative.dev/docs/the-new-architecture/codegen-cli.md
# The Codegen CLI
Calling Gradle or manually calling a script might be hard to remember and it requires a lot of ceremony.
To simplify it, we created a CLI tool that can help you running those tasks: the **Codegen** cli. This command runs [@react-native/codegen](https://www.npmjs.com/package/@react-native/codegen) for your project. The following options are available:
sh
```
npx @react-native-community/cli codegen --help
Usage: rnc-cli codegen [options]
Options:
--verbose Increase logging verbosity
--path Path to the React Native project root. (default: "/Users/MyUsername/projects/my-app")
--platform Target platform. Supported values: "android", "ios", "all". (default: "all")
--outputPath Path where generated artifacts will be output to.
-h, --help display help for command
```
## Examples[](#examples "Direct link to Examples")
* Read `package.json` from the current working directory, generate code based on its codegenConfig.
shell
```
npx @react-native-community/cli codegen
```
* Read `package.json` from the current working directory, generate iOS code in the location defined in the codegenConfig.
shell
```
npx @react-native-community/cli codegen --platform ios
```
* Read `package.json` from `third-party/some-library`, generate Android code in `third-party/some-library/android/generated`.
shell
```
npx @react-native-community/cli codegen \
--path third-party/some-library \
--platform android \
--outputPath third-party/some-library/android/generated
```
## Including Generated Code into Libraries[](#including-generated-code-into-libraries "Direct link to Including Generated Code into Libraries")
The Codegen CLI is a great tool for library developers. It can be used to take a sneak-peek at the generated code to see which interfaces you need to implement.
Normally the generated code is not included in the library, and the app that uses the library is responsible for running the Codegen at build time. This is a good setup for most cases, but Codegen also offers a mechanism to include the generated code in the library itself via the `includesGeneratedCode` property.
It's important to understand what are the implications of using `includesGeneratedCode = true`. Including the generated code comes with several benefits such as:
* No need to rely on the app to run **Codegen** for you, the generated code is always there.
* The implementation files are always consistent with the generated interfaces (this makes your library code more resilient against API changes in codegen).
* No need to include two sets of files to support both architectures on Android. You can only keep the New Architecture one, and it is guaranteed to be backwards compatible.
* Since all native code is there, it is possible to ship the native part of the library as a prebuild.
On the other hand, you also need to be aware of one drawback:
* The generated code will use the React Native version defined inside your library. So if your library is shipping with React Native 0.76, the generated code will be based on that version. This could mean that the generated code is not compatible with apps using **previous** React Native version used by the app (e.g. an App running on React Native 0.75).
## Enabling `includesGeneratedCode`[](#enabling-includesgeneratedcode "Direct link to enabling-includesgeneratedcode")
To enable this setup:
* Add the `includesGeneratedCode` property into your library's `codegenConfig` field in the `package.json` file. Set its value to `true`.
* Run **Codegen** locally with the codegen CLI.
* Update your `package.json` to include the generated code.
* Update your `podspec` to include the generated code.
* Update your `build.Gradle` file to include the generated code.
* Update `cmakeListsPath` in `react-native.config.js` so that Gradle doesn't look for CMakeLists file in the build directory but instead in your outputDir.
---
# Source: https://reactnative.dev/docs/colors.md
# Color Reference
Components in React Native are [styled using JavaScript](/docs/style.md). Color properties usually match how [CSS works on the web](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value). General guides on the color usage on each platform could be found below:
* [Android](https://material.io/design/color/color-usage.html)
* [iOS](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/)
## Color APIs[](#color-apis "Direct link to Color APIs")
React Native has several color APIs designed to allow you to take full advantage of your platform's design and user preferences.
* [PlatformColor](/docs/platformcolor.md) lets you reference the platform's color system.
* [DynamicColorIOS](/docs/dynamiccolorios.md) is iOS specific and allows you to specify which colors should be used in light or Dark Mode.
## Color representations[](#color-representations "Direct link to Color representations")
### Red Green Blue (RGB)[](#red-green-blue-rgb "Direct link to Red Green Blue (RGB)")
React Native supports `rgb()` and `rgba()` in both hexadecimal and functional notation:
* `'#f0f'` (#rgb)
* `'#ff00ff'` (#rrggbb)
* `'#f0ff'` (#rgba)
* `'#ff00ff00'` (#rrggbbaa)
* `'rgb(255, 0, 255)'`
* `'rgb(255 0 255)'`
* `'rgba(255, 0, 255, 1.0)'`
* `'rgba(255 0 255 / 1.0)'`
### Hue Saturation Lightness (HSL)[](#hue-saturation-lightness-hsl "Direct link to Hue Saturation Lightness (HSL)")
React Native supports `hsl()` and `hsla()` in functional notation:
* `'hsl(360, 100%, 100%)'`
* `'hsl(360 100% 100%)'`
* `'hsla(360, 100%, 100%, 1.0)'`
* `'hsla(360 100% 100% / 1.0)'`
### Hue Whiteness Blackness (HWB)[](#hue-whiteness-blackness-hwb "Direct link to Hue Whiteness Blackness (HWB)")
React Native supports `hwb()` in functional notation:
* `'hwb(0, 0%, 100%)'`
* `'hwb(360, 100%, 100%)'`
* `'hwb(0 0% 0%)'`
* `'hwb(70 50% 0%)'`
### Color ints[](#color-ints "Direct link to Color ints")
React Native supports also colors as an `int` values (in RGB color mode):
* `0xff00ff00` (0xrrggbbaa)
caution
This might appear similar to the Android [Color](https://developer.android.com/reference/android/graphics/Color) ints representation but on Android values are stored in SRGB color mode (0xaarrggbb).
### Named colors[](#named-colors "Direct link to Named colors")
In React Native you can also use color name strings as values.
info
React Native only supports lowercase color names. Uppercase color names are not supported.
#### `transparent`[](#transparent "Direct link to transparent")
This is a shortcut for `rgba(0,0,0,0)`, same like in [CSS3](https://www.w3.org/TR/css-color-3/#transparent).
#### Color keywords[](#color-keywords "Direct link to Color keywords")
Named colors implementation follows the [CSS3/SVG specification](https://www.w3.org/TR/css-color-3/#svg-color):
* aliceblue (`#f0f8ff`)
* antiquewhite (`#faebd7`)
* aqua (`#00ffff`)
* aquamarine (`#7fffd4`)
* azure (`#f0ffff`)
* beige (`#f5f5dc`)
* bisque (`#ffe4c4`)
* black (`#000000`)
* blanchedalmond (`#ffebcd`)
* blue (`#0000ff`)
* blueviolet (`#8a2be2`)
* brown (`#a52a2a`)
* burlywood (`#deb887`)
* cadetblue (`#5f9ea0`)
* chartreuse (`#7fff00`)
* chocolate (`#d2691e`)
* coral (`#ff7f50`)
* cornflowerblue (`#6495ed`)
* cornsilk (`#fff8dc`)
* crimson (`#dc143c`)
* cyan (`#00ffff`)
* darkblue (`#00008b`)
* darkcyan (`#008b8b`)
* darkgoldenrod (`#b8860b`)
* darkgray (`#a9a9a9`)
* darkgreen (`#006400`)
* darkgrey (`#a9a9a9`)
* darkkhaki (`#bdb76b`)
* darkmagenta (`#8b008b`)
* darkolivegreen (`#556b2f`)
* darkorange (`#ff8c00`)
* darkorchid (`#9932cc`)
* darkred (`#8b0000`)
* darksalmon (`#e9967a`)
* darkseagreen (`#8fbc8f`)
* darkslateblue (`#483d8b`)
* darkslategrey (`#2f4f4f`)
* darkturquoise (`#00ced1`)
* darkviolet (`#9400d3`)
* deeppink (`#ff1493`)
* deepskyblue (`#00bfff`)
* dimgray (`#696969`)
* dimgrey (`#696969`)
* dodgerblue (`#1e90ff`)
* firebrick (`#b22222`)
* floralwhite (`#fffaf0`)
* forestgreen (`#228b22`)
* fuchsia (`#ff00ff`)
* gainsboro (`#dcdcdc`)
* ghostwhite (`#f8f8ff`)
* gold (`#ffd700`)
* goldenrod (`#daa520`)
* gray (`#808080`)
* green (`#008000`)
* greenyellow (`#adff2f`)
* grey (`#808080`)
* honeydew (`#f0fff0`)
* hotpink (`#ff69b4`)
* indianred (`#cd5c5c`)
* indigo (`#4b0082`)
* ivory (`#fffff0`)
* khaki (`#f0e68c`)
* lavender (`#e6e6fa`)
* lavenderblush (`#fff0f5`)
* lawngreen (`#7cfc00`)
* lemonchiffon (`#fffacd`)
* lightblue (`#add8e6`)
* lightcoral (`#f08080`)
* lightcyan (`#e0ffff`)
* lightgoldenrodyellow (`#fafad2`)
* lightgray (`#d3d3d3`)
* lightgreen (`#90ee90`)
* lightgrey (`#d3d3d3`)
* lightpink (`#ffb6c1`)
* lightsalmon (`#ffa07a`)
* lightseagreen (`#20b2aa`)
* lightskyblue (`#87cefa`)
* lightslategrey (`#778899`)
* lightsteelblue (`#b0c4de`)
* lightyellow (`#ffffe0`)
* lime (`#00ff00`)
* limegreen (`#32cd32`)
* linen (`#faf0e6`)
* magenta (`#ff00ff`)
* maroon (`#800000`)
* mediumaquamarine (`#66cdaa`)
* mediumblue (`#0000cd`)
* mediumorchid (`#ba55d3`)
* mediumpurple (`#9370db`)
* mediumseagreen (`#3cb371`)
* mediumslateblue (`#7b68ee`)
* mediumspringgreen (`#00fa9a`)
* mediumturquoise (`#48d1cc`)
* mediumvioletred (`#c71585`)
* midnightblue (`#191970`)
* mintcream (`#f5fffa`)
* mistyrose (`#ffe4e1`)
* moccasin (`#ffe4b5`)
* navajowhite (`#ffdead`)
* navy (`#000080`)
* oldlace (`#fdf5e6`)
* olive (`#808000`)
* olivedrab (`#6b8e23`)
* orange (`#ffa500`)
* orangered (`#ff4500`)
* orchid (`#da70d6`)
* palegoldenrod (`#eee8aa`)
* palegreen (`#98fb98`)
* paleturquoise (`#afeeee`)
* palevioletred (`#db7093`)
* papayawhip (`#ffefd5`)
* peachpuff (`#ffdab9`)
* peru (`#cd853f`)
* pink (`#ffc0cb`)
* plum (`#dda0dd`)
* powderblue (`#b0e0e6`)
* purple (`#800080`)
* rebeccapurple (`#663399`)
* red (`#ff0000`)
* rosybrown (`#bc8f8f`)
* royalblue (`#4169e1`)
* saddlebrown (`#8b4513`)
* salmon (`#fa8072`)
* sandybrown (`#f4a460`)
* seagreen (`#2e8b57`)
* seashell (`#fff5ee`)
* sienna (`#a0522d`)
* silver (`#c0c0c0`)
* skyblue (`#87ceeb`)
* slateblue (`#6a5acd`)
* slategray (`#708090`)
* snow (`#fffafa`)
* springgreen (`#00ff7f`)
* steelblue (`#4682b4`)
* tan (`#d2b48c`)
* teal (`#008080`)
* thistle (`#d8bfd8`)
* tomato (`#ff6347`)
* turquoise (`#40e0d0`)
* violet (`#ee82ee`)
* wheat (`#f5deb3`)
* white (`#ffffff`)
* whitesmoke (`#f5f5f5`)
* yellow (`#ffff00`)
* yellowgreen (`#9acd32`)
---
# Source: https://reactnative.dev/docs/communication-android.md
# Communication between native and React Native
In [Integrating with Existing Apps guide](/docs/integration-with-existing-apps.md) and [Native UI Components guide](/docs/legacy/native-components-android.md) we learn how to embed React Native in a native component and vice versa. When we mix native and React Native components, we'll eventually find a need to communicate between these two worlds. Some ways to achieve that have been already mentioned in other guides. This article summarizes available techniques.
## Introduction[](#introduction "Direct link to Introduction")
React Native is inspired by React, so the basic idea of the information flow is similar. The flow in React is one-directional. We maintain a hierarchy of components, in which each component depends only on its parent and its own internal state. We do this with properties: data is passed from a parent to its children in a top-down manner. If an ancestor component relies on the state of its descendant, one should pass down a callback to be used by the descendant to update the ancestor.
The same concept applies to React Native. As long as we are building our application purely within the framework, we can drive our app with properties and callbacks. But, when we mix React Native and native components, we need some specific, cross-language mechanisms that would allow us to pass information between them.
## Properties[](#properties "Direct link to Properties")
Properties are the most straightforward way of cross-component communication. So we need a way to pass properties both from native to React Native, and from React Native to native.
### Passing properties from native to React Native[](#passing-properties-from-native-to-react-native "Direct link to Passing properties from native to React Native")
You can pass properties down to the React Native app by providing a custom implementation of `ReactActivityDelegate` in your main activity. This implementation should override `getLaunchOptions` to return a `Bundle` with the desired properties.
* Java
* Kotlin
java
```
public class MainActivity extends ReactActivity {
@Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
@Override
protected Bundle getLaunchOptions() {
Bundle initialProperties = new Bundle();
ArrayList imageList = new ArrayList(Arrays.asList(
"https://dummyimage.com/600x400/ffffff/000000.png",
"https://dummyimage.com/600x400/000000/ffffff.png"
));
initialProperties.putStringArrayList("images", imageList);
return initialProperties;
}
};
}
}
```
kotlin
```
class MainActivity : ReactActivity() {
override fun createReactActivityDelegate(): ReactActivityDelegate {
return object : ReactActivityDelegate(this, mainComponentName) {
override fun getLaunchOptions(): Bundle {
val imageList = arrayListOf("https://dummyimage.com/600x400/ffffff/000000.png", "https://dummyimage.com/600x400/000000/ffffff.png")
val initialProperties = Bundle().apply { putStringArrayList("images", imageList) }
return initialProperties
}
}
}
}
```
tsx
```
import React from 'react';
import {View, Image} from 'react-native';
export default class ImageBrowserApp extends React.Component {
renderImage(imgURI) {
return ;
}
render() {
return {this.props.images.map(this.renderImage)};
}
}
```
`ReactRootView` provides a read-write property `appProperties`. After `appProperties` is set, the React Native app is re-rendered with new properties. The update is only performed when the new updated properties differ from the previous ones.
* Java
* Kotlin
java
```
Bundle updatedProps = mReactRootView.getAppProperties();
ArrayList imageList = new ArrayList(Arrays.asList(
"https://dummyimage.com/600x400/ff0000/000000.png",
"https://dummyimage.com/600x400/ffffff/ff0000.png"
));
updatedProps.putStringArrayList("images", imageList);
mReactRootView.setAppProperties(updatedProps);
```
kotlin
```
var updatedProps: Bundle = reactRootView.getAppProperties()
var imageList = arrayListOf("https://dummyimage.com/600x400/ff0000/000000.png", "https://dummyimage.com/600x400/ffffff/ff0000.png")
```
It is fine to update properties anytime. However, updates have to be performed on the main thread. You use the getter on any thread.
There is no way to update only a few properties at a time. We suggest that you build it into your own wrapper instead.
info
Currently, JS function `componentWillUpdateProps` of the top level RN component will not be called after a prop update. However, you can access the new props in `componentDidMount` function.
### Passing properties from React Native to native[](#passing-properties-from-react-native-to-native "Direct link to Passing properties from React Native to native")
The problem exposing properties of native components is covered in detail in [this article](/docs/legacy/native-components-android.md#3-expose-view-property-setters-using-reactprop-or-reactpropgroup-annotation). In short, properties that are to be reflected in JavaScript needs to be exposed as setter method annotated with `@ReactProp`, then use them in React Native as if the component was an ordinary React Native component.
### Limits of properties[](#limits-of-properties "Direct link to Limits of properties")
The main drawback of cross-language properties is that they do not support callbacks, which would allow us to handle bottom-up data bindings. Imagine you have a small RN view that you want to be removed from the native parent view as a result of a JS action. There is no way to do that with props, as the information would need to go bottom-up.
Although we have a flavor of cross-language callbacks ([described here](/docs/legacy/native-modules-android.md#callbacks)), these callbacks are not always the thing we need. The main problem is that they are not intended to be passed as properties. Rather, this mechanism allows us to trigger a native action from JS, and handle the result of that action in JS.
## Other ways of cross-language interaction (events and native modules)[](#other-ways-of-cross-language-interaction-events-and-native-modules "Direct link to Other ways of cross-language interaction (events and native modules)")
As stated in the previous chapter, using properties comes with some limitations. Sometimes properties are not enough to drive the logic of our app and we need a solution that gives more flexibility. This chapter covers other communication techniques available in React Native. They can be used for internal communication (between JS and native layers in RN) as well as for external communication (between RN and the 'pure native' part of your app).
React Native enables you to perform cross-language function calls. You can execute custom native code from JS and vice versa. Unfortunately, depending on the side we are working on, we achieve the same goal in different ways. For native - we use events mechanism to schedule an execution of a handler function in JS, while for React Native we directly call methods exported by native modules.
### Calling React Native functions from native (events)[](#calling-react-native-functions-from-native-events "Direct link to Calling React Native functions from native (events)")
Events are described in detail in [this article](/docs/legacy/native-components-android.md#events). Note that using events gives us no guarantees about execution time, as the event is handled on a separate thread.
Events are powerful, because they allow us to change React Native components without needing a reference to them. However, there are some pitfalls that you can fall into while using them:
* As events can be sent from anywhere, they can introduce spaghetti-style dependencies into your project.
* Events share namespace, which means that you may encounter some name collisions. Collisions will not be detected statically, which makes them hard to debug.
* If you use several instances of the same React Native component and you want to distinguish them from the perspective of your event, you'll likely need to introduce identifiers and pass them along with events (you can use the native view's `reactTag` as an identifier).
### Calling native functions from React Native (native modules)[](#calling-native-functions-from-react-native-native-modules "Direct link to Calling native functions from React Native (native modules)")
Native modules are Java/Kotlin classes that are available in JS. Typically one instance of each module is created per JS bridge. They can export arbitrary functions and constants to React Native. They have been covered in detail in [this article](/docs/legacy/native-modules-android.md).
warning
All native modules share the same namespace. Watch out for name collisions when creating new ones.
---
# Source: https://reactnative.dev/docs/communication-ios.md
# Communication between native and React Native
In [Integrating with Existing Apps guide](/docs/integration-with-existing-apps.md) and [Native UI Components guide](/docs/legacy/native-components-ios.md) we learn how to embed React Native in a native component and vice versa. When we mix native and React Native components, we'll eventually find a need to communicate between these two worlds. Some ways to achieve that have been already mentioned in other guides. This article summarizes available techniques.
## Introduction[](#introduction "Direct link to Introduction")
React Native is inspired by React, so the basic idea of the information flow is similar. The flow in React is one-directional. We maintain a hierarchy of components, in which each component depends only on its parent and its own internal state. We do this with properties: data is passed from a parent to its children in a top-down manner. If an ancestor component relies on the state of its descendant, one should pass down a callback to be used by the descendant to update the ancestor.
The same concept applies to React Native. As long as we are building our application purely within the framework, we can drive our app with properties and callbacks. But, when we mix React Native and native components, we need some specific, cross-language mechanisms that would allow us to pass information between them.
## Properties[](#properties "Direct link to Properties")
Properties are the most straightforward way of cross-component communication. So we need a way to pass properties both from native to React Native, and from React Native to native.
### Passing properties from native to React Native[](#passing-properties-from-native-to-react-native "Direct link to Passing properties from native to React Native")
In order to embed a React Native view in a native component, we use `RCTRootView`. `RCTRootView` is a `UIView` that holds a React Native app. It also provides an interface between native side and the hosted app.
`RCTRootView` has an initializer that allows you to pass arbitrary properties down to the React Native app. The `initialProperties` parameter has to be an instance of `NSDictionary`. The dictionary is internally converted into a JSON object that the top-level JS component can reference.
objectivec
```
NSArray *imageList = @[@"https://dummyimage.com/600x400/ffffff/000000.png",
@"https://dummyimage.com/600x400/000000/ffffff.png"];
NSDictionary *props = @{@"images" : imageList};
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"ImageBrowserApp"
initialProperties:props];
```
tsx
```
import React from 'react';
import {View, Image} from 'react-native';
export default class ImageBrowserApp extends React.Component {
renderImage(imgURI) {
return ;
}
render() {
return {this.props.images.map(this.renderImage)};
}
}
```
`RCTRootView` also provides a read-write property `appProperties`. After `appProperties` is set, the React Native app is re-rendered with new properties. The update is only performed when the new updated properties differ from the previous ones.
objectivec
```
NSArray *imageList = @[@"https://dummyimage.com/600x400/ff0000/000000.png",
@"https://dummyimage.com/600x400/ffffff/ff0000.png"];
rootView.appProperties = @{@"images" : imageList};
```
It is fine to update properties anytime. However, updates have to be performed on the main thread. You use the getter on any thread.
note
Currently, there is a known issue where setting appProperties during the bridge startup, the change can be lost. See for more information.
There is no way to update only a few properties at a time. We suggest that you build it into your own wrapper instead.
### Passing properties from React Native to native[](#passing-properties-from-react-native-to-native "Direct link to Passing properties from React Native to native")
The problem exposing properties of native components is covered in detail in [this article](/docs/legacy/native-components-ios.md#properties). In short, export properties with `RCT_CUSTOM_VIEW_PROPERTY` macro in your custom native component, then use them in React Native as if the component was an ordinary React Native component.
### Limits of properties[](#limits-of-properties "Direct link to Limits of properties")
The main drawback of cross-language properties is that they do not support callbacks, which would allow us to handle bottom-up data bindings. Imagine you have a small RN view that you want to be removed from the native parent view as a result of a JS action. There is no way to do that with props, as the information would need to go bottom-up.
Although we have a flavor of cross-language callbacks ([described here](/docs/legacy/native-modules-ios.md#callbacks)), these callbacks are not always the thing we need. The main problem is that they are not intended to be passed as properties. Rather, this mechanism allows us to trigger a native action from JS, and handle the result of that action in JS.
## Other ways of cross-language interaction (events and native modules)[](#other-ways-of-cross-language-interaction-events-and-native-modules "Direct link to Other ways of cross-language interaction (events and native modules)")
As stated in the previous chapter, using properties comes with some limitations. Sometimes properties are not enough to drive the logic of our app and we need a solution that gives more flexibility. This chapter covers other communication techniques available in React Native. They can be used for internal communication (between JS and native layers in RN) as well as for external communication (between RN and the 'pure native' part of your app).
React Native enables you to perform cross-language function calls. You can execute custom native code from JS and vice versa. Unfortunately, depending on the side we are working on, we achieve the same goal in different ways. For native - we use events mechanism to schedule an execution of a handler function in JS, while for React Native we directly call methods exported by native modules.
### Calling React Native functions from native (events)[](#calling-react-native-functions-from-native-events "Direct link to Calling React Native functions from native (events)")
Events are described in detail in [this article](/docs/legacy/native-components-ios.md#events). Note that using events gives us no guarantees about execution time, as the event is handled on a separate thread.
Events are powerful, because they allow us to change React Native components without needing a reference to them. However, there are some pitfalls that you can fall into while using them:
* As events can be sent from anywhere, they can introduce spaghetti-style dependencies into your project.
* Events share namespace, which means that you may encounter some name collisions. Collisions will not be detected statically, which makes them hard to debug.
* If you use several instances of the same React Native component and you want to distinguish them from the perspective of your event, you'll likely need to introduce identifiers and pass them along with events (you can use the native view's `reactTag` as an identifier).
The common pattern we use when embedding native in React Native is to make the native component's RCTViewManager a delegate for the views, sending events back to JavaScript via the bridge. This keeps related event calls in one place.
### Calling native functions from React Native (native modules)[](#calling-native-functions-from-react-native-native-modules "Direct link to Calling native functions from React Native (native modules)")
Native modules are Objective-C classes that are available in JS. Typically one instance of each module is created per JS bridge. They can export arbitrary functions and constants to React Native. They have been covered in detail in [this article](/docs/legacy/native-modules-ios.md#content).
The fact that native modules are singletons limits the mechanism in the context of embedding. Let's say we have a React Native component embedded in a native view and we want to update the native, parent view. Using the native module mechanism, we would export a function that not only takes expected arguments, but also an identifier of the parent native view. The identifier would be used to retrieve a reference to the parent view to update. That said, we would need to keep a mapping from identifiers to native views in the module.
Although this solution is complex, it is used in `RCTUIManager`, which is an internal React Native class that manages all React Native views.
Native modules can also be used to expose existing native libraries to JS. The [Geolocation library](https://github.com/michalchudziak/react-native-geolocation) is a living example of the idea.
caution
All native modules share the same namespace. Watch out for name collisions when creating new ones.
## Layout computation flow[](#layout-computation-flow "Direct link to Layout computation flow")
When integrating native and React Native, we also need a way to consolidate two different layout systems. This section covers common layout problems and provides a brief description of mechanisms to address them.
### Layout of a native component embedded in React Native[](#layout-of-a-native-component-embedded-in-react-native "Direct link to Layout of a native component embedded in React Native")
This case is covered in [this article](/docs/legacy/native-components-ios.md#styles). To summarize, since all our native react views are subclasses of `UIView`, most style and size attributes will work like you would expect out of the box.
### Layout of a React Native component embedded in native[](#layout-of-a-react-native-component-embedded-in-native "Direct link to Layout of a React Native component embedded in native")
#### React Native content with fixed size[](#react-native-content-with-fixed-size "Direct link to React Native content with fixed size")
The general scenario is when we have a React Native app with a fixed size, which is known to the native side. In particular, a full-screen React Native view falls into this case. If we want a smaller root view, we can explicitly set RCTRootView's frame.
For instance, to make an RN app 200 (logical) pixels high, and the hosting view's width wide, we could do:
SomeViewController.m
```
- (void)viewDidLoad
{
[...]
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:appName
initialProperties:props];
rootView.frame = CGRectMake(0, 0, self.view.width, 200);
[self.view addSubview:rootView];
}
```
When we have a fixed size root view, we need to respect its bounds on the JS side. In other words, we need to ensure that the React Native content can be contained within the fixed-size root view. The easiest way to ensure this is to use Flexbox layout. If you use absolute positioning, and React components are visible outside the root view's bounds, you'll get overlap with native views, causing some features to behave unexpectedly. For instance, 'TouchableHighlight' will not highlight your touches outside the root view's bounds.
It's totally fine to update root view's size dynamically by re-setting its frame property. React Native will take care of the content's layout.
#### React Native content with flexible size[](#react-native-content-with-flexible-size "Direct link to React Native content with flexible size")
In some cases we'd like to render content of initially unknown size. Let's say the size will be defined dynamically in JS. We have two solutions to this problem.
1. You can wrap your React Native view in a `ScrollView` component. This guarantees that your content will always be available and it won't overlap with native views.
2. React Native allows you to determine, in JS, the size of the RN app and provide it to the owner of the hosting `RCTRootView`. The owner is then responsible for re-laying out the subviews and keeping the UI consistent. We achieve this with `RCTRootView`'s flexibility modes.
`RCTRootView` supports 4 different size flexibility modes:
RCTRootView\.h
```
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
RCTRootViewSizeFlexibilityNone = 0,
RCTRootViewSizeFlexibilityWidth,
RCTRootViewSizeFlexibilityHeight,
RCTRootViewSizeFlexibilityWidthAndHeight,
};
```
`RCTRootViewSizeFlexibilityNone` is the default value, which makes a root view's size fixed (but it still can be updated with `setFrame:`). The other three modes allow us to track React Native content's size updates. For instance, setting mode to `RCTRootViewSizeFlexibilityHeight` will cause React Native to measure the content's height and pass that information back to `RCTRootView`'s delegate. An arbitrary action can be performed within the delegate, including setting the root view's frame, so the content fits. The delegate is called only when the size of the content has changed.
caution
Making a dimension flexible in both JS and native leads to undefined behavior. For example - don't make a top-level React component's width flexible (with `flexbox`) while you're using `RCTRootViewSizeFlexibilityWidth` on the hosting `RCTRootView`.
Let's look at an example.
FlexibleSizeExampleView\.m
```
- (instancetype)initWithFrame:(CGRect)frame
{
[...]
_rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"FlexibilityExampleApp"
initialProperties:@{}];
_rootView.delegate = self;
_rootView.sizeFlexibility = RCTRootViewSizeFlexibilityHeight;
_rootView.frame = CGRectMake(0, 0, self.frame.size.width, 0);
}
#pragma mark - RCTRootViewDelegate
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView
{
CGRect newFrame = rootView.frame;
newFrame.size = rootView.intrinsicContentSize;
rootView.frame = newFrame;
}
```
In the example we have a `FlexibleSizeExampleView` view that holds a root view. We create the root view, initialize it and set the delegate. The delegate will handle size updates. Then, we set the root view's size flexibility to `RCTRootViewSizeFlexibilityHeight`, which means that `rootViewDidChangeIntrinsicSize:` method will be called every time the React Native content changes its height. Finally, we set the root view's width and position. Note that we set there height as well, but it has no effect as we made the height RN-dependent.
You can checkout full source code of the example [here](https://github.com/facebook/react-native/blob/main/packages/rn-tester/RNTester/NativeExampleViews/FlexibleSizeExampleView.mm).
It's fine to change root view's size flexibility mode dynamically. Changing flexibility mode of a root view will schedule a layout recalculation and the delegate `rootViewDidChangeIntrinsicSize:` method will be called once the content size is known.
note
React Native layout calculation is performed on a separate thread, while native UI view updates are done on the main thread. This may cause temporary UI inconsistencies between native and React Native. This is a known problem and our team is working on synchronizing UI updates coming from different sources.
note
React Native does not perform any layout calculations until the root view becomes a subview of some other views. If you want to hide React Native view until its dimensions are known, add the root view as a subview and make it initially hidden (use `UIView`'s `hidden` property). Then change its visibility in the delegate method.
---
# Source: https://reactnative.dev/community/communities.md
# Communities
The React Native ecosystem is far and wide, and people can be part of it in many forms; here you will find but a partial list of different ways one developer can be part of it. If you know of other, or want to help expand this page, [submit a PR](https://github.com/facebook/react-native-website/pulls?q=is%3Apr+is%3Aopen+sort%3Aupdated-desc)!
### Local communities[](#local-communities "Direct link to Local communities")
There are a lot of React Native gatherings that happen around the world. Often there is React Native content in React meetups as well, use tools like [Meetup](https://www.meetup.com/topics/react-native/) and [Eventbrite](https://www.eventbrite.co.uk/d/online/react-native/?page=1) to find out recent events in your area - or start one!
### Company-based communities[](#company-based-communities "Direct link to Company-based communities")
Some companies actively involved in the React Native have also their own communication channels focused towards the projects they maintain:
* [Callstack.io's](https://www.callstack.com/) [Discord server](https://discordapp.com/invite/zwR2Cdh)
* [Invertase.io's (e.g. React Native Firebase)](https://invertase.io/) [Discord server](https://discord.gg/C9aK28N)
* [Infinite Red's](https://infinite.red/) [Slack Group](https://community.infinite.red/)
* [Expo's](https://expo.dev/) [Discord server](https://chat.expo.dev/)
### Independent communities[](#independent-communities "Direct link to Independent communities")
Organic communities of React Native developers, not sponsored by a business with a commercial interest.
* [The Reactiflux community](https://reactiflux.com) on [Discord](https://discord.gg/reactiflux)
### Content sharing[](#content-sharing "Direct link to Content sharing")
React Native tagged content can be found on many platforms, such as:
* [DevTo community](https://dev.to/t/reactnative)
* [Medium](https://medium.com/tag/react-native)
* [Hashnode](https://hashnode.com/n/react-native)
* [Hacker News](https://hn.algolia.com/?q=react-native)
* [r/reactnative/](https://www.reddit.com/r/reactnative/)
These are places where you can share React Native projects, articles and tutorials as well as start discussions and ask for feedback on React Native related topics. (but remember to give some love to the [main documentation](https://github.com/facebook/react-native-website) too!)
---
# Source: https://reactnative.dev/docs/components-and-apis.md
# Core Components and APIs
React Native provides a number of built-in [Core Components](/docs/intro-react-native-components.md) ready for you to use in your app. You can find them all in the left sidebar (or menu above, if you are on a narrow screen). If you're not sure where to get started, take a look at the following categories:
* [Basic Components](/docs/components-and-apis.md#basic-components)
* [User Interface](/docs/components-and-apis.md#user-interface)
* [List Views](/docs/components-and-apis.md#list-views)
* [Android-specific](/docs/components-and-apis.md#android-components-and-apis)
* [iOS-specific](/docs/components-and-apis.md#ios-components-and-apis)
* [Others](/docs/components-and-apis.md#others)
You're not limited to the components and APIs bundled with React Native. React Native has a community of thousands of developers. If you're looking for a library that does something specific, please refer to [this guide about finding libraries](/docs/libraries.md#finding-libraries).
## Basic Components[](#basic-components "Direct link to Basic Components")
Most apps will end up using one or more of these basic components.
### [View](./view)
[The most fundamental component for building a UI.](./view)
### [Text](./text)
[A component for displaying text.](./text)
### [Image](./image)
[A component for displaying images.](./image)
### [TextInput](./textinput)
[A component for inputting text into the app via a keyboard.](./textinput)
### [Pressable](./pressable)
[A wrapper component that can detect various stages of press interactions on any of its children.](./pressable)
### [ScrollView](./scrollview)
[Provides a scrolling container that can host multiple components and views.](./scrollview)
### [StyleSheet](./stylesheet)
[Provides an abstraction layer similar to CSS stylesheets.](./stylesheet)
## User Interface[](#user-interface "Direct link to User Interface")
These common user interface controls will render on any platform.
### [Button](./button)
[A basic button component for handling touches that should render nicely on any platform.](./button)
### [Switch](./switch)
[Renders a boolean input.](./switch)
## List Views[](#list-views "Direct link to List Views")
Unlike the more generic [`ScrollView`](/docs/scrollview.md), the following list view components only render elements that are currently showing on the screen. This makes them a performant choice for displaying long lists of data.
### [FlatList](./flatlist)
[A component for rendering performant scrollable lists.](./flatlist)
### [SectionList](./sectionlist)
[Like `FlatList`, but for sectioned lists.](./sectionlist)
## Android Components and APIs[](#android-components-and-apis "Direct link to Android Components and APIs")
Many of the following components provide wrappers for commonly used Android classes.
### [BackHandler](./backhandler)
[Detect hardware button presses for back navigation.](./backhandler)
### [DrawerLayoutAndroid](./drawerlayoutandroid)
[Renders a `DrawerLayout` on Android.](./drawerlayoutandroid)
### [PermissionsAndroid](./permissionsandroid)
[Provides access to the permissions model introduced in Android M.](./permissionsandroid)
### [ToastAndroid](./toastandroid)
[Create an Android Toast alert.](./toastandroid)
## iOS Components and APIs[](#ios-components-and-apis "Direct link to iOS Components and APIs")
Many of the following components provide wrappers for commonly used UIKit classes.
### [ActionSheetIOS](./actionsheetios)
[API to display an iOS action sheet or share sheet.](./actionsheetios)
## Others[](#others "Direct link to Others")
These components may be useful for certain applications. For an exhaustive list of components and APIs, check out the sidebar to the left (or menu above, if you are on a narrow screen).
### [ActivityIndicator](./activityindicator)
[Displays a circular loading indicator.](./activityindicator)
### [Alert](./alert)
[Launches an alert dialog with the specified title and message.](./alert)
### [Animated](./animated)
[A library for creating fluid, powerful animations that are easy to build and maintain.](./animated)
### [Dimensions](./dimensions)
[Provides an interface for getting device dimensions.](./dimensions)
### [KeyboardAvoidingView](./keyboardavoidingview)
[Provides a view that moves out of the way of the virtual keyboard automatically.](./keyboardavoidingview)
### [Linking](./linking)
[Provides a general interface to interact with both incoming and outgoing app links.](./linking)
### [Modal](./modal)
[Provides a simple way to present content above an enclosing view.](./modal)
### [PixelRatio](./pixelratio)
[Provides access to the device pixel density.](./pixelratio)
### [RefreshControl](./refreshcontrol)
[This component is used inside a `ScrollView` to add pull to refresh functionality.](./refreshcontrol)
### [StatusBar](./statusbar)
[Component to control the app status bar.](./statusbar)
---
# Source: https://reactnative.dev/contributing/contribution-license-agreement.md
# Contribution License Agreement
You must sign a Contribution License Agreement (CLA) before your pull request can be merged. This a one-time requirement for Meta projects in GitHub. You can read more about [Contributor License Agreements (CLA)](https://en.wikipedia.org/wiki/Contributor_License_Agreement) on Wikipedia.
However, you don't have to do this up-front. We welcome you to follow, fork, and submit a pull request.
When your pull request is created, it is classified by the Facebook GitHub bot. If you have not signed a CLA, the bot will provide instructions for [signing a CLA](https://code.facebook.com/cla) before your pull request can be considered eligible for merging. Once you have done so, the current and all future pull requests will be labelled as "CLA Signed".
Signing the CLA might sound scary, but it's actually very simple and can be done in less than a minute.
---
# Source: https://reactnative.dev/docs/the-new-architecture/create-module-library.md
# Create a Library for Your Module
React Native has a rich ecosystem of libraries to solve common problems. We collect React Native libraries in the [reactnative.directory](https://reactnative.directory) website, and this is a great resource to bookmark for every React Native developer.
Sometimes, you might be working on a module that is worth extracting in a separate library for code reuse. This can be a library that you want to reuse in all your apps, a library that you want to distribute to the ecosystem as an open source component, or even a library you'd like to sell.
In this guide, you'll learn:
* how to extract a module into a library
* how to distribute the library using NPM
## Extract the Module into a Library[](#extract-the-module-into-a-library "Direct link to Extract the Module into a Library")
You can use the [`create-react-native-library`](https://callstack.github.io/react-native-builder-bob/create) tool to create a new library. This tool sets up a new library with all the boilerplate code that is needed: all the configuration files and all files required by the various platforms. It also comes with a nice interactive menu to guide you through the creation of the library.
To extract a module into a separate library, you can follow these steps:
1. Create the new library
2. Move the code from the App to the Library
3. Update the code to reflect the new structure
4. Publish it.
### 1. Create a Library[](#1-create-a-library "Direct link to 1. Create a Library")
1. Start the creation process by running the command:
sh
```
npx create-react-native-library@latest
```
2. Add a name for your module. It must be a valid npm name, so it should be all lowercase. You can use `-` to separate words.
3. Add a description for the package.
4. Continue filling the form until you reach the question *"What type of library do you want to develop?"* 
5. For the sake of this guide, select the *Turbo module* option. Notice that you can create libraries for both New Architecture and Legacy Architecture.
6. Then, you can choose whether you want a library that access the platform (Kotlin & Objective-C) or a shared C++ library (C++ for Android and iOS).
7. Finally, select the `Test App` as last option. This option creates the library with a separate app already configured within the library folder.
Once the interactive prompt is done, the tool creates a folder whose structure looks like this in Visual Studio Code:

Feel free to explore the code that has been created for you. However, the most important parts:
* The `android` folder: this is where the Android code lives
* The `cpp` folder: this is where the c++ code lives
* The `ios` folder: this is where the iOS code lives
* The `src` folder: this is where the JS code lives.
The `package.json` is already configured with all the information that we provided to the `create-react-native-library` tool, including the name and the description of the package. Notice that the `package.json` is also already configured to run Codegen.
json
```
"codegenConfig": {
"name": "RNSpec",
"type": "all",
"jsSrcsDir": "src",
"outputDir": {
"ios": "ios/generated",
"android": "android/generated"
},
"android": {
"javaPackageName": "com."
}
},
```
Finally, the library contains already all the infrastructure to let the library be linked with iOS and Android.
### 2. Copy the Code over from Your App[](#2-copy-the-code-over-from-your-app "Direct link to 2. Copy the Code over from Your App")
The rest of the guide assumes that you have a local Turbo Native Module in your app, created following the guidelines shown in the other guides in the website: platform specific Turbo Native Modules, or [cross-platform Turbo Native Modules](/docs/the-new-architecture/pure-cxx-modules.md). But it works also for Components and legacy architecture modules and components. You'll have to adapt the files you need to copy and update.
1. **\[Not required for legacy architecture modules and components]** Move the code you have in the `specs` folder in your app into the `src` folder created by the `create-react-native-library` folder.
2. Update the `index.ts` file to properly export the Turbo Native Module spec so that it is accessible from the library. For example:
ts
```
import NativeSampleModule from './NativeSampleModule';
export default NativeSampleModule;
```
3. Copy the native module over:
* Replace the code in the `android/src/main/java/com/` with the code you wrote in the app for your native module, if any.
* Replace the code in the `ios` folder with the code you wrote in your app for your native module, if any.
* Replace the code in the `cpp` folder with the code you wrote in your app for your native module, if any.
4. **\[Not required for legacy architecture modules and components]** Update all the references from the previous spec name to the new spec name, the one that is defined in the `codegenConfig` field of the library's `package.json`. For example, if in the app `package.json` you set `AppSpecs` as `codegenConfig.name` and in the library it is called `RNNativeSampleModuleSpec`, you have to replace every occurrence of `AppSpecs` with `RNNativeSampleModuleSpec`.
That's it! You have moved all the required code out of your app and in a separate library.
## Testing your Library[](#testing-your-library "Direct link to Testing your Library")
The `create-react-native-library` comes with a useful example application that is already configured to work properly with the library. This is a great way to test it!
If you look at the `example` folder, you can find the same structure of a new React Native application that you can create from the [`react-native-community/template`](https://github.com/react-native-community/template).
To test your library:
1. Navigate to the `example` folder.
2. Run `yarn install` to install all the dependencies.
3. For iOS only, you need to install CocoaPods: `cd ios && pod install`.
4. Build and run Android with `yarn android` from the `example` folder.
5. Build and run iOS with `yarn ios` from the `example` folder.
## Use your library as a Local Module[](#use-your-library-as-a-local-module "Direct link to Use your library as a Local Module")
There are some scenario where you might want to reuse your library as a local module for your applications, without publishing it to NPM.
In this case, you might end up in a scenario where you have your library sitting as a sibling of your apps.
shell
```
Development
├── App
└── Library
```
You can use the library created with `create-react-native-library` also in this case.
1. add you library to your app by navigating into the `App` folder and running `yarn add ../Library`.
2. For iOS only, navigate in the `App/ios` folder and run `bundle exec pod install` to install your dependencies.
3. Update the `App.tsx` code to import the code in your library. For example:
tsx
```
import NativeSampleModule from '../Library/src/index';
```
If you run your app right now, Metro would not find the JS files that it needs to serve to the app. That's because metro will be running starting from the `App` folder and it would not have access to the JS files located in the `Library` folder. To fix this, let's update the `metro.config.js` file as it follows
diff
```
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
/**
* Metro configuration
* https://reactnative.dev/docs/metro
*
* @type {import('metro-config').MetroConfig}
*/
+ const path = require('path');
- const config = {}
+ const config = {
+ // Make Metro able to resolve required external dependencies
+ watchFolders: [
+ path.resolve(__dirname, '../Library'),
+ ],
+ resolver: {
+ extraNodeModules: {
+ 'react-native': path.resolve(__dirname, 'node_modules/react-native'),
+ },
+ },
+};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);
```
The `watchFolders` configs tells Metro to watch for files and changes in some additional paths, in this case to the `../Library` path, which contains the `src/index` file you need. The `resolver`property is required to feed to the library the React Native code used by the app. The library might refer and import code from React Native: without the additional resolver, the imports in the library will fail.
At this point, you can build and run your app as usual:
* Build and run Android with `yarn android` from the `example` folder.
* Build and run iOS with `yarn ios` from the `example` folder.
## Publish the Library on NPM[](#publish-the-library-on-npm "Direct link to Publish the Library on NPM")
The setup to publish everything on NPM is already in place, thanks to `create-react-native-library`.
1. Install the dependencies in your module `yarn install`.
2. Build the library running `yarn prepare`.
3. Release it with `yarn release`.
After a while, you'll find your library on NPM. To verify that, run:
bash
```
npm view
```
where `package.name` is the `name` you set up in the `package.json` file during the initialization of the library.
Now, you can install the library in your application by running:
bash
```
yarn add
```
note
For iOS only, whenever you install a new module with some native code, you have to reinstall CocoaPods, by running `bundle exec pod install` (recommended) or `pod install` if you are not using Ruby's Bundler (not recommended).
Congratulations! You published your first React Native library.
---
# Source: https://reactnative.dev/docs/the-new-architecture/custom-cxx-types.md
# Advanced: Custom C++ Types
note
This guide assumes that you are familiar with the [**Pure C++ Turbo Native Modules**](/docs/the-new-architecture/pure-cxx-modules.md) guide. This will build on top of that guide.
C++ Turbo Native Modules support [bridging functionality](https://github.com/facebook/react-native/tree/main/packages/react-native/ReactCommon/react/bridging) for most `std::` standard types. You can use most of those types in your modules without any additional code required.
If you want to add support for new and custom types in your app or library, you need to provide the necessary `bridging` header file.
## Adding a New Custom: Int64[](#adding-a-new-custom-int64 "Direct link to Adding a New Custom: Int64")
C++ Turbo Native Modules don't support `int64_t` numbers yet - because JavaScript doesn't support numbers greater 2^53. To represent numbers greater than 2^53, we can use a `string` type in JS and automatically convert it to `int64_t` in C++.
### 1. Create the Bridging Header file[](#1-create-the-bridging-header-file "Direct link to 1. Create the Bridging Header file")
The first step to support a new custom type is to define the bridging header that takes care of converting the type **from** the JS representation to the C++ representation, and from the C++ representation **to** the JS one.
1. In the `shared` folder, add a new file called `Int64.h`
2. Add the following code to that file:
Int64.h
```
#pragma once
#include
namespace facebook::react {
template <>
struct Bridging {
// Converts from the JS representation to the C++ representation
static int64_t fromJs(jsi::Runtime &rt, const jsi::String &value) {
try {
size_t pos;
auto str = value.utf8(rt);
auto num = std::stoll(str, &pos);
if (pos != str.size()) {
throw std::invalid_argument("Invalid number"); // don't support alphanumeric strings
}
return num;
} catch (const std::logic_error &e) {
throw jsi::JSError(rt, e.what());
}
}
// Converts from the C++ representation to the JS representation
static jsi::String toJs(jsi::Runtime &rt, int64_t value) {
return bridging::toJs(rt, std::to_string(value));
}
};
}
```
The key components for your custom bridging header are:
* Explicit specialization of the `Bridging` struct for your custom type. In this case, the template specify the `int64_t` type.
* A `fromJs` function to convert from the JS representation to the C++ representation
* A `toJs` function to convert from the C++ representation to the JS representation
note
On iOS, remember to add the `Int64.h` file to the Xcode project.
### 2. Modify the JS Spec[](#2-modify-the-js-spec "Direct link to 2. Modify the JS Spec")
Now, we can modify the JS spec to add a method that uses the new type. As usual, we can use either Flow or TypeScript for our specs.
1. Open the `specs/NativeSampleTurbomodule`
2. Modify the spec as follows:
* TypeScript
* Flow
NativeSampleModule.ts
```
import {TurboModule, TurboModuleRegistry} from 'react-native';
export interface Spec extends TurboModule {
readonly reverseString: (input: string) => string;
+ readonly cubicRoot: (input: string) => number;
}
export default TurboModuleRegistry.getEnforcing(
'NativeSampleModule',
);
```
NativeSampleModule.js
```
// @flow
import type {TurboModule} from 'react-native';
import { TurboModuleRegistry } from "react-native";
export interface Spec extends TurboModule {
+reverseString: (input: string) => string;
+ +cubicRoot: (input: string) => number;
}
export default (TurboModuleRegistry.getEnforcing(
"NativeSampleModule"
): Spec);
```
In this files, we are defining the function that needs to be implemented in C++.
### 3. Implement the Native Code[](#3-implement-the-native-code "Direct link to 3. Implement the Native Code")
Now, we need to implement the function that we declared in the JS specification.
1. Open the `specs/NativeSampleModule.h` file and apply the following changes:
NativeSampleModule.h
```
#pragma once
#include
#include
#include
+ #include "Int64.h"
namespace facebook::react {
class NativeSampleModule : public NativeSampleModuleCxxSpec {
public:
NativeSampleModule(std::shared_ptr jsInvoker);
std::string reverseString(jsi::Runtime& rt, std::string input);
+ int32_t cubicRoot(jsi::Runtime& rt, int64_t input);
};
} // namespace facebook::react
```
2. Open the `specs/NativeSampleModule.cpp` file and apply the implement the new function:
NativeSampleModule.cpp
```
#include "NativeSampleModule.h"
+ #include
namespace facebook::react {
NativeSampleModule::NativeSampleModule(std::shared_ptr jsInvoker)
: NativeSampleModuleCxxSpec(std::move(jsInvoker)) {}
std::string NativeSampleModule::reverseString(jsi::Runtime& rt, std::string input) {
return std::string(input.rbegin(), input.rend());
}
+int32_t NativeSampleModule::cubicRoot(jsi::Runtime& rt, int64_t input) {
+ return std::cbrt(input);
+}
} // namespace facebook::react
```
The implementation imports the `` C++ library to perform mathematical operations, then it implements the `cubicRoot` function using the `cbrt` primitive from the `` module.
### 4. Test your code in Your App[](#4-test-your-code-in-your-app "Direct link to 4. Test your code in Your App")
Now, we can test the code in our app.
First, we need to update the `App.tsx` file to use the new method from the TurboModule. Then, we can build our apps in Android and iOS.
1. Open the `App.tsx` code apply the following changes:
App.tsx
```
// ...
+ const [cubicSource, setCubicSource] = React.useState('')
+ const [cubicRoot, setCubicRoot] = React.useState(0)
return (
Welcome to C++ Turbo Native Module Example
Write down here the text you want to revertReversed text: {reversedValue}
+ For which number do you want to compute the Cubic Root?
+
+
);
}
//...
```
2. To test the app on Android, run `yarn android` from the root folder of your project.
3. To test the app on iOS, run `yarn ios` from the root folder of your project.
## Adding a New Structured Custom Type: Address[](#adding-a-new-structured-custom-type-address "Direct link to Adding a New Structured Custom Type: Address")
The approach above can be generalized to any kind of type. For structured types, React Native provides some helper functions that make it easier to bridge them from JS to C++ and vice versa.
Let's assume that we want to bridge a custom `Address` type with the following properties:
ts
```
interface Address {
street: string;
num: number;
isInUS: boolean;
}
```
### 1. Define the type in the specs[](#1-define-the-type-in-the-specs "Direct link to 1. Define the type in the specs")
For the first step, let's define the new custom type in the JS specs, so that Codegen can output all the supporting code. In this way, we don't have to manually write the code.
1. Open the `specs/NativeSampleModule` file and add the following changes.
* TypeScript
* Flow
NativeSampleModule (Add Address type and validateAddress function)
```
import {TurboModule, TurboModuleRegistry} from 'react-native';
+export type Address = {
+ street: string,
+ num: number,
+ isInUS: boolean,
+};
export interface Spec extends TurboModule {
readonly reverseString: (input: string) => string;
+ readonly validateAddress: (input: Address) => boolean;
}
export default TurboModuleRegistry.getEnforcing(
'NativeSampleModule',
);
```
NativeSampleModule (Add Address type and validateAddress function)
```
// @flow
import type {TurboModule} from 'react-native';
import { TurboModuleRegistry } from "react-native";
+export type Address = {
+ street: string,
+ num: number,
+ isInUS: boolean,
+};
export interface Spec extends TurboModule {
+reverseString: (input: string) => string;
+ +validateAddress: (input: Address) => boolean;
}
export default (TurboModuleRegistry.getEnforcing(
"NativeSampleModule"
): Spec);
```
This code defines the new `Address` type and defines a new `validateAddress` function for the Turbo Native Module. Notice that the `validateFunction` requires an `Address` object as parameter.
It is also possible to have functions that return custom types.
### 2. Define the bridging code[](#2-define-the-bridging-code "Direct link to 2. Define the bridging code")
From the `Address` type defined in the specs, Codegen will generate two helper types: `NativeSampleModuleAddress` and `NativeSampleModuleAddressBridging`.
The first type is the definition of the `Address`. The second type contains all the infrastructure to bridge the custom type from JS to C++ and vice versa. The only extra step we need to add is to define the `Bridging` structure that extends the `NativeSampleModuleAddressBridging` type.
1. Open the `shared/NativeSampleModule.h` file
2. Add the following code in the file:
NativeSampleModule.h (Bridging the Address type)
```
#include "Int64.h"
#include
#include
namespace facebook::react {
+ using Address = NativeSampleModuleAddress;
+ template <>
+ struct Bridging
+ : NativeSampleModuleAddressBridging {};
// ...
}
```
This code defines an `Address` typealias for the generic type `NativeSampleModuleAddress`. **The order of the generics matters**: the first template argument refers to the first data type of the struct, the second refers to the second, and so forth.
Then, the code adds the `Bridging` specialization for the new `Address` type, by extending `NativeSampleModuleAddressBridging` that is generated by Codegen.
note
There is a convention that is followed to generate this types:
* The first part of the name is always the type of the module. `NativeSampleModule`, in this example.
* The second part of the name is always the name of the JS type defined in the specs. `Address`, in this example.
### 3. Implement the Native Code[](#3-implement-the-native-code-1 "Direct link to 3. Implement the Native Code")
Now, we need to implement the `validateAddress` function in C++. First, we need to add the function declaration into the `.h` file, and then we can implement it in the `.cpp` file.
1. Open the `shared/NativeSampleModule.h` file and add the function definition
NativeSampleModule.h (validateAddress function prototype)
```
std::string reverseString(jsi::Runtime& rt, std::string input);
+ bool validateAddress(jsi::Runtime &rt, jsi::Object input);
};
} // namespace facebook::react
```
2. Open the `shared/NativeSampleModule.cpp` file and add the function implementation
NativeSampleModule.cpp (validateAddress implementation)
```
bool NativeSampleModule::validateAddress(jsi::Runtime &rt, jsi::Object input) {
std::string street = input.getProperty(rt, "street").asString(rt).utf8(rt);
int32_t number = input.getProperty(rt, "num").asNumber();
return !street.empty() && number > 0;
}
```
In the implementation, the object that represents the `Address` is a `jsi::Object`. To extract the values from this object, we need to use the accessors provided by `JSI`:
* `getProperty()` retrieves the property from and object by name.
* `asString()` converts the property to `jsi::String`.
* `utf8()` converts the `jsi::String` to a `std::string`.
* `asNumber()` converts the property to a `double`.
Once we manually parsed the object, we can implement the logic that we need.
note
If you want to learn more about `JSI` and how it works, have a look at this [great talk](https://youtu.be/oLmGInjKU2U?feature=shared) from App.JS 2024
### 4. Testing the code in the app[](#4-testing-the-code-in-the-app "Direct link to 4. Testing the code in the app")
To test the code in the app, we have to modify the `App.tsx` file.
1. Open the `App.tsx` file. Remove the content of the `App()` function.
2. Replace the body of the `App()` function with the following code:
App.tsx (App function body replacement)
```
const [street, setStreet] = React.useState('');
const [num, setNum] = React.useState('');
const [isValidAddress, setIsValidAddress] = React.useState<
boolean | null
>(null);
const onPress = () => {
let houseNum = parseInt(num, 10);
if (isNaN(houseNum)) {
houseNum = -1;
}
const address = {
street,
num: houseNum,
isInUS: false,
};
const result = SampleTurboModule.validateAddress(address);
setIsValidAddress(result);
};
return (
Welcome to C Turbo Native Module Example
Address:Number:
{isValidAddress != null && (
Your address is {isValidAddress ? 'valid' : 'not valid'}
)}
);
```
Congratulation! 🎉
You bridged your first types from JS to C++.
---
# Source: https://reactnative.dev/docs/datepickerandroid.md
# ❌ DatePickerAndroid
Removed from React Native
Use one of the [community packages](https://reactnative.directory/?search=datepicker) instead.
---
# Source: https://reactnative.dev/docs/datepickerios.md
# ❌ DatePickerIOS
Removed from React Native
Use one of the [community packages](https://reactnative.directory/?search=datepicker) instead.
---
# Source: https://reactnative.dev/docs/debugging-native-code.md
# Debugging Native Code
### Projects with Native Code Only
The following section only applies to projects with native code exposed. If you are using the managed Expo workflow, see the guide on [prebuild](https://docs.expo.dev/workflow/prebuild/) to use this API.
## Accessing Logs[](#accessing-logs "Direct link to Accessing Logs")
You can display the native logs for an iOS or Android app by using the following commands in a terminal while the app is running:
shell
```
# For Android:
npx react-native log-android
# Or, for iOS:
npx react-native log-ios
```
You may also access these through Debug > Open System Log… in the iOS Simulator or by running `adb logcat "*:S" ReactNative:V ReactNativeJS:V` in a terminal while an Android app is running on a device or emulator.
**💡 Custom Native Logs**
If you are writing a Native Module and want to add custom logs to your module for debugging purposes, you can use the following method:
#### Android (Java/Kotlin)[](#android-javakotlin "Direct link to Android (Java/Kotlin)")
In your native module, use the `Log` class to add logs that can be viewed in Logcat:
java
```
import android.util.Log;
private void log(String message) {
Log.d("YourModuleName", message);
}
```
To view these logs in Logcat, use this command, replacing `YourModuleName` with your custom tag:
shell
```
adb logcat "*:S" ReactNative:V ReactNativeJS:V YourModuleName:D
```
#### iOS (Objective-C/Swift)[](#ios-objective-cswift "Direct link to iOS (Objective-C/Swift)")
In your native module, use `NSLog` for custom logs:
objective-c
```
NSLog(@"YourModuleName: %@", message);
```
Or, in Swift:
swift
```
print("YourModuleName: \(message)")
```
These logs will appear in the Xcode console when running the app.
## Debugging in a Native IDE[](#debugging-in-a-native-ide "Direct link to Debugging in a Native IDE")
When working with native code, such as when writing native modules, you can launch the app from Android Studio or Xcode and take advantage of the native debugging features (setting up breakpoints, etc.) as you would in case of building a standard native app.
Another option is to run your application using the React Native CLI and attach the native debugger of the native IDE (Android Studio or Xcode) to the process.
### Android Studio[](#android-studio "Direct link to Android Studio")
On Android Studio you can do this by going on the "Run" option on the menu bar, clicking on "Attach to Process..." and selecting the running React Native app.
### Xcode[](#xcode "Direct link to Xcode")
On Xcode click on "Debug" on the top menu bar, select the "Attach to process" option, and select the application in the list of "Likely Targets".
---
# Source: https://reactnative.dev/docs/debugging-release-builds.md
# Debugging Release Builds
## Symbolicating a stack trace[](#symbolicating-a-stack-trace "Direct link to Symbolicating a stack trace")
If a React Native app throws an unhandled exception in a release build, the output may be obfuscated and hard to read.
shell
```
07-15 10:58:25.820 18979 18998 E AndroidRuntime: FATAL EXCEPTION: mqt_native_modules
07-15 10:58:25.820 18979 18998 E AndroidRuntime: Process: com.awesomeproject, PID: 18979 07-15 10:58:25.820 18979 18998 E AndroidRuntime: com.facebook.react.common.JavascriptException: Failed, js engine: hermes, stack:
07-15 10:58:25.820 18979 18998 E AndroidRuntime: p@1:132161
07-15 10:58:25.820 18979 18998 E AndroidRuntime: p@1:132084
07-15 10:58:25.820 18979 18998 E AndroidRuntime: f@1:131854
07-15 10:58:25.820 18979 18998 E AndroidRuntime: anonymous@1:131119
```
In the above stack trace, entries like `p@1:132161` are minified function names and bytecode offsets. To debug these calls, we want to translate these into file, line, and function name, e.g. `AwesomeProject/App.js:54:initializeMap`. This is known as **symbolication.**
You can symbolicate minified function names and bytecode like the above by passing the stack trace and a generated source map to [`metro-symbolicate`](https://www.npmjs.com/package/metro-symbolicate).
### Enabling source maps[](#enabling-source-maps "Direct link to Enabling source maps")
Source maps are required to symbolicate stack traces. Make sure that source maps are enabled within the build config for the target platform.
* Android
* iOS
info
On Android, source maps are **enabled** by default.
To enable source map generation, ensure the following `hermesFlags` are present in `android/app/build.gradle`.
groovy
```
react {
hermesFlags = ["-O", "-output-source-map"]
}
```
If done correctly you should see the output location of the source map during Metro build output.
text
```
Writing bundle output to:, android/app/build/generated/assets/react/release/index.android.bundle
Writing sourcemap output to:, android/app/build/intermediates/sourcemaps/react/release/index.android.bundle.packager.map
```
info
On iOS, source maps are **disabled** by default. Use the following instructions to enable them.
To enable source map generation:
* Open Xcode and edit the build phase "Bundle React Native code and images".
* Above the other exports, add a `SOURCEMAP_FILE` entry with the desired output path.
diff
```
+ export SOURCEMAP_FILE="$(pwd)/../main.jsbundle.map"
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
```
If done correctly you should see the output location of the source map during Metro build output.
text
```
Writing bundle output to:, Build/Intermediates.noindex/ArchiveIntermediates/application/BuildProductsPath/Release-iphoneos/main.jsbundle
Writing sourcemap output to:, Build/Intermediates.noindex/ArchiveIntermediates/application/BuildProductsPath/Release-iphoneos/main.jsbundle.map
```
### Using `metro-symbolicate`[](#using-metro-symbolicate "Direct link to using-metro-symbolicate")
With source maps being generated, we can now translate our stack traces.
shell
```
# Print usage instructions
npx metro-symbolicate
# From a file containing the stack trace
npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map < stacktrace.txt
# From adb logcat (Android)
adb logcat -d | npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map
```
### Notes on source maps[](#notes-on-source-maps "Direct link to Notes on source maps")
* Multiple source maps may be generated by the build process. Make sure to use the one in the location shown in the examples.
* Make sure that the source map you use corresponds to the exact commit of the crashing app. Small changes in source code can cause large differences in offsets.
* If `metro-symbolicate` exits immediately with success, make sure the input comes from a pipe or redirection and not from a terminal.
---
# Source: https://reactnative.dev/docs/debugging.md
# Debugging Basics
note
Debugging features, such as the Dev Menu, LogBox, and React Native DevTools are disabled in release (production) builds.
## Opening the Dev Menu[](#opening-the-dev-menu "Direct link to Opening the Dev Menu")
React Native provides an in-app developer menu providing access to debugging features. You can access the Dev Menu by shaking your device or via keyboard shortcuts:
* iOS Simulator: `Ctrl` + `Cmd ⌘` + `Z` (or Device > Shake)
* Android emulators: `Cmd ⌘` + `M` (macOS) or `Ctrl` + `M` (Windows and Linux)
Alternative (Android): `adb shell input keyevent 82`.

## Opening DevTools[](#opening-devtools "Direct link to Opening DevTools")
[React Native DevTools](/docs/react-native-devtools.md) is our built-in debugger for React Native. It allows you to inspect and understand how your JavaScript code is running, similar to a web browser.
To open DevTools, either:
* Select "Open DevTools" in the Dev Menu.
* Press `j` from the CLI.

On first launch, DevTools will open to a welcome panel, along with an open console drawer where you can view logs and interact with the JavaScript runtime. From the top of the window, you can navigate to other panels, including the integrated React Components Inspector and Profiler.
Learn more in our [React Native DevTools guide](/docs/react-native-devtools.md).
## LogBox[](#logbox "Direct link to LogBox")
LogBox is an in-app tool that displays when warnings or errors are logged by your app.

### Fatal Errors[](#fatal-errors "Direct link to Fatal Errors")
When an unrecoverable error occurs, such as a JavaScript syntax error, LogBox will open with the location of the error. In this state, LogBox is not dismissable since your code cannot be executed. LogBox will automatically dismiss once the syntax error is fixed — either via Fast Refresh or after a manual reload.
### Console Errors and Warnings[](#console-errors-and-warnings "Direct link to Console Errors and Warnings")
Console errors and warnings are displayed as on-screen notifications with a red or yellow badge.
* **Errors** will display with a notification count. Tap the notification to see an expanded view and to paginate through other logs.
* **Warnings** will display a notification banner without details, prompting you to open React Native DevTools.
When React Native DevTools is open, all errors except fatal errors will be hidden to LogBox. We recommend using the Console panel within React Native DevTools as a source of truth, due to various LogBox options which can hide or adjust the level of certain logs.
**💡 Ignoring logs**
LogBox can be configured via the `LogBox` API.
js
```
import {LogBox} from 'react-native';
```
#### Ignore all logs[](#ignore-all-logs "Direct link to Ignore all logs")
LogBox notifications can be disabled using `LogBox.ignoreAllLogs()`. This can be useful in situations such as giving product demos.
js
```
LogBox.ignoreAllLogs();
```
#### Ignore specific logs[](#ignore-specific-logs "Direct link to Ignore specific logs")
Notifications can be disabled on a per-log basis via `LogBox.ignoreLogs()`. This can be useful for noisy warnings or those that cannot be fixed, e.g. in a third-party dependency.
js
```
LogBox.ignoreLogs([
// Exact message
'Warning: componentWillReceiveProps has been renamed',
// Substring or regex match
/GraphQL error: .*/,
]);
```
note
LogBox will treat certain errors from React as warnings, which will mean they don't display as an in-app error notification. Advanced users can change this behaviour by customising LogBox's warning filter using [`LogBoxData.setWarningFilter()`](https://github.com/facebook/react-native/blob/d334f4d77eea538dff87fdcf2ebc090246cfdbb0/packages/react-native/Libraries/LogBox/Data/LogBoxData.js#L338).
## Performance Monitor[](#performance-monitor "Direct link to Performance Monitor")
On 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](/docs/performance.md).

info
The Performance Monitor runs in-app and is a guide. We recommend investigating the native tooling under Android Studio and Xcode for accurate performance measurements.
---
# Source: https://reactnative.dev/docs/devsettings.md
# DevSettings
The `DevSettings` module exposes methods for customizing settings for developers in development.
***
# Reference
## Methods[](#methods "Direct link to Methods")
### `addMenuItem()`[](#addmenuitem "Direct link to addmenuitem")
tsx
```
static addMenuItem(title: string, handler: () => any);
```
Add a custom menu item to the Dev Menu.
**Parameters:**
| Name | Type |
| --------------- | -------- |
| titleRequired | string |
| handlerRequired | function |
**Example:**
tsx
```
DevSettings.addMenuItem('Show Secret Dev Screen', () => {
Alert.alert('Showing secret dev screen!');
});
```
***
### `reload()`[](#reload "Direct link to reload")
tsx
```
static reload(reason?: string): void;
```
Reload the application. Can be invoked directly or on user interaction.
**Example:**
tsx
```