https://www.njleonzhang.com/2018/08/30/react-native-modules.html
一,新建demo項目
1,安裝環境
$ npm install -g yarn react-native-cli
$ npm install -g react-native-create-library
2,創建HelloWorld(demo)
$ react-native init AwesomeProject
如果命令行出現卡頓在這個位置,請移步:https://www.devdo.net/%E8%A7%A3%E5%86%B3react-native-init-%E5%88%9D%E5%A7%8B%E5%8C%96%E6%97%B6-info-installing-required-cocoapods-dependencies/
info Installing required CocoaPods dependencies
3,編譯並運行 React Native 應用
$ cd AwesomeProject
$ react-native run-android
如果運行不起來,如下:
error Failed to install the app. Make sure you have the Android development environment set up: https://reactnative.dev/docs/environment-setup. Run CLI with --verbose flag for more details. Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081
用Android studio打開/Users/z/code/rntest/AwesomeProject/android 叫項目轉一轉就好了
二,新建插件項目
1,選擇一個額外的目錄,開始創建插件。
react-native-create-library --package-identifier com.reactlibrary --platforms android,ios MyLibrary
2,編寫插件Module
進入創建好的插件目錄,找到xxxModule.java的文件,該Module它可以實現一些JavaScript所需的功能。
package com.reactlibrary; import android.widget.Toast; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Callback; import java.util.HashMap; import java.util.Map; import javax.annotation.Nullable; public class RNMyLibraryModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; private static final String DURATION_SHORT_KEY = "SHORT"; private static final String DURATION_LONG_KEY = "LONG"; public RNMyLibraryModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; } @Override public String getName() { return "RNMyLibrary"; } @Nullable @Override public Map<String, Object> getConstants() { Map<String, Object> constants = new HashMap<>(); constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG); constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT); return constants; } @ReactMethod public void show(String message, int duration) { Toast.makeText(getReactApplicationContext(), message, duration).show(); } }
getConstants()返回了需要導出給 JavaScript 使用的常量,它並不一定需要實現。
注解@ReactMethod,用於提供給JavaScript調用的方法,方法的返回類型必須為void。React Native 的跨語言訪問是異步進行的,所以想要給 JavaScript 返回一個值的唯一辦法是使用回調函數或者發送事件。
3. 編寫插件Package
注冊這個模塊。我們需要在應用的 Package 類的createNativeModules方法中添加這個模塊。
package com.reactlibrary; import java.util.Arrays; import java.util.Collections; import java.util.List; import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import com.facebook.react.bridge.JavaScriptModule; public class RNMyLibraryPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { return Arrays.<NativeModule>asList(new RNMyLibraryModule(reactContext)); } // Deprecated from RN 0.47 public List<Class<? extends JavaScriptModule>> createJSModules() { return Collections.emptyList(); } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return Collections.emptyList(); } }
4. 編寫index.js,用於返回native模塊
import { NativeModules } from 'react-native'; const { RNMyLibrary } = NativeModules; export default RNMyLibrary;
其中,RNMyLibrary這個名字需要與Module中getName()返回的字符串相同。
5. 引入插件
方法一:
打開插件目錄下package.json,記錄name的值。在這里示例為"name": "react-native-my-library"。接下來會link它。
使用命令行終端cd到插件根目錄,執行
$ yarn link
cd到項目根目錄,執行
$ yarn link "react-native-my-library"
使鏈接生效。它可以讓react native工程中的android和ios原生項目,自動去生成依賴(會在原生項目中生成配置代碼)。在項目根目錄執行
$ react-native link "react-native-my-library"
方法二:
打開項目目錄中的package.json,修改dependencies
"dependencies": { "react": "16.6.0-alpha.8af6728", "react-native": "0.57.4", "react-native-my-library": "file:../MyLibrary" }
react-native-my-library為插件的name,file后面帶的是插件目錄相對當前項目的路徑。然后cd到項目根目錄,執行
$ yarn $ react-native link "react-native-my-library"
6. 運行
$ react-native run-android
7. 更新Library
每次更新插件代碼,都需要將項目的鏈接清除,然后再重新鏈接。最好是清除緩存。為了避免說你更新的原生代碼沒有生效的情況。
方法一:
進入項目根目錄
$ react-native unlink "react-native-my-library" $ yarn unlink "react-native-my-library"
進入到插件目錄
$ yarn unlink
修改好插件代碼后,然后進入插件根目錄,刪除node_modules
$ rm -rf node_modules
需要重新鏈接。
$ yarn
同上【引入插件 一】的說明依次執行。
方法二:
進入項目根目錄
$ react-native unlink "react-native-my-library"
修改好插件代碼后,然后進入插件根目錄,刪除node_modules
$ rm -rf node_modules
需要重新鏈接。
$ yarn
同上【引入插件 二】的說明依次執行。
配置中出現的問題:
1. 找不到包引用
將VSCode和模擬器/命令行終端全部關掉,監聽端口8081的進程全部關閉。然后重新打開,重新運行。