今天在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()方法触发绑定的事件,执行回调,更新内容。

最新文章

  1. Android中使用AsyncTask实现文件下载以及进度更新提示
  2. JS中用new创建对象与不用new创建对象区别:
  3. nl2br() 函数
  4. docker swarm
  5. 前端架构:Angular与requirejs集成实践
  6. Winform後台如何動態修改App.config文件里的內容
  7. The Kernel Newbie Corner: Kernel Debugging with proc &quot;Sequence&quot; Files--Part 2
  8. Storm集群扩容——从单机模式拓展到集群模式,以此类推
  9. java Active Object模式(下)
  10. 炎黄流程中改流程节点颜色的js
  11. JS自学笔记02
  12. 我做SAP CRM One Order redesign的一些心得体会
  13. layui table 数据表格 隐藏列
  14. Java时间类总结
  15. 树莓派 Learning 002 装机后的必要操作 --- 04 添加软件源 之 添加公钥 --- 解决“由于没有公钥,无法验证下列签名”问题
  16. HTML5(lufylegend.js练习)
  17. JS高级学习历程-11
  18. hiho编程练习赛20
  19. Hibernate游记——装备篇《三》(连接池的使用)
  20. CSS3 伪类选择器 nth-child() 的用法

热门文章

  1. Javascript实现返回上一页面并刷新
  2. Token报错问题
  3. BFS 两个重要性质
  4. python 面试题3
  5. Servlet笔记3--Servlet生命周期
  6. gnome桌面无法使用笔记本的触摸板
  7. socket相关系统调用的调用流程
  8. Oracle 11G R2 RAC中的scan ip 的用途和基本原理【转】
  9. ASP.NET 实现Base64文件流下载PDF
  10. jQuery插件之ajaxFileUpload(异步上传图片并实时显示,并解决onchange后ajaxFileUpload失效问题)