# reactNativeDemo **Repository Path**: dujiang1992/reactNativeDemo ## Basic Information - **Project Name**: reactNativeDemo - **Description**: No description available - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2021-06-07 - **Last Updated**: 2021-10-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # typescript + react-native开发仿喜马拉雅app # 环境搭建 ## 下载jdk * 下载地址: https://www.oracle.com/java/technologies/javase-downloads.html * ![jdk的安装与配置](/images/reactNative/images/jdk安装及配置.jpg) {% note primary %} 注意:推荐下载jdk1.8及以上的版本,下载之后配置环境变量 {% endnote %} ## 下载android studo * 下载地址: https://developer.android.google.cn/studio/ {% note primary %} android studo推荐使用3.5以上的版本,然后下载android sdk,选择8.1以上的版本 {% endnote %} * ![android studio和android sdk下载安装](/images/reactNative/images/androidstudio环境搭建.jpg) * ![安卓环境变量](/images/reactNative/images/android环境变量.jpg) ## 创建react-native项目(typescript) * 输入命令:npx react-native init MyApp --template react-native-template-typescript *** # 打包APK 1. 生成keyStore * 在当前目录下输入命令: ``` keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000 ``` * 输入密码和确认的密码之后,其他不用填,一直回车, ![生成keyStore](/img/生成keyStore.png) 2. 将生成的my-release-key.keystore文件放到android/app文件夹下:![keystore放的位置](/img/keystore放的位置.png) 3. 编辑android\gradle.properties文件,添加如下的代码(注意把其中的****替换为相应密码) ``` MYAPP_RELEASE_STORE_FILE=my-release-key.keystore MYAPP_RELEASE_KEY_ALIAS=my-key-alias MYAPP_RELEASE_STORE_PASSWORD=123456 MYAPP_RELEASE_KEY_PASSWORD=123456 ``` 4. 编辑android/app/build.gradle文件,添加以下配置: ``` android { ... defaultConfig { ... } signingConfigs { release { storeFile file(MYAPP_RELEASE_STORE_FILE) storePassword MYAPP_RELEASE_STORE_PASSWORD keyAlias MYAPP_RELEASE_KEY_ALIAS keyPassword MYAPP_RELEASE_KEY_PASSWORD } } buildTypes { release { ... signingConfig signingConfigs.release } } } ``` 5. 执行命令: ``` cd android && ./gradlew assembleRelease 或者在package.json配置下 "scripts": { ... "release": "cd android && ./gradlew assembleRelease" }, 执行npm run release ``` # 修改app的名称(安卓) * 修改android\app\src\main\res\values\strings.xml文件即可 # 修改应用图标(安卓) * 修改android\app\src\main\AndroidManifest.xml里面的 ``` ic_launcher是图片的名称,可改,不改的话,替换android\app\src\main\res里面的图片即可 ``` * ![图标](img/app图标更换.png) # ios打包 1. 在ios文件夹下,新建bundle文件夹,通过命令将包编译到本地 ``` react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/bundle/index.ios.bundle --assets-dest ios/bundle ``` 2. 为了方便,在package.json中添加编译命令: ``` "scripts": { ... "bundle-ios": "react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/bundle/index.ios.bundle --assets-dest ios/bundle" }, ``` 3. 打开xCode,引入ios文件夹,![引入ios目录](img/引入ios目录.jpg) 4. 右键打开项目同名的iotApp的菜单,Add Files to "RNIos", ![右键目录](img/引入ios目录.jpg) 5. 选中bundle,勾选create foider refrences,![勾选](img/勾选.png) 6. 添加到项目中的文件夹必须是蓝色的,![蓝色](img/蓝色.png) 7. 修改xcode的debug状态,Xcode——Product——Schema——Edit Scheme,查看run选择的模式,将项目由debug状态改成release状态 * ![目录](img/找到编辑scheme.png) * ![选择release](img/选择release.png) 8. 在左上角选中MyApp > Ceneric IOS Device, ![选择](img/选择打包.png) 9. 点击xcode ios里的根目录,在General和Signing & Capabilities菜单中,填写项目信息 * ![填写信息1](img/填写打包信息.png) * ![填写信息2](img/填写打包信息2.png) 10. 点击Product——Archive开始打包。显示build完成之后,显示如下弹框:点击Distribute App * ![打包后选择](img/打包后选择1.png) * ![打包后选择2](img/打包后选择2.png) * ![打包后选择3](img/打包后选择3.png) * ![打包后选择4](img/打包后选择4.png) * ![打包后选择5](img/打包后选择5.png) # 项目开发经验 ## UI框架react-native-mobile 使用步骤: 1. 核心包下载: ``` npm install @ant-design/react-native --save ``` 2. 使用: ``` import React, { Component } from 'react'; import { AppRegistry } from 'react-native'; import Button from '@ant-design/react-native/lib/button'; class HelloWorldApp extends Component { render() { return ; } } AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp); ``` 3. 详细文档请看:https://rn.mobile.ant.design/index-cn ## 多环境配置 * 详细文档请看: https://github.com/luggit/react-native-config * 下载安装包: 当前版本("react-native-config": "^1.3.1") ``` yarn add react-native-config ``` * 连接库: (react-native 0.60版本后可以不执行这个命令) ``` npx react-native link react-native-config ``` * ios端需要连接库: ``` 在当前项目下进入ios目录, 执行: pod install ``` * android端链接库: 1. 在当前项目下的android/settings.gradle添加: ``` include ':react-native-config' project(':react-native-config').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-config/android') ``` 2. 将插件添加到android/app/build.gradle中: ``` apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle" ``` * 基本使用 1. 在项目根路径下新建.env.development和.env.production文件,写点内容(文件名一定要.env开头,否则没有效果) ``` API_URL=https://myapi.com GOOGLE_MAPS_API_KEY=abcdefgh ``` 2. 在package.json中,添加命令: ``` "dev": "SET ENVFILE=.env.development && react-native run-android", "prod": "SET ENVFILE=.env.production && react-native run-android" ``` 3. 在js项目中使用该配置: ``` import Config from "react-native-config"; console.log(Config.API_URL); // 'https://myapi.com' ``` 4. 在android工程中使用多环境: ``` # 进入到andorid目录,执行: ENVFILE=.env.development ./gradlew assembleRelease ``` 5. 在ios工程中使用多环境: ``` The basic idea in iOS is to have one scheme per environment file, so you can easily alternate between them. Start by creating a new scheme: In the Xcode menu, go to Product > Scheme > Edit Scheme Click Duplicate Scheme on the bottom Give it a proper name on the top left. For instance: "Myapp (staging)" Then edit the newly created scheme to make it use a different env file. From the same "manage scheme" window: Expand the "Build" settings on left Click "Pre-actions", and under the plus sign select "New Run Script Action" Where it says "Type a script or drag a script file", type: cp ${PROJECT_DIR}/../.env.staging .env # replace .env.staging for your file ``` ## 配置绝对路径 * 为了防止引入时不断的../,使用babel-plugin-module-resolver * 下载安装包: ``` yarn add babel-plugin-module-resolver ``` * 在babel.config.js中改造并添加: ``` plugins: [ [ 'module-resolver', { root: ['./src'], alias: { '@/utils': './src/utils', '@/pages': './src/pages', '@/components': './src/components', '@/models': './src/models', '@/assets': './src/assets' } } ] ] ``` * 在tsconfig.json中修改配置: ``` "baseUrl": "./src", "paths": { "@/assets/*": ["assets/*"], "@/components/*": ["components/*"], "@/models/*": ["models/*"], "@/pages/*": ["pages/*"], "@/utils/*": ["utils/*"], }, ``` * 使用方式和vue完全一样,以根路径为@ ``` import App from '@/src/pages/Home/Main' ``` ## 导航器react-navigation(5.x) 1. 安装核心包: ``` yarn add @react-navigation/native ``` 2. 安装相应的依赖包: ``` yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view ``` 3. 在根路径的index.js中引入react-native-gesture-handler,否则生产环境会报错 4. 在你应用的根路径Home/index.tsx中,使用NavigationContainer进行包裹: ``` import 'react-native-gesture-handler'; import {AppRegistry} from 'react-native'; import App from '@/src/pages/Home'; import {name as appName} from './app.json'; import { NavigationContainer } from '@react-navigation/native'; AppRegistry.registerComponent(appName, () => ); ``` ### 堆栈式导航器 1. 安装核心包: ``` yarn add @react-navigation/stack ``` 2. 创建堆栈式导航器 * createStackNavigator标签包含两个子组件Screen和Navigator ``` import React, { Component } from 'react' import { NavigationContainer } from '@react-navigation/native' import { createStackNavigator } from '@react-navigation/stack' import Home from '@/pages/Home' import Detail from '@/pages/Home/Detail' type RootStackList = { // 定义类型别名 Home: undefined, Detail: undefined } let Stack = createStackNavigator() export default class Navigator extends Component { render() { return ( ) } } # 最后在根路径引入即可 ``` * Stack.Navigator可以接收screenOptions属性,用于配置所有的导航器的样式 3. 页面传参: * home页面跳转到detail页面 ``` # home页面传递: this.props.navigation.navigate('Detail', {id: '123'}) # detail页面接收 {this.props.route.params.id} ``` * 详细代码请看 * router/index.tsx里: ``` import React, { Component } from 'react' import { NavigationContainer } from '@react-navigation/native' import { createStackNavigator, StackNavigationProp, HeaderStyleInterpolators, CardStyleInterpolators } from '@react-navigation/stack' import Home from '@/pages/Home' import Detail from '@/pages/Home/Detail' export type RootStackList = { // 定义类型别名,用于约束navigator组件,在添加组件时,这里必须声明类型 Home: undefined, Detail: { id: string } } // 该类型申明约束每一个页面组件的props export type RootStackNavigation = StackNavigationProp let Stack = createStackNavigator() export default class Navigator extends Component { render() { return ( ) } } ``` * Home.tsx里: ``` import React, { Component } from 'react' import { Text, View, Button } from 'react-native' import { RootStackNavigation } from '@/router/index' interface homeProps { navigation: RootStackNavigation } export default class Home extends Component { render() { return ( textInComponent