React-Native-DeviceEventEmitter

实现

DeviceEventEmitter在RN内的发送和接受消息。例如:

A页面注册通知:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import {DeviceEventEmitter} from'react-native';



//…



//调用事件通知



DeviceEventEmitter.emit('xxxName’,param);



//xxxName:通知的名称 param:发送的消息(传参)

B页面接收通知:

componentDidMount(){



varself =this;



this.listener =DeviceEventEmitter.addListener('xxxName',function(param){



// use param do something



});



}



//xxxName:通知的名称 param:接收到的消息(传参)



componentWillUnmount(){



this.listener.remove();



}



//在componentWillUnmount 内需要我们手动移除通知

知道DeviceEventEmitter的简单使用后

我的页面在获取到用户数据后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//注册监听事件,时间名称:changeMine 传参:jsonData.avatar(头像url)



DeviceEventEmitter.emit('changeMine',jsonData.avatar);

tabbar.js 文件:

componentDidMount(){



varself =this;



this.listener = DeviceEventEmitter.addListener('changeMine',function(url){



self.setState({



avatar:url



})



});



//通知开始,获取到url,调用setState 方法,刷新状态机,这时候实时的刷新了‘我的’图标



//最后别忘了移除通知



componentWillUnmount(){



this.listener.remove();



}

js 向 js 发送数据

DeviceEventEmitter.emit('自定义名称',发送数据);

例:边看边买退出登录之后,我的淘宝和详情页的钱包数据应该改变。这时,我们可以在退出登录请求返回退出登录成功时发送一个通知

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
userInfo.userLogout((success) = {



if (success) {




DeviceEventEmitter.emit('taobaoBind',{taobaoBind:false,walletSum:0.00,couponNum:0});



const nav = this.props.navigator;



const routers = nav.getCurrentRoutes();



if (routers.length 1) {



nav.pop();



}



}



});

然后在我的淘宝和详情页接收通知,并使用setState改变数据

DeviceEventEmitter.addListener('taobaoBind',(events) ={this.setState({walletSum : events.walletSum});});

js接受数据

DeviceEventEmitter.addListener('名称',(events) ={使用数据events});

android向js发送数据

1
2
3
4
5
6
7
8
WritableMap params = Arguments.createMap();

params.putString("message",msg.obj.toString());


reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)

.emit(eventName, params);

例:扫码轮询时,扫码成功可以向扫码页发送一个扫码成功的状态,输入密码完成时,也可以发送一个状态,使扫码页自动关闭。并将用户信息发给我的淘宝,详情页等。

React-Native-VSCode插件

控制组件显示与否的问题小结

问题说明

在开发React Native过程中,我们常常会根据一个变量的值是否为空来控制组件的显示与否。

一个简单的做法是{ someVariable && some text }

今天就因为写了这样的代码踩到了一个坑,导致App Crash了。

Error内容:RawText “” must be wrapped in an explicitcomponent.

分析了一波,发现是数据问题导致的。当下面的代码中someVariable的值为空字符串’’的时候,就会出现这种Error。

{ someVariable && some text }

测试结果

为了分析这个问题,针对someVariable为空的情况做了一些测试,结果如下:

case 1.{ ‘’ && some text }=>有Error,App会Crash

case 2.{ 0 && some text }=>有Error,App会Crash

case 3.{ null && some text }=> 没有Error,组件不会显示

case 4.{ undefined && some text }=> 没有Error,组件不会显示

case 5.{ NaN && some text }=>有Error,App会Crash

case 6.{ [] && some text }=> 没有Error,组件会显示

case 7.{ {} && some text }=> 没有Error,组件会显示

原因分析

为什么会出现以上结果呢?

为了分析这个问题首先需要明白expr1 && expr2的含义。

这个表达式是说当expr1为false的时候,会返回expr1,否则会返回expr2。

那么’’|0|null|undefined|NaN|[]|{}这些值到底是true还是false呢,我们可以在Chrome
Console上面通过两个非操作!!来测试一下。

从上面结果可以看到,’’|0|null|undefined|NaN的值是false,[]|{}的值为true。

好了,通过以上分析我们可以得到case 1 ~ case 6的结果如下:

case 1.{ ‘’ && some text }=>{ ‘’ }

case 2.{ 0 && some text }=>{ 0 }

case 3.{ null && some text }=>{ null }

case 4.{ undefined && some text }=>{ undefined }

case 5.{ NaN && some text }=>{ NaN }

case 6.{ [] && some text }=>{ some text }

case 7.{ {} && some text }=>{ some text }

在React Native中{ ‘’ }|{ 0 }|{ NaN }会被当做文本字符串,必须要包含在组件中,所以case 1、case
2、case 5会导致App Crash;case 3、case 4不会报错,也不会在页面上显示任何东西;case 5、case 6会在页面上显示some
text文本。

解决方案

为了规避App Crash的风险,有两个简单的方案来实现【根据变量的值是否为空来控制组件的显示与否】:

1.当变量类型为Object或Array时,可以使用lodash的isEmpty方法

{ !_.isEmpty(someVariable) && some text }

2.当变量为其他类型时,使用两个非操作

{ !!someVariable && some text }

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×