在react native中會涉及到很多頁面之間的參數傳遞問題。靜態的參數傳遞通常利用組件的Props屬性,在初始化組件時即可從父組件中將參數傳遞到子組件中。對於非父子關系的組件來說,無法直接傳遞參數,此時可能會用到react-navigation來傳遞;此外,若要將異步函數、不可預料的事件執行等得到的參數用於頁面刷新時,前述的方法都不太奏效。
DeviceEventEmitter
react-native中采用了DeviceEventEmitter來實現對事件的監聽,實現非父子關系的頁面之間的通信。具體來說,我們可以在一個頁面中通過DeviceEventEmitter來對特定名稱的事件進行監聽,此后每當其它位置發送該名稱的事件,都會觸發這個監聽的響應並執行對應的函數。
DeviceEventEmitter優點在於一次注冊多次響應,並且注冊后的監聽事件是全局性的。不僅如此,通過DeviceEventEmitter還可以與原生模塊進行交互。
基本語法
導入DeviceEventEmitter
首先要引入DeviceEventEmitter,DeviceEventEmitter在原生庫中,直接引入即可:
import { DeviceEventEmitter } from 'react-native';
注冊監聽事件
通常來說我們會在組件加載完成后開始監聽事件:
componentDidMount(){
this.emitter = DeviceEventEmitter.addListener('eventName’, function);
};
addListener('eventName’, function);
擁有兩個參數,第一個參數是監聽事件的名稱,為字符串類型;第二個參數是觸發監聽事件后的回調函數。
發送監聽事件
注冊監聽后,我們可以在任意位置直接使用DeviceEventEmitter.emit('eventName',params)
來廣播一個事件。該函數也有兩個參數。第一個參數同樣為事件名稱;第二個參數為可選項,用於參數的傳遞。
卸載監聽事件
當頁面卸載時,卸載監聽事件:
componentWillUnmount() {
this.emitter.remove()
}
與原生通信
只需要在原生模塊中廣播該事件即可。具體代碼如下:
private void sendEvent(ReactContext reactContext,String eventName, @Nullable WritableMap params) {
reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
上述代碼發送了一個名為eventName的包含params參數的事件,值得注意的是發送該事件的前提是react native環境已經加載完成,需要獲取其上下文ReactContext。
示例——react native響應通知消息點擊事件
react native無法直接監聽廣播事件,因此需要用到原生模塊協助。此處通過兩次監聽事件,采用安卓原生廣播+安卓與react native通信來實現react native對通知消息點擊事件的響應。
獲取通知內容
第一步采用通過安卓原生模塊監聽通知點擊事件(參見安卓廣播機制)並獲取到通知攜帶的參數信息。
public static class NotificationReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("androidNotification")){//響應通知事件
String params = intent.getExtras().getString("params");
if(params != null){
sendEventToRn("RNnotification",params);//發送事件給RN
}
}
}
}
public static void sendEventToRn(String eventName, @Nullable String params){
//這里的模塊中context已經獲取
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit("notification", params);
}
'RNnotification','androidNotification'為靜態注冊的廣播接收器。廣播的發送需要在通知消息的設置處自定義。本項目中處理過程如下:
Intent intent =new Intent();
intent.setAction("androidNotification");
intent.putExtra("params",msg.getRaw().toString());
Activity currentActivity = MainActivity.getCurrentActivity();//這里獲取的是當前activity
currentActivity.sendBroadcast(intent);
然后在react native中監聽通知事件'RNnotification'
DeviceEventEmitter.addListener('notification',this.notification);
console.log('開始監聽通知');
notification = (paramString) =>{
//...此處實現了根據參數導航到指定頁面
}
大功告成。