今天在Demo这样一个项目的时候,首先遇到的第一个问题就是,每次通过dialog选择【本周、本月、本天】时,伴随着内容重新渲染的时候,tab navigator每次都重新创建和渲染,造成性能浪费和用户体验差的问题

问题分析:

由于tab navigator是在render()函数中动态创建的,因此每次随着状态的改变,render都会重新渲染,从而导致的问题是,每次都要重新动态创建tab navigator。

解决方案

将创建好的tabNav给绑定到当前this上,如果当前tabNav已经存在,则直接返回。

伪代码

export default class TrendingPage extends Component<Props> {
constructor(props) {
super(props);
this.tabNames = ['All', 'C', 'C#', 'PHP', 'JavaScript'];
}
/**
* 优化tabNav 避免每次render的时候都要重新动态的创建nav
*
* 优化效率:根据需要选择是否重新创建TabNavigator,通常tab改变后才重新创建
* @returns
* @memberof TrendingPage
*/
_tabNav() {
if (!this.tabNav) {
this.tabNav = createMaterialTopTabNavigator(
this._genTabs(), {
tabBarOptions: {
tabStyle: styles.tabStyle,
upperCaseLabel: false, //是否标签大写,默认为true
scrollEnabled: true, // 选项卡排不下的时候,可以滚动,默认为false
style: {
backgroundColor: '#678',
height: 30,
},
indicatorStyle: typeAlias.indicatorStyle, // 标签指示器的样式
labelStyle: styles.labelStyle
}
}
);
}
return this.tabNav;
} _genTabs() {
const tabs = {};
this.tabNames.forEach((item, index) => {
tabs[`tab${index}`] = {
// screen: PopTab,
screen: props => <TrendingTabPage {...props} timeSpan={this.state.timeSpan} tabLabel={item} />,
navigationOptions: {
title: item
}
}
})
return tabs;
} /* 省略其他代码*/
}

但是随之出现了接下来的问题,就是当我们通过在dialog选择完【本周】后,导航栏不变的情况下不重新动态创建了,下面的数据也不刷新了,从而导致该功能失效。

问题分析

由于带有信息list的screen是绑定在创建tab navigator中,因此当tab navigator不重新创建时,screen内容将不会重新渲染,那么我们又要保持当tab不改变的时候不重新创建和渲染,又想要当前tab下的内容根据用户操作而改变。

解决方案

使用react-native官方的一个API-----DeviceEventEmitter

使用方法

componentDidMount() {
this.loadData();
this.timeSpanChangeListener = DeviceEventEmitter.addListener(EVENT_TYPE_TIME_SPAN_CHANGE, (timeSpan) => { //将监听事件绑定到当前this上的目的是在组件卸载时能撤销事件
this.timeSpan = timeSpan;
this.loadData();
})
} componentWillUnmount() {
if (this.timeSpanChangeListener) {
this.timeSpanChangeListener.remove();
}
}

DeviceEventEmitter.addListener()注册上事件,第一个参数是事件,第二个参数是事件触发时候的回调。注意在组件卸载时撤销事件的绑定,避免性能浪费。

    /**
* 当从selection中选择一个触发的回调
*
* @param {*} tab
* @memberof TrendingPage
*/
onSelectTimeSpan(tab) {
this.dialog.dismiss();
this.setState({
timeSpan: tab
});
DeviceEventEmitter.emit(EVENT_TYPE_TIME_SPAN_CHANGE, tab)
} /**
* 创建一个TrendingDialog
*
* @returns
* @memberof TrendingPage
*/
renderTrendingDialog() {
return <TrendingDialog
ref={dialog => this.dialog=dialog}
onSelect={tab=>this.onSelectTimeSpan(tab)}
/>
}

然后,我们给【本周、本天、本月】添加上回调onSelectTimeSpan,当用户操作的时候,触发回调,然后通过DeviceEventEmitter.emit()方法触发绑定的事件,执行回调,更新内容。

React Native之DeviceEventEmitter发送和接收消息完成事件处理的更多相关文章

  1. React Native使用 DeviceEventEmitter发送通知emit和监听接收addListener的用法

    js 向 js 发送数据 DeviceEventEmitter.emit('自定义名称',发送数据);   例:边看边买退出登录之后,我的淘宝和详情页的钱包数据应该改变.这时,我们可以在退出登录请求返 ...

  2. ROS_Kinetic_26 使用rosserial_windows实现windows与ROS master发送与接收消息

    使用rosserial_windows实现windows与ROS master发送与接收消息(适用版本hydro,indigo,jade,kinetic) 官方wiki地址汇总请参考:http://b ...

  3. ActiveMQ实例1--简单的发送和接收消息

    一.环境准备 1,官网http://activemq.apache.org/下载最新版本的ActiveMQ,并解压 2,打开对应的目录,在Mac环境下,一般可以运行命令: cd /Users/***/ ...

  4. ActiveMQ 发送和接收消息

    一.添加 jar 包 <dependency> <groupId>org.apache.activemq</groupId> <artifactId>a ...

  5. rabbitMQ学习笔记(二) 简单的发送与接收消息 HelloWorld

    首先要下载rabbitmq的javaClient库,然后加入到项目中,下载地址为:http://www.rabbitmq.com/releases/rabbitmq-java-client/v3.1. ...

  6. 关于Java客户端连接虚拟机中的Kafka时,无法发送、接收消息的问题

    kafka通过控制台模拟消息发送和消息接收正常,但是通过javaAPI操作生产者发送消息不成功 消费者接收不到数据解决方案? 1.问题排查 (1)首先通过在服务器上使用命令行来模拟生产.消费数据,发现 ...

  7. 生产/消费 发送和接收消息---基于kombu和redis交互

    from kombu import Connection, Exchange, Queue media_exchange = Exchange('media', 'direct', durable=T ...

  8. C# WinForm UDP 发送和接收消息

    using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; ...

  9. XMPP客户端开发(2)--发送接收消息

    客户端连接上服务器并登录以后,可以发送.接收消息. 首先需要定义Chat,MessageListener和ChatMessageListener几个变量: private static Chat ch ...

随机推荐

  1. idea绘制activity流程图中文乱码解决

    发现问题: 绘制activity的bpm工作流程图的时候,在name项中填写中文,开始的时候没问题,显示的确是中文,关闭文件再打开发现已经乱码,重启idea效果相同,如图 解决方案:修改idea启动参 ...

  2. CSS中的选择器(笔记)

    1.通配符选择器(*):通配符选择器是用来选择所有元素,也可以选择某个元素下的所有元素.所有浏览器都支持通配符选择器. ;;} .dome *{padding: 2px;} 2.元素选择器(Ele): ...

  3. C++中getline()和cin()同时使用时的注意事项

    今天做tju的oj,遇到一个问题,想前部分用cin函数一个一个的读入数据,中间部分利用getline()一起读入一行,但是测试发现,cin之后的getline函数并无作用,遂谷歌之.原来cin只是在缓 ...

  4. HDU 4521 小明系列问题——小明序列 (线段树 单点更新)

    题目连接 Problem Description 大家都知道小明最喜欢研究跟序列有关的问题了,可是也就因为这样,小明几乎已经玩遍各种序列问题了.可怜的小明苦苦地在各大网站上寻找着新的序列问题,可是找来 ...

  5. JavaScript 实用技巧和写法建议

    1.前言 从大学到现在,接触前端已经有几年了,感想方面,就是对于程序员而言,想要提高自己的技术水平和编写易于阅读和维护的代码,我觉得不能每天都是平庸的写代码,更要去推敲,去摸索和优化代码,总结当中的技 ...

  6. C++ Primer 5th 第14章 重载运算与类型转换

    当运算符作用域类类型的对象时,可以通过运算符重载来重新定义该运算符的含义.重载运算符的意义在于我们和用户能够更简洁的书写和更方便的使用代码. 基本概念 重载的运算符是具有特殊名字的函数:函数名由关键词 ...

  7. 使用IntelliJ IDEA新建maven的javaWeb项目部署,启动访问index,jsp页面

    对于用惯了eclipse的人,idea其实还挺不一样的,也是摸索了很久,看了好多博客,这里就记录一下,以后肯定经常用!,不过使用熟练了,功能确实非常强大,真的牛! 1 新建maven项目,配置好目录结 ...

  8. 与JavaWeb有关的故事(Web请求与Java IO)

    作为一名后端屌丝程序员,对算法.并发.性能乐此不疲.但是,随着年龄和阅历的增加,显然叶落而不知秋的心态是不太能混了.尤其是,某T面试官在明知我是后端,且明确表示对HTTP协议不太熟的情况下,强行让我解 ...

  9. Pytorch数据变换(Transform)

    实例化数据库的时候,有一个可选的参数可以对数据进行转换,满足大多神经网络的要求输入固定尺寸的图片,因此要对原图进行Rescale或者Crop操作,然后返回的数据需要转换成Tensor如: import ...

  10. Java标记接口

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈" ...