react-native

react-native
文章图片

Learn once, write anywhere. 什么是react-native? React Native 是由 Facebook 创建和开发的跨平台框架。它允许使用 JavaScript 创建 Android 和 iOS 应用程序。
RN与原生技术 RN的优势

  1. 快速地开发和迭代。
    RN最大的优势是热重载,开发人员节省了代码编译的时间,而在使用原生编程语言时,这需要更长的时间。对代码所做的更改可以在几秒钟内看到,而不是像原生技术那样几分钟。
    React Native 开发的应用支持热更新,因为 React Native 的产物是 bundle 文件,其实本质上就是 JS 代码。在 App 启动的时候就会去服务器上获取 bundle 文件,我们只需要更新 bundle 文件,从而使得 App 不需要重新前往商店下载包体就可以进行版本更新,开发者可以在用户无感知的情况下进行功能迭代或者 bug 修复。但是值得注意的是,AppStore 禁止热更新的功能中有调用私有 API、篡改原生代码和改变 App 的行为。
  2. 成本低
    使用原生技术开发Android和iOS应用,需要相应的Android工程师和iOS工程师,也同时维护两套代码,而RN只需要一位会编写JavaScript且了解react框架的前端工程师。
  3. 上手快
    相比于原生开发,JavaScript 学习成本低、语法灵活。允许让 Web 开发者更多地基于现有经验开发 App。React Native 只需使用 JavaScript 就能编写移动原生应用,它和 React 的设计理念是一样的,因此可以毫不夸张地说:你如果会写 React,就会写 React Native!
原生体验 虽然RN使用JavaScript编写代码,但是它使用的是原生暴露出来的API和UI组件。
RN是在react基础上运行的,编写代码时,可以使用react调用React Native的Components来创建和原生一样外观和感觉的视图。在运行时,React Native 会为这些组件创建相应的 Android 和 iOS 视图。因此,体验和性能足以媲美原生应用
react-native
文章图片

RN 的不足
React Native 不支持原生 API 和 SDK,即如果您想访问相机、使用增强现实、语音助手或 SDK 进行移动支付,这迫使开发人员自己创建原生模块或使用 Java/Kotlin ( Android ) 或 Swift/Objective-C (iOS) 开发“bridge”,并严重增加软件开发时间。而原生技术则没有这种困扰。
RN应用的体验虽然可以媲美原生应用,但是在性能上却不及原生应用,它的一部分性能会消耗在js和原生的转化和通信上。
React-native原理
React Native 需要一个 JS 的运行环境,因为 React Native 会把应用的 JS 代码编译成一个 JS 文件(x x.bundle),React Native 框架的目标就是解释运行这个 JS 脚本文件,如果是 Native 拓展的 API,则直接通过 bridge 调用 Native 方法,最基础的比如绘制 UI 界面,映射 Virtual DOM 到真实的 UI 组件中。
react-native
文章图片

如何创建自定义的原生模块 Android
  1. 创建并编写原生模块
    首先是在包名(android/app/src/main/java/com/your-app-name/夹下)创建 CalendarModule.java Java 文件。
    package com.your-app-name; // replace com.your-app-name with your app’s name import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import java.util.Map; import java.util.HashMap; import android.util.Log; public class CalendarModule extends ReactContextBaseJavaModule { CalendarModule(ReactApplicationContext context) { super(context); } @Override public String getName() { return "CalendarModule"; }@ReactMethod // 将方法导出到js中 public void createCalendarEvent(String name, String location) { Log.d("CalendarModule", "Create event called with name: " + name + " and location: " + location); } }

  2. 注册模块
    编写原生模块后,需要创建MyAppPackage.java向 React Native 注册
    package com.your-app-name; // replace your-app-name with your app’s name import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MyAppPackage implements ReactPackage {@Override public List createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); }@Override public List createNativeModules( ReactApplicationContext reactContext) { List modules = new ArrayList<>(); modules.add(new CalendarModule(reactContext)); return modules; }}

  3. 将注册好的包添加的包列表
    android/app/src/main/java/com/your-app-name/MainApplication.java找到getPackages()方法,通过add方法将你的包添加到包列表。
    @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); // below MyAppPackage is added to the list of packages returned packages.add(new MyAppPackage()); return packages; }

  4. 在js中调用
    import { NativeModules } from 'react-native'; const { CalendarModule } = NativeModules; CalendarModule.createCalendarEvent('foo', 'bar');

    IOS
1.创建主要的自定义原生模块头文件和实现文件;.h文件是用于类的公共声明(如API)的头文件,而.m文件是私有实现。
创建头文件RCTCalendarModule.h,
//RCTCalendarModule.h #import @interface RCTCalendarModule : NSObject @end

2.创建实现文件RCTCalendarModule.m
// RCTCalendarModule.m #import "RCTCalendarModule.h" #import @implementation RCTCalendarModule// To export a module named RCTCalendarModule RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name location:(NSString *)location) { RCTLogInfo(@"Pretending to create an event %@ at %@", name, location); }@end

3.js访问
import { NativeModules } from 'react-native'; const { CalendarModule } = NativeModules; CalendarModule.createCalendarEvent('testName', 'testLocation');

环境搭建
如何搭建react-native的开发环境
搭建iOS开发环境中可能会遇到的问题
  1. pod install时报错
// 设备: Macbook M1 -- Crash Report log information -------------------------------------------- See Crash Report log file under the one of following: * ~/Library/Logs/DiagnosticReports * /Library/Logs/DiagnosticReports for more details. Don't forget to include the above Crash Report log file in bug reports.

解决方案
【react-native】参考cocoaPods github 相关issues

    推荐阅读