# React-Native-Project
**Repository Path**: zhao-jingtao-l/react-native-project
## Basic Information
- **Project Name**: React-Native-Project
- **Description**: 根据你所使用的操作系统、针对的目标平台不同,具体步骤有所不同。如果想同时开发 iOS 和 Android 也没问题,你只需要先选一个平台开始,另一个平台的环境搭建只是稍有不同。必须安装的依赖有:Node、JDK 和 Android Studio。虽然你可以使用`任何编辑器`来开发应用,但你仍然必须安装 Android Studio 来获得编译 Android 应用所需的工具和环境。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: https://gitee.com/zhao-jingtao-l
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-09-30
- **Last Updated**: 2024-03-20
## Categories & Tags
**Categories**: Uncategorized
**Tags**: React-native, TypeScript, React, Android, IOS
## README
# 一、搭建开发环境
欢迎使用 React Native!这篇文档会帮助你搭建基本的 React Native 开发环境。
- 完整原生环境
- 简易沙盒环境
根据你所使用的操作系统、针对的目标平台不同,具体步骤有所不同。如果想同时开发 iOS 和 Android 也没问题,你只需要先选一个平台开始,另一个平台的环境搭建只是稍有不同。
如果`阅读完本文档`后还碰到很多环境搭建的问题,我们建议你还可以再看看[求助讨论区](https://github.com/reactnativecn/react-native-website/issues)。注意!视频教程或者其他网络上的博客和文章可能和本文档有所出入,请以最新版本的本文档所述为准!
- macOS
- Windows
- Linux
#### 目标平台
- Android
- iOS
## 安装依赖
必须安装的依赖有:Node、JDK 和 Android Studio。
虽然你可以使用`任何编辑器`来开发应用(编写 js 代码),但你仍然必须安装 Android Studio 来获得编译 Android 应用所需的工具和环境。
### Node, JDK
我们建议直接使用搜索引擎搜索下载 Node 和[Java SE Development Kit (JDK)](https://www.oracle.com/java/technologies/downloads/#java11)
注意 Node 的版本应大于等于 16,安装完 Node 后建议设置 npm 镜像(淘宝源)以加速后面的过程(或使用科学上网工具)。
> 注意:强烈建议始终选择 Node 当前的 LTS (长期维护)版本,一般是偶数版本,不要选择偏实验性质的奇数版本。
> 注意:不要使用 cnpm!cnpm 安装的模块路径比较奇怪,packager 不能正常识别!
React Native 需要 Java Development Kit [JDK] 11。你可以在命令行中输入 `javac -version`(请注意是 javac,不是 java)来查看你当前安装的 JDK 版本。如果版本不合要求,则可以去[Temurin](https://adoptium.net/?variant=openjdk11&jvmVariant=hotspot)或[Oracle JDK](https://www.oracle.com/java/technologies/downloads/#java11)上下载(后者下载需注册登录)。
> 低于 0.67 版本的 React Native 需要 JDK 1.8 版本(官方也称 8 版本)。
```jsx
# 使用nrm工具切换淘宝源
npx nrm use taobao
# 如果之后需要切换回官方源可使用
npx nrm use npm
```
### Yarn
[Yarn](http://yarnpkg.com/)是 Facebook 提供的替代 npm 的工具,可以加速 node 模块的下载。
```jsx
npm install -g yarn
```
安装完 yarn 之后就可以用 yarn 代替 npm 了,例如用`yarn`代替`npm install`命令,用`yarn add 某第三方库名`代替`npm install 某第三方库名`。
### Android 开发环境
如果你之前没有接触过 Android 的开发环境,那么请做好心理准备,这一过程相当繁琐。请`万分仔细`地阅读下面的说明,严格对照文档进行配置操作。
> 译注:请注意!!!国内用户`必须必须必须`有稳定的代理软件,否则在下载、安装、配置过程中会不断遭遇链接超时或断开,无法进行开发工作。某些代理软件可能只提供浏览器的代理功能,或只针对特定网站代理等等,请自行研究配置或更换其他软件。总之如果报错中出现有网址,那么 99% 就是无法正常连接网络。
#### 1. 安装 Android Studio
[首先下载和安装 Android Studio](https://developer.android.google.cn/studio/),国内用户可能无法打开官方链接,请自行使用搜索引擎搜索可用的下载链接。安装界面中选择"Custom"选项,确保选中了以下几项:
- `Android SDK`
- `Android SDK Platform`
- `Android Virtual Device`
然后点击"Next"来安装选中的组件。
> 如果选择框是灰的,你也可以先跳过,稍后再来安装这些组件。
安装完成后,看到欢迎界面时,就可以进行下面的操作了。
#### 2. 安装 Android SDK
Android Studio 默认会安装最新版本的 Android SDK。目前编译 React Native 应用需要的是`Android 13 (Tiramisu)`版本的 SDK(注意 SDK 版本不等于终端系统版本,RN 目前支持 android 5 以上设备)。你可以在 Android Studio 的 SDK Manager 中选择安装各版本的 SDK。
你可以在 Android Studio 的欢迎界面中找到 SDK Manager。点击"Configure",然后就能看到"SDK Manager"。

> SDK Manager 还可以在 Android Studio 的"Preferences"菜单中找到。具体路径是**Appearance & Behavior** → **System Settings** → **Android SDK**。
在 SDK Manager 中选择"SDK Platforms"选项卡,然后在右下角勾选"Show Package Details"。展开`Android 13 (Tiramisu)`选项,确保勾选了下面这些组件(重申你必须使用稳定的代理软件,否则可能都看不到这个界面):
- `Android SDK Platform 33`
- `Intel x86 Atom_64 System Image`(官方模拟器镜像文件,使用非官方模拟器不需要安装此组件)
然后点击"SDK Tools"选项卡,同样勾中右下角的"Show Package Details"。展开"Android SDK Build-Tools"选项,确保选中了 React Native 所必须的`33.0.0`版本。你可以同时安装多个其他版本。
最后点击"Apply"来下载和安装这些组件。
#### 3. 配置 ANDROID_HOME 环境变量[](https://www.reactnative.cn/docs/environment-setup#3-配置-android_home-环境变量)
React Native 需要通过环境变量来了解你的 Android SDK 装在什么路径,从而正常进行编译。
打开`控制面板` -> `系统和安全` -> `系统` -> `高级系统设置` -> `高级` -> `环境变量` -> `新建`,创建一个名为`ANDROID_HOME`的环境变量(系统或用户变量均可),指向你的 Android SDK 所在的目录(具体的路径可能和下图不一致,请自行确认):

SDK 默认是安装在下面的目录:
```powershell
C:\Users\你的用户名\AppData\Local\Android\Sdk
```
你可以在 Android Studio 的"Preferences"菜单中查看 SDK 的真实路径,具体是**Appearance & Behavior** → **System Settings** → **Android SDK**。
你需要关闭现有的命令符提示窗口然后重新打开,这样新的环境变量才能生效。
#### 4. 把一些工具目录添加到环境变量 Path[](https://www.reactnative.cn/docs/environment-setup#4-把一些工具目录添加到环境变量-path)
打开`控制面板` -> `系统和安全` -> `系统` -> `高级系统设置` -> `高级` -> `环境变量`,选中**Path**变量,然后点击**编辑**。点击**新建**然后把这些工具目录路径添加进去:platform-tools、emulator、tools、tools/bin
```powershell
%ANDROID_HOME%\platform-tools
%ANDROID_HOME%\emulator
%ANDROID_HOME%\tools
%ANDROID_HOME%\tools\bin
```
## 创建新项目
> 如果你之前全局安装过旧的`react-native-cli`命令行工具,请使用`npm uninstall -g react-native-cli`卸载掉它以避免一些冲突:
>
> ```shell
> npm uninstall -g react-native-cli @react-native-community/cli
> ```
使用 React Native 内建的命令行工具来创建一个名为"AwesomeProject"的新项目。这个命令行工具不需要安装,可以直接用 node 自带的`npx`命令来使用:
> **必须要看的注意事项一**:请`不要`在目录、文件名中使用`中文、空格`等特殊符号。请`不要`单独使用常见的关键字作为项目名(如 class, native, new, package 等等)。请`不要`使用与核心模块同名的项目名(如 react, react-native 等)。
> **必须要看的注意事项二**:请`不要`在某些权限敏感的目录例如 System32 目录中 init 项目!会有各种权限限制导致不能运行!
> **必须要看的注意事项三**:请`不要`使用一些移植的终端环境,例如`git bash`或`mingw`等等,这些在 windows 下可能导致找不到环境变量。请使用系统自带的命令行(CMD 或 powershell)运行。
```shell
npx react-native@latest init AwesomeProject
```
如果你是想把 React Native 集成到现有的原生项目中,则步骤完全不同,请参考[集成到现有原生应用](https://www.reactnative.cn/docs/integration-with-existing-apps)。
### 指定版本或项目模板
你可以使用`--version`参数(注意是`两`个杠)创建指定版本的项目。注意版本号必须精确到两个小数点。
```shell
npx react-native@X.XX.X init AwesomeProject --version X.XX.X
```
还可以使用`--template`来使用一些社区提供的模板。
## 准备 Android 设备
你需要准备一台 Android 设备来运行 React Native Android 应用。这里所指的设备既可以是真机,也可以是模拟器。后面我们所有的文档除非特别说明,并不区分真机或者模拟器。Android 官方提供了名为 Android Virtual Device(简称 AVD)的模拟器。此外还有很多第三方提供的模拟器如[Genymotion](https://www.genymotion.com/download)、BlueStack 等。一般来说官方模拟器免费、功能完整,但性能较差。第三方模拟器性能较好,但可能需要付费,或带有广告。
### 使用 Android 真机
你也可以使用 Android 真机来代替模拟器进行开发,只需用 usb 数据线连接到电脑,然后遵照[在设备上运行](https://www.reactnative.cn/docs/running-on-device)这篇文档的说明操作即可。
### 使用 Android 模拟器
你可以使用 Android Studio 打开项目下的"android"目录,然后可以使用"AVD Manager"来查看可用的虚拟设备,它的图标看起来像下面这样:

如果你刚刚才安装 Android Studio,那么可能需要先[创建一个虚拟设备](https://developer.android.com/studio/run/managing-avds.html)。点击"Create Virtual Device...",然后选择所需的设备类型并点击"Next",然后选择**Tiramisu** API Level 33 image.
> 译注:请不要轻易点击 Android Studio 中可能弹出的建议更新项目中某依赖项的建议,否则可能导致无法运行。
## 编译并运行 React Native 应用
确保你先运行了模拟器或者连接了真机,然后在你的项目目录中运行`yarn android`或者`yarn react-native run-android`:
```jsx
cd AwesomeProject
yarn android
# 或者
yarn react-native run-android
```
此命令会对项目的原生部分进行编译,同时在另外一个命令行中启动`Metro`服务对 js 代码进行实时打包处理(类似 webpack)。`Metro`服务也可以使用`yarn start`命令单独启动。
如果配置没有问题,你应该可以看到应用自动安装到设备上并开始运行。注意第一次运行时需要下载大量编译依赖,耗时可能数十分钟。此过程`严重依赖稳定的代理软件`,否则将频繁遭遇链接超时和断开,导致无法运行。
也可以尝试阿里云提供的[maven 镜像](https://help.aliyun.com/document_detail/102512.html?spm=a2c40.aliyun_maven_repo.0.0.361865e90r2x4b),将`android/build.gradle`中的`mavenCentral()`和`google()`分别替换为`maven { url 'https://maven.aliyun.com/repository/central' }`和`maven { url 'https://maven.aliyun.com/repository/google' }`(注意可能有多处需要替换)。
`npx react-native run-android`只是运行应用的方式之一。你也可以在 Android Studio 中直接运行应用。
> 译注:建议在`run-android`成功后再尝试使用 Android Studio 启动。请不要轻易点击 Android Studio 中可能弹出的建议更新项目中某依赖项的建议,否则可能导致无法运行。
> 如果你无法正常运行,遇到奇奇怪怪的红屏错误,先回头`仔细对照文档检查`,然后可以看看[问题讨论区](https://github.com/reactnativecn/react-native-website/issues)。不同时期不同版本可能会碰到不同的问题,我们会在论坛中及时解答更新。但请注意***千万不要\***执行 bundle 命令,那样会导致代码完全无法刷新。
### 修改项目
现在你已经成功运行了项目,我们可以开始尝试动手改一改了:
- 使用你喜欢的文本编辑器打开`App.js`并随便改上几行
- 按两下 R 键,或是在开发者菜单中选择 *Reload*,就可以看到你的最新修改。
### 完成了!
恭喜!你已经成功运行并修改了你的第一个 React Native 应用

## 接下来?
如果你想把 React Native 集成到现有的原生项目中,则请参考[集成到现有原生应用](https://www.reactnative.cn/docs/integration-with-existing-apps)。
如果你想从头开始学习 React Native 开发,可以从[简介](https://www.reactnative.cn/docs/environment-setup)文档开始。
# 二、集成到现有原生应用
如果你正准备从头开始制作一个新的应用,那么 React Native 会是个非常好的选择。但如果你只想给现有的原生应用中添加一两个视图或是业务流程,React Native 也同样不在话下。只需简单几步,你就可以给原有应用加上新的基于 React Native 的特性、画面和视图等。
具体的步骤根据你所开发的目标平台不同而不同。
> 译注:本文档可能更新不够及时,不能保证适用于最新版本,欢迎了解的朋友使用页面底部的编辑链接帮忙改进此文档。一个实用的建议是可以使用`npx react-native init NewProject`创建一个最新版本的纯 RN 项目,去参考其 Podfile 或是 gradle 等的配置,以它们为准。
- Android (Java)
- iOS (Objective-C)
- iOS (Swift)
## 核心概念
把 React Native 组件集成到 Android 应用中有如下几个主要步骤:
1. 配置好 React Native 依赖和项目结构。
2. 创建 js 文件,编写 React Native 组件的 js 代码。
3. 在应用中添加一个`ReactRootView`。这个`ReactRootView`正是用来承载你的 React Native 组件的容器。
4. 启动 React Native 的 Metro 服务,运行应用。
5. 验证这部分组件是否正常工作。
## 开发环境准备
首先按照[开发环境搭建教程](https://www.reactnative.cn/docs/environment-setup)来安装 React Native 在 Android 平台上所需的一切依赖软件。
### 1. 配置项目目录结构
首先创建一个空目录用于存放 React Native 项目,然后在其中创建一个`/android`子目录,把你现有的 Android 项目拷贝到`/android`子目录中。
### 2. 安装 JavaScript 依赖包
在项目根目录下创建一个名为`package.json`的空文本文件,然后填入以下内容:
```jsx
{
"name": "MyReactNativeApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "react-native start"
}
}
```
> 示例中的`version`字段没有太大意义(除非你要把你的项目发布到 npm 仓库)。`scripts`中是用于启动 Metro 服务的命令。
接下来我们使用 yarn 或 npm(两者都是 node 的包管理器)来安装 React 和 React Native 模块。请打开一个终端/命令提示行,进入到项目目录中(即包含有 package.json 文件的目录),然后运行下列命令来安装:
```shell
$ yarn add react-native
```
这样默认会安装最新版本的 React Native,同时会打印出类似下面的警告信息(你可能需要滚动屏幕才能注意到):
> warning "[react-native@0.52.2](mailto:react-native@0.52.2)" has unmet peer dependency "[react@16.2.0](mailto:react@16.2.0)".
这是正常现象,意味着我们还需要安装指定版本的 React:
```jsx
$ yarn add react@16.2.0
```
注意必须严格匹配警告信息中所列出的版本,高了或者低了都不可以。
> 如果你使用多个第三方依赖,可能这些第三方各自要求的 react 版本有所冲突,此时应优先满足`react-native`所需要的`react`版本。其他第三方能用则用,不能用则只能考虑选择其他库。
所有 JavaScript 依赖模块都会被安装到项目根目录下的`node_modules/`目录中(这个目录我们原则上不复制、不移动、不修改、不上传,随用随装)。
把`node_modules/`目录记录到`.gitignore`文件中(即不上传到版本控制系统,只保留在本地)。
## 把 React Native 添加到你的应用中eact-native-添加到你的应用中)
### 配置 Gradle
React Native 使用 React Native Gradle Plugin 来配置您的依赖项和项目设置。
首先,让我们通过添加以下行来编辑您的`settings.gradle`文件:
```groovy
includeBuild('../node_modules/@react-native/gradle-plugin')
```
然后你需要打开顶层的 `build.gradle` 文件并添加这一行:
```diff
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
+ classpath("com.facebook.react:react-native-gradle-plugin")
}
}
```
这将确保 React Native Gradle Plugin 在您的项目中可用。 最后,在 `app/build.gradle` 文件中添加以下行(注意它的路径不同于上面,是`app/build.gradle`):
```diff
apply plugin: "com.android.application"
+apply plugin: "com.facebook.react"
repositories {
mavenCentral()
}
dependencies {
// Other dependencies here
+ implementation "com.facebook.react:react-android"
+ implementation "com.facebook.react:hermes-android"
}
```
这些依赖项可在 `mavenCentral()` 上获得,因此请确保您已在 `repositories{}` 块中定义它。
提示
我们故意不为这些`implementation`依赖项指定版本,因为 React Native Gradle Plugin 会自动处理它。如果您不使用 React Native Gradle Plugin,则必须手动指定版本。
### 启用原生模块的自动链接
要使用[自动链接](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md)的功能,我们必须将其应用于几个地方。首先,将以下内容添加到`settings.gradle`:
```gradle
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
```
接下来,在`app/build.gradle`的最底部添加以下内容:
```gradle
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
```
### 配置权限
接着,在 `AndroidManifest.xml` 清单文件中声明网络权限:
```xml
```
如果需要访问 `DevSettingsActivity` 界面(即开发者菜单),则还需要在 `AndroidManifest.xml` 中声明:
```xml
```
开发者菜单一般仅用于在开发时从 Packager 服务器刷新 JavaScript 代码,所以在正式发布时你可以去掉这一权限。
### 允许明文传输(http 接口) (API level 28+)
> 从 Android 9 (API level 28)开始,默认情况下明文传输(http 接口)是禁用的,只能访问 https 接口。这将阻止应用程序连接到[Metro bundler](https://facebook.github.io/metro)。下面的更改允许调试版本中的明文通信。
#### 1. 为 debug 版本启用 `usesCleartextTraffic`选项
在`src/debug/AndroidManifest.xml`中添加`usesCleartextTraffic`选项:
```xml
```
如果希望在正式打包后也能继续访问 http 接口,则需要在`src/main/AndroidManifest.xml`中也添加这一选项。
要了解有关网络安全配置和明文通信策略的更多信息,请参阅[此链接](https://developer.android.com/training/articles/security-config#CleartextTrafficPermitted)。
### 代码集成
现在我们将修改原生 Android 应用程序以集成 React Native。
#### React Native 组件
我们首先要写的是"High Score"(得分排行榜)的 JavaScript 端的代码。
##### 1. 创建一个`index.js`文件
首先在项目根目录中创建一个空的`index.js`文件。(注意一些老的教程可能提到,在 0.49 版本之前是 index.android.js 文件)
`index.js`是 React Native 应用在 Android 上的入口文件。而且它是不可或缺的!它可以是个很简单的文件,简单到可以只包含一行`require/import`导入语句。本教程中为了简单示范,把全部的代码都写到了`index.js`里(当然实际开发中我们并不推荐这样做)。
##### 2. 添加你自己的 React Native 代码
在`index.js`中添加你自己的组件。这里我们只是简单的添加一个``组件,然后用一个带有样式的``组件把它包起来。
```jsx
import React from 'react';
import {AppRegistry, StyleSheet, Text, View} from 'react-native';
const HelloWorld = () => {
return (
Hello, World
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
hello: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
AppRegistry.registerComponent(
'MyReactNativeApp',
() => HelloWorld,
);
```
##### 3. 配置权限以便开发中的红屏错误能正确显示
如果你的应用会运行在 Android 6.0(API level 23)或更高版本,请确保你在开发版本中有打开`悬浮窗(overlay)`权限。你可以在代码中使用`Settings.canDrawOverlays(this);`来检查。之所以需要这一权限,是因为我们会把开发中的报错显示在悬浮窗中(仅在开发阶段需要)。在 Android 6.0(API level 23)中用户需要手动同意授权。具体请求授权的做法是在`onCreate()`中添加如下代码。其中`OVERLAY_PERMISSION_REQ_CODE`是用于回传授权结果的字段。
```java
private final int OVERLAY_PERMISSION_REQ_CODE = 1; // 任写一个值
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
}
}
```
最后,必须重写`onActivityResult()`方法(如下面的代码所示)来处理权限接受或拒绝情况以实现一致的用户体验。此外,为了集成使用 startActivityForResult 的原生模块,我们需要将结果传递给 ReactInstanceManager 实例的 onActivityResult 方法。
```java
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
// SYSTEM_ALERT_WINDOW permission not granted
}
}
}
mReactInstanceManager.onActivityResult( this, requestCode, resultCode, data );
}
```
#### 核心组件:`ReactRootView`
我们还需要添加一些原生代码来启动 React Native 的运行时环境并让它开始渲染。首先需要在一个`Activity`中创建一个`ReactRootView`对象,然后在这个对象之中启动 React Native 应用,并将它设为界面的主视图。
> 如果你要在安卓 5.0 以下的系统上运行,请用 `com.android.support:appcompat` 包中的 `AppCompatActivity` 代替 `Activity` 。
```java
public class MyReactActivity extends Activity implements DefaultHardwareBackBtnHandler {
private ReactRootView mReactRootView;
private ReactInstanceManager mReactInstanceManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SoLoader.init(this, false);
mReactRootView = new ReactRootView(this);
List packages = new PackageList(getApplication()).getPackages();
// 有一些第三方可能不能自动链接,对于这些包我们可以用下面的方式手动添加进来:
// packages.add(new MyReactNativePackage());
// 同时需要手动把他们添加到`settings.gradle`和 `app/build.gradle`配置文件中。
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setCurrentActivity(this)
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index")
.addPackages(packages)
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.build();
// 注意这里的MyReactNativeApp 必须对应"index.js"中的
// "AppRegistry.registerComponent()"的第一个参数
mReactRootView.startReactApplication(mReactInstanceManager, "MyReactNativeApp", null);
setContentView(mReactRootView);
}
@Override
public void invokeDefaultOnBackPressed() {
super.onBackPressed();
}
}
```
执行"Sync Project files with Gradle"操作。
如果你使用的是 Android Studio , 可以使用`Alt + Enter`快捷键来自动为 MyReactActivity 类补上缺失的 import 语句。注意`BuildConfig`应该是在你自己的包中自动生成,无需额外引入。千万不要从`com.facebook...`的包中引入!
我们需要把 `MyReactActivity` 的主题设定为 `Theme.AppCompat.Light.NoActionBar` ,因为里面有许多组件都使用了这一主题。
```xml
```
> 一个`ReactInstanceManager`可以在多个 activities 或 fragments 间共享。你将需要创建自己的`ReactFragment`或`ReactActivity`,并拥有一个保存`ReactInstanceManager`的单例持有者。当你需要`ReactInstanceManager`(例如,将`ReactInstanceManager`连接到这些 Activities 或 Fragments 的生命周期)时,请使用单例提供的那个。
下一步我们需要把一些 activity 的生命周期回调传递给`ReactInstanceManager`:
```java
@Override
protected void onPause() {
super.onPause();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostPause(this);
}
}
@Override
protected void onResume() {
super.onResume();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostResume(this, this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mReactInstanceManager != null) {
mReactInstanceManager.onHostDestroy(this);
}
if (mReactRootView != null) {
mReactRootView.unmountReactApplication();
}
}
```
我们还需要把后退按钮事件传递给 React Native:
```java
@Override
public void onBackPressed() {
if (mReactInstanceManager != null) {
mReactInstanceManager.onBackPressed();
} else {
super.onBackPressed();
}
}
```
这允许 JavaScript 控制用户按下设备后退按钮时发生的情况(例如,执行导航时)。当 JavaScript 不处理后退按钮按下的情况时,将调用`invokeDefaultOnBackPressed`方法。默认情况下,这将完成你的`Activity`。
最后,我们需要连接开发菜单。默认情况下通过(狂)摇晃设备来激活,但这在模拟器中不是很有用,只有当你按下设备菜单按钮时才显示(如果你使用的是 Android Studio 模拟器,请使用`Ctrl + M`):
```java
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
mReactInstanceManager.showDevOptionsDialog();
return true;
}
return super.onKeyUp(keyCode, event);
}
```
现在 activity 已就绪,可以运行一些 JavaScript 代码了。
### 测试集成结果
你已经完成了将 React Native 与当前应用程序集成的所有基本步骤。现在我们将启动[Metro bundler](https://facebook.github.io/metro)来构建`index.bundle`包,并通过本地主机提供服务。
##### 1. 运行 Metro 服务
运行应用首先需要启动开发服务器(Metro)。你只需在项目根目录中执行以下命令即可:
```shell
$ yarn start
```
##### 2. 运行你的应用
保持 Metro 的窗口运行不要关闭,然后像往常一样编译运行你的 Android 应用(在命令行中执行`./gradlew installDebug`或是在 Android Studio 中编译运行)。
编译执行一切顺利进行之后,在进入到 MyReactActivity 时应该就能立刻从 Metro 中读取 JavaScript 代码并执行和显示:

### 在 Android Studio 中打包
你也可以使用 Android Studio 来打 release 包!其步骤基本和原生应用一样,只是如果你**没有**使用 React Native Gradle Plugin 的话,则在每次编译打包之前需要先执行 js 文件的打包(即生成离线的 jsbundle 文件)。具体的 js 打包命令如下:
```shell
# 注:如果你使用了 React Native Gradle Plugin,则其会自动执行以下命令,不需要手动执行
$ npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/com/your-company-name/app-package-name/src/main/assets/index.android.bundle --assets-dest android/com/your-company-name/app-package-name/src/main/res/
```
> 注意把上述命令中的路径替换为你实际项目的路径。如果 assets 目录不存在,则需要提前自己创建一个。
然后在 Android Studio 中正常生成 release 版本即可!
# 三、运行命令(连接手机)
```bash
adb reverse tcp:8081 tcp:8081
```
## 安装apk包
```bash
yarn android
```
## 运行
```bash
yarn start
```
## 打包(包的位置===>android-app-build-outputs-apk-release-app-release.apk)
```bash
cd android
gradlew assembleRelease
```
## 错误记录
### 1 pod install git 报错
```
Pre-downloading: `boost-for-react-native` from `git@e.coding.net:theling/theling-utils/boost-for-react-native.git`
[!] Error installing boost-for-react-native
[!] Failed to download 'boost-for-react-native': [!] /usr/bin/git -C /var/folders/rp/g5qct2rs6wj7n5ps6nyvgzw40000gn/T/d20210708-37324-5z9v55 rev-parse HEAD
HEAD
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git [...] -- [...]'
```
解决方案:
先移除掉本地的 master,在终端输入 pod repo remove master 然后转到路径下,在终端输入 cd
~/.cocoapods/repos
### 2.iOS 错误 library not found for -lXXX
```angular2html
查看此链接解决
https://cloud.tencent.com/developer/article/1143340
```
### 3.打包步骤
```angular2html
1.运行build-ios
pod cache clean --all
```
# FlatList 使用文档
## 使用场景
- 所有列表页皆可使用(减少 scrollView 的使用,ScrollView 是 FlatList 的子集)
## 重点属性
### key
flatList 跟手动 map 一样,要给子项加 Key,但是不用加载 renderItem 里,给 FlatList 组件加个属
性**keyExtractor**,格式如下:
```javascript
keyExtractor={(item) => item.id}
```
### ListEmptyComponent
```js
{
loadData(true);
}}
/>
}
ListEmptyComponent={}
keyExtractor={(item) => item.policyId}
contentContainerStyle={{ paddingHorizontal: 10 }}
onEndReached={() => loadData()}
onEndReachedThreshold={0.1}
data={dataList.records}
renderItem={renderItem}
/>
```
renderItem 这个属性是个(item)=>你想要 render 的东西,**当你的 data 数组为空时,代码不会经过
renderItem**,所以也就不能在 renderItem 里判断空值并且设置 Empty 组件,当然你可以这么写
```js
{
xxx.length > 0 ? (
}
keyExtractor={(item) => item.policyId}
contentContainerStyle={{ paddingHorizontal: 10 }}
onEndReached={() => loadData()}
onEndReachedThreshold={0.1}
refreshControl={
{
loadData(true);
}}
/>
}
data={dataList.records}
renderItem={renderItem}
/>
) : (
);
}
```
但是不优雅,所以有个属性叫 ListEmptyComponent,字面意思,字面用法:
```js
ListEmptyComponent={}
或
ListEmptyComponent={()=>}
```
### 刷新属性
#### onEndReached
#### onEndReachedThreshold
#### refreshControl
这三个属性是处理列表刷新翻页的,具体看官方文档,
### ListHeaderComponent
正常情况下 一个列表页 包括 列表本身 翻页相关 搜索筛选相关列表本身和翻页已经了解了,搜索下拉,直觉上会
这么写
```js
<筛选组件XXX>
```
这么写肯定会包黄色警告,因为 FlatList 不能嵌套在**_同属性的_**ScrollView 里所以最外层得改成 View. 也
可以用到这个属性 ListHeaderComponent,把上半部分的东西写在 FlatList 里
```js
<筛选组件XXX>
}
xxx={xxx}
xxx={xxx}
xxx={xxx}
>
```
# 四、初始化项目
进入到自己的工作目录,执行下面的命令创建 react native 项目
```bash
npx react-native init AwesomeProject
```
如果 出现如下报错:
```bash
cli.init is not a function
```

产生这个问题的原因是:使用这种方式创建工程,在[react-native](https://so.csdn.net/so/search?q=react-native&spm=1001.2101.3001.7020) 版本是0.69 版本上不适用。各位可以检查下自己安装的React-native的版本。
为了解决这个错误,我们要做的就是降级我们最新的 0.69 版本的 react native。要使用较旧的项目降级我们的项目,您必须执行以下命令。
可以将之前输入的命令改成:
```bash
npx react-native init AwesomeProject --version 0.68.2
```

看到如上图片,代表初始化成功。
# 五、使用 TypeScript
## 使用 TypeScript 开始新项目
如果您要开始一个新项目,则有几种不同的上手方法。 您可以使用[TypeScript 模板](https://github.com/react-native-community/react-native-template-typescript):
```sh
npx react-native init MyApp --template react-native-template-typescript
```
> **Note** 如果以上命令失败,则可能是您的 PC 上全局安装了旧版本的`react-native`或`react-native-cli`。 尝试卸载 cli 并使用`npx`运行 cli.
您可以使用具有两个 TypeScript 模板的[Expo](https://expo.io/):
```sh
npm install -g expo-cli
expo init MyTSProject
```
或者,您可以使用[Ignite](https://infinite.red/ignite),它也具有 TypeScript 模板:
```sh
npm install -g ignite-cli
ignite new MyTSProject
```
## 在已有的项目中添加 TypeScript
1. 将 TypeScript 以及 React Native 和 Jest 的依赖添加到您的项目中。
```sh
yarn add --dev typescript @types/jest @types/react @types/react-native @types/react-test-renderer
# or for npm
npm install --save-dev typescript @types/jest @types/react @types/react-native @types/react-test-renderer
```
添加一个 TypeScript 配置文件。在项目的根目录中创建一个`tsconfig.json`:
```json
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"isolatedModules": true,
"jsx": "react-native",
"lib": ["es2017"],
"types": ["react-native", "jest"],
"moduleResolution": "node",
"noEmit": true,
"strict": true,
"target": "esnext"
},
"exclude": [
"node_modules",
"babel.config.js",
"metro.config.js",
"jest.config.js"
]
}
```
1. 创建一个`jest.config.js`文件来配置 Jest 以使用 TypeScript:
```js
module.exports = {
preset: 'react-native',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
};
```
1. 将 JavaScript 文件重命名为`* .tsx`:
> 请保留`./index.js`入口文件,否则将在打包生产版本时遇到问题。
1. 运行 `yarn tsc` 对 TypeScript 文件进行类型检查。
## TypeScript 和 React Native 是如何工作的
无需额外配置,和非 TypeScript 的 React Native 项目一样都是直接通过 [Babel 体系](https://reactnative.cn/docs/javascript-environment#javascript-syntax-transformers) 将您的文件转换为 JavaScript。我们建议您只使用 TypeScript 编译器的类型检查功能(而不是编译)。如果您有已经存在的 TypeScript 代码需要迁移到 React Native,这里有一些关于使用 Babel 而不是 TypeScript 编译器的[注意事项](https://babeljs.io/docs/en/next/babel-plugin-transform-typescript)。
## 用 TypeScript 写 React Native 的示例
可以用`interface`来为 React 的函数组件编写[Props](https://reactnative.cn/docs/props)的类型(使用`React.FC`)。这样在后续编码的过程中,编辑器就会根据这一类型来做类型检查并提供自动补全。
```tsx
// components/Hello.tsx
import React from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
export interface Props {
name: string;
enthusiasmLevel?: number;
}
const Hello: React.FC = (props) => {
const [enthusiasmLevel, setEnthusiasmLevel] = React.useState(
props.enthusiasmLevel
);
const onIncrement = () =>
setEnthusiasmLevel((enthusiasmLevel || 0) + 1);
const onDecrement = () =>
setEnthusiasmLevel((enthusiasmLevel || 0) - 1);
const getExclamationMarks = (numChars: number) =>
Array(numChars + 1).join('!');
return (
Hello{' '}
{props.name + getExclamationMarks(enthusiasmLevel || 0)}
);
};
// styles
const styles = StyleSheet.create({
root: {
alignItems: 'center',
alignSelf: 'center'
},
buttons: {
flexDirection: 'row',
minHeight: 70,
alignItems: 'stretch',
alignSelf: 'center',
borderWidth: 5
},
button: {
flex: 1,
paddingVertical: 0
},
greeting: {
color: '#999',
fontWeight: 'bold'
}
});
export default Hello;
```