React Native从0.39.x升级到0.49.x的那些事
前言:
由于公司的RN的版本(v0.39.4)太老了,所以打算升级到最新的版本(0.49.3)(其实是为了使用FlatList等一些新特性及减少框架带来的bug),由于中间的版本跨度太大,所以特地记录下升级的一些要点,有一些是框架本身跟,还有一些是第三方库引起的
注意:
1.目前是以0.49.x版本为准,如果是低于这个版本,可能有些错误并不会出现
2.下面的问题有一些是警告,我也一并修复了,因为这些警告在后面的版本可能就会变成错误
1.android下GIF图片不显示(没有动画)
在android/app/build.gradle中更新freso对应的gif动画库的版本(看API最好还是看英文官网,中文网的更新不及时)
dependencies { ... compile 'com.facebook.fresco:animated-gif:0.13.0' //需要从0.13.0升级到1.3.0 }
2.View.propTypes引起的错误
在RN0.44版本中,将View中的propTypes移动作为一个新的ViewPropTypes属性
● Move View.propTypes to ViewPropTypes (53905a5) - @bvaughn
注意:该问题在debug模式下可以运行(chrome里面console会显示错误),但是可以运行,release模式下直接报错,所以必须修改
修改方式:
import { Dimensions, PanResponder, NativeModules, StyleSheet, TVEventHandler, View, ViewPropTypes, } from 'react-native';
//然后将prop定义的View.propType的地方替换成ViewPropTypes
3.React16引起的相关问题
https://zhuanlan.zhihu.com/p/26250968?group_id=834155723037487104
主要有两处
- 将React库中的createClass方法移到一个独立的包 create-react-class
-
import createReactClass from 'create-react-class'; var Component = createReactClass({ })
废弃了React的PropTypes,将之移到一个独立的prop-types包中
-
import PropTypes from 'prop-types'; Component.propTypes = { text: PropTypes.string.isRequired, };
4.NetInfo的api变化了
在0.48.x版本中,NetInfo的API发生了变化(旧方式依旧兼容,但是会报警告),新的API解决了两个方面的问题
- The NetInfo API is currently platform-specific. It returns completely different values on iOS and Android. - The NetInfo API currently doesn't expose a way to determine whether the connection is 2g, 3g, or 4g.
具体查看:
5.zIndex问题
6.require() must have a single string literal argument" when bundling moment.js
因为动态引用的原因,在新版本中会出现不兼容的情况,目前出现的主要有两个库realm和moment
其中moment库很快就修复了该问题
Fixed in moment 2.19.0, working for me with RN 0.49.3. https://github.com/moment/moment/blob/develop/CHANGELOG.md
7.Touchable*直接作为容器引起的布局混乱
<TouchableOpacity activeOpacity={0.75} style={[styles.machineSection, { borderColor: wrapperBorderColor,flexDirection:'row',alignItems:'center',justifyContent:"space-between",paddingVertical:5,paddingLeft:5,backgroundColor:'#FAFCFF',marginTop:10,borderTopWidth:gScreen.onePix}]} onPress={this.selectAll.bind(this,sectionId,data)} > <View style={{flexDirection:'row',alignItems:'center',backgroundColor:'green'}}> <Image style={{width:25,height:25,borderRadius:12.5,marginRight:5}} source={avatar} /> <Text style={{color:gColors.color666,fontSize:gFont.size13}}>{data.userId===gUserData.Id?'自营':(data.group_name+' 的机器')}</Text> </View> <TouchableOpacity activeOpacity={activeOpacity} style={{alignSelf:'stretch',justifyContent:'center'}} onPress={this.selectAll.bind(this,sectionId,data)} > <Image style={{width:17,height:17,marginRight:10}} source={data.isSelected? require('../../../../resources/ico/slider_selected.png') : require('../../../../resources/ico/slider_blank.png')} resizeMode="contain" /> </TouchableOpacity> </TouchableOpacity>
8.Image作为容器
9.PermissionAndroid的api变化了
由PermissionsAndroid.requestPermission 变为 PermissionsAndroid.request
10.FlatList中的extraData
前面一直没有使用,也不明白这个值到底是干什么的,直到将一个场景的ListView升级为FlatList的时候遇到问题,
场景是点击右上角按钮,item中的箭头会变成一个圆圈,表示可以选中
通过this,state.removeMode控制是否处于编辑模式,点击右上角按钮会将removeMode设为true
这个在ListView中是没问题的,但是在FlatList中发现,renderItem方法(没有单独写一个component,只是一个方法)没有被重新触发,最后通过查找FlatList的代码发现
class FlatList<ItemT> extends React.PureComponent<Props<ItemT>, void> {
FlatList是直接继承PureComponent,this.state.removeMode并没有作为FlatList的一个属性,所以其改变并不会造成FlatList的重新渲染,此时需要设置extraData={this.state.removeMode},这样才能其效果
/** * A marker property for telling the list to re-render (since it implements `PureComponent`). If * any of your `renderItem`, Header, Footer, etc. functions depend on anything outside of the * `data` prop, stick it here and treat it immutably. */ extraData?: any,