最近在使用react-native的时候遇到了很多坑,这里给大家分享下

一.样式

react-native 虽然支持flex布局,但是所有的样式均是css样式的一个很小的集合,尤其是在安卓机下问题尤为凸显:

1.View内部的元素千万不要超出父级的范围,iso上问题倒是不大,安卓上就什么超出的都看不到了

2.lineHeight 可以用,不过千万不要写成小数,否则安卓上会直接崩溃

3.rn的样式不存在继承的情况,所以基本上每个节点都要写style,真的是体力活

4.如果Text的父级元素设置了背景颜色,那么ios下Text的背景颜色也是父级的背景颜色,要么自己写个Text重置下样式,要么就遇到了再改

5.react-native的字号是没有设置单位的,所以会随着系统设置的字体大小而变化,我也不知道这是不是坑,不过貌似有的app也没有管这个,如果硬要去设置Text的文字不随系统改变,安卓是可以统一设置的,ios上Text设置allowFontScaling ={false}就可以解决

二.异常

react-native 在发生js异常的时候,debug的时候会直接红屏幕,但是再release的时候直接会崩溃退出,解决办法

import ErrorUtils from "ErrorUtils" 
//这里应该做个判断,如果不是debug的才做这样的异常全局处理
ErrorUtils.setGlobalHandler((e)=>{
  //发生异常的处理方法,当然如果是打包好的话可能你找都找不到是哪段代码出问题了
  Alert.alert("异常",JSON.stringify(e))
});

三.fetch

react-native虽然自带有fetch,不过在使用的时候发现了一个问题,如果需要获取http的header头的时候问题就来了,可能得到的是一些千奇百怪的样式,这并不是react-native的错,而是第三方的 whatwg-fetch 留下的坑,当然也有人再github上跟react-native反映过这个问题,不过得到的解决方案都很坑,唯有一个办法,就是拷贝自己修改,修改如下:

1.注释该注释的

(function(self) {
'use strict';
   //注释这里,不然总是用的是全局的fetch
// if (self.fetch) {
// return
// }

2.修改该修改的

function parseHeaders(rawHeaders) {
var headers = new Headers()
     //把\t\n改成\t,因为一般header都是用\n来分割的
rawHeaders.split('\n').forEach(function(line) {
//rawHeaders.split('\t\n').forEach(function(line) {
var parts = line.split(':')
var key = parts.shift().trim()
if (key) {
var value = parts.join(':').trim()
headers.append(key, value)
}
})
}
return headers
}

3.直接import你改好的文件,fetch就可以用了

四.Modal

Mode控件在使用的时候要注意了,因为这个是rn提供的,并且也写的很清楚是最高层级的一个弹出层,所以你想要又打开Model又要跳转基本是无望的了,所以建议不要使用这个,最好是使用第三方的控件,我们用的是 react-native-modalbox + 高阶控件 实现的全遮盖的弹出层

五.点击屏幕其他位置关闭的菜单

这类菜单有个共同的特点就是点击屏幕其他地方然后菜单就关闭,我们的解决办法就是用自己写的 react-native-modalbox + 高阶控件 也就是说放在一个弹出层里面,当然可以试试把当前页面套进一个大的 TouchableWithoutFeedback 里面

六.接口请求

非特殊情况下都应该这样做

import {InteractionManager} from "react-native"

componentDidMount(){
InteractionManager.runAfterInteractions(() => {
fetch("xxx.xxx.xxx",{})
});
}

七.键盘

官方提供的自定义隐藏键盘的方法是

import { Keyboard } from 'react-native'

Keyboard.dismiss()

但是我试了很多次之后发现根本不能,而且还报错,楼主的react-native版本是0.35.0

看了官方的issue才知道这个不行,推荐下面方法

import dismissKeyboard from 'dismissKeyboard'
dismissKeyboard()

这样就可以隐藏了,太坑了  

还有个很坑的地方,官方提供的移除键盘事件的方法不可用

componentDidMount () {
  Keyboard.addListener('keyboardDidShow', this.keyboardDidShow.bind(this))
  Keyboard.addListener('keyboardDidHide', this.keyboardDidHide.bind(this))
} componentWillUnmount () {
Keyboard.removeAllListeners('keyboardDidShow')
Keyboard.removeAllListeners('keyboardDidHide')
}

这样的方式特么的如果操作快了,或者有时候莫名其妙的就会出错,下面的才是正确的打开方式:

componentDidMount () {
  this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this.keyboardDidShow.bind(this))
  this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this.keyboardDidHide.bind(this))
}
componentWillUnmount () {
this.keyboardDidShowListener.remove()
this.keyboardDidHideListener.remove()
}

八.https

https这个问题上ios还好,安卓问题就来了,前期我们准备将ajax请求的库丢给原生安卓和ios来做我们直接调用就是了,但是后来发现问题这样那样的问题太多了,

所以在热更新服务器启动或者打包的时候就把源代码先改了在进行打包或者启动服务器

文件位置:

node_modules/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/network/OkHttpClientProvider.java

这个文件的最后一个方法修改如下:

  private static OkHttpClient createClient() {
// No timeouts by default
return new OkHttpClient.Builder()
.sslSocketFactory(sslContext.getSocketFactory())
.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true; //忽略所有的认证,直接返回了true
}
})
.connectTimeout(0, TimeUnit.MILLISECONDS)
.readTimeout(0, TimeUnit.MILLISECONDS)
.writeTimeout(0, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer())
.build();
}

修改源代码的方式有点略坑,不过可以解决很多问题,还节约时间!!!

九.BackAndroid

安卓机有独特的点击按键返回,所以在最外层会注册一个监听方法

    bindHardwareBackPress(){
if (Platform.OS === 'android') {
BackAndroid.addEventListener('hardwareBackPress', this._onHomeBackPress);
}
} onHomeBackPress(){
let routeList = this.getRouteList();
if (routeList.length !== 1) {
this.navigator.pop();
return true;
} this.handleHomeBackPress();
return true;
} handleHomeBackPress(){
if (Platform.OS === "android") {
ToastAndroid.show("再按一次退出应用", ToastAndroid.SHORT);
BackAndroid.removeEventListener("hardwareBackPress", this._onHomeBackPress);
BackAndroid.addEventListener("hardwareBackPress", this._onExitApp);
this.timer = TimerMixin.setInterval(() => {
TimerMixin.clearInterval(this.timer);
BackAndroid.removeEventListener("hardwareBackPress", this._onExitApp);
BackAndroid.addEventListener("hardwareBackPress", this._onHomeBackPress);
}, 2000);
}
} exitApp(){
BackAndroid.exitApp();
}

上面的代码是监听返回键,如果不是在最外层的路由就返回上一个,如果在最外层就直接关闭app,但是有很多这样那样的需求要去对安卓的返回键进行操作,坑就来了,你以为提供的removeEventListener方法是没问题的?no !!! 他会移除所有的监听,这是不是很坑!!!!

所以:在需要对安卓返回键进行特殊处理的时候记得其他地方做了监听的再重新监听一次!!!!

react-native 踩坑记的更多相关文章

  1. React Native踩坑Tip

    最近在使用React Native(以下简称RN)中踩了个坑,RN只能异步调用原生方法,所以在原生方法直接调用UI刷新操作需要将任务递交到主线程才可以. RCT_EXPORT_METHOD(finis ...

  2. React Native踩坑日记 —— tailwind-rn

    项目背景 在项目的初始阶段,我们需要建立自己的design system,我们spike了一些方案,tailwind-rn就是其中一种,如果有用到或者即将用到tailwind-rn的,可以进来看一看, ...

  3. React Native踩坑之旅

    原文连接:http://www.studyshare.cn/blog-front/blog/details/1137 最近做一个app,使用React Native实现,如果严格按照RN官方文档去配置 ...

  4. react Native 踩坑记录

    应用 1 安卓打包 经验 解决方案 ,官方 解决方案 2 调试 用 React-Native-Debugger 教程 3 微信分享和登录 使用 react-native-wechat    地址 设计 ...

  5. React Native踩坑之FlatList组件中的onEndReached

    最近在做一个RN项目,有使用到FlatList这样一个RN封装的组件去做上拉加载更多功能,在iOS和Android平台上,总结了以下几个遇到的问题及解决方案 1. 进入页面onReached开始就被触 ...

  6. React Native踩坑之The SDK directory 'xxxxx' does not exist

    相信和我一样,自己摸索配置环境的过程中,第一次配,很可能就遇到了这个比较简单地错误,没有配置sdk环境 解决办法 在电脑,系统环境变量中,添加一个sdk的环境变量 uploading-image-95 ...

  7. React Native踩坑之无法启动Debug

    问题 在chrome启动debug模式,连接不到地址 解决办法 在模拟器中,ctrl+m调出command,选择dev setting,然后设置debug地址为localhost:8081

  8. React Native踩坑之启动android模拟器失败

    报错 Could not install the app on the device, read the error above for details.Make sure you have an A ...

  9. React Native踩坑之Unable to load script from assets

    报错: Unable to load script from assets 'index.android.bundle'. Make sure your bundle is packaged corr ...

  10. react native 踩坑之 SectionList state更新 不执行render重新渲染页面

    官方文档中指出 SectionList 本组件继承自PureComponent而非通常的Component,这意味着如果其props在浅比较中是相等的,则不会重新渲染.所以请先检查你的renderIt ...

随机推荐

  1. Spring--多人开发

    在spring中, 可以定义多个配置文件. 例子: ①首先定义一个班级类和一个学生类 1 package com.fuwh.spring;      }                    }    ...

  2. mysql ,服务器耗时测试

    测试一 字段:ID,test,number 电脑配置:8g内存 同时写入超过5w条,就会卡死 错误提示 Fatal error: Allowed memory size of bytes exhaus ...

  3. 图解TCP/IP→第2章基础知识

    ####TCP.IP背景**关键词:ARPANET,UNIX,分组交换技术,*ARPANET(阿帕网),也是全球互联网的鼻祖.阿帕网的成功也充分证明了基于分组交换技术的通信方法的可行性.*20世纪70 ...

  4. 面向对象编程(OOP)

    什么是面向对象编程,对于面向对象编程与面向过程编程的解释随处可见,个人认为对面向对象编程解释最好的一个定义是:依赖倒转原则是面向对象编程的标志,面向对象编程是一种思想,无论使用哪一种编程语言,如果在编 ...

  5. spring 静态注入

    1.静态注入 在setter 方法修改为非 static , 然后在上面注入即可 @Component public class WeixinConfig { // token public stat ...

  6. MySQL收藏

    MySQL手册:5.5手册 .5.6手册 cd /usr/local/mysql/bin mysql -uroot -p show processlist;   // 显示系统中正在运行的所有进程 M ...

  7. virtualBox上虚拟机和主机互联{}

    VirtualBox实现内外网络互访问的配置   环境: 宿主机操作系统            Windows XP sp3 虚拟机软件                       VirtualBo ...

  8. python画决策树

    1.安装graphviz.下载地址在:http://www.graphviz.org/.如果你是linux,可以用apt-get或者yum的方法安装.如果是windows,就在官网下载msi文件安装. ...

  9. mybatis逆向工程生成JavaBean、dao、mapper generatorSqlmapCustom

    import java.io.File; import java.util.ArrayList; import java.util.List; import org.mybatis.generator ...

  10. tail命令详解

    搜索 纠正错误  添加实例 tail 在屏幕上显示指定文件的末尾若干行 补充说明 tail命令 用于输入文件中的尾部内容.tail命令默认在屏幕上显示指定文件的末尾10行.如果给定的文件不止一个,则在 ...