react-native 踩坑记

时间:2022-09-01 13:19:09

最近在使用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. AndroidStudio快捷键

    在这里,自己整理了下在使用AndroidStudio开发工具所使用到的一些快捷键提示,也出于在开发过程中节省时间提升效率,然而可能多数开发者之前使用的都是Eclipse开发工具,可能开始都不习惯,但是 ...

  2. 谈谈 ES6 的 Promise 对象

    https://segmentfault.com/a/1190000002928371 前言 开篇首先设想一个日常开发常常会遇到的需求:在多个接口异步请求数据,然后利用这些数据来进行一系列的操作.一般 ...

  3. PayPal 高级工程总监:读完这 100 篇文献,就能成大数据高手

    原文地址 开源(Open Source)对大数据影响,有二:一方面,在大数据技术变革之路上,开源在众人之力和众人之智推动下,摧枯拉朽,吐故纳新,扮演着非常重要的推动作用:另一方面,开源也给大数据技术构 ...

  4. 6-Highcharts曲线图之带标识

    <!DOCTYPE> <html lang='en'> <head> <title>6-Highcharts曲线图之带标识</title> ...

  5. 【Python】python 多线程两种实现方式

    目前python 提供了几种多线程实现方式 thread,threading,multithreading ,其中thread模块比较底层,而threading模块是对thread做了一些包装,可以更 ...

  6. TensorBoard:Visualizing Learning 学习笔记

    为了更方便的理解.调试和优化TF程序,我们可以使用TensorBoard(可视化工具).可以使用TensorBoard查看graph,绘制图表执行过程中的定量指标.TensorBoard是完全可配置的 ...

  7. 【Python实战】模块和包导入详解(import)

    1.模块(module) 1.1 模块定义 通常模块为一个.py文件,其他可作为module的文件类型还有".pyo".".pyc".".pyd&qu ...

  8. tomcat运行后提示Could not create the Java Virtual Machine&period;

    大致的问题是Java虚拟机(JVM)分配的内存大于系统可用内存,一开始去网上找了些资料,大多是都是说修改MyEclipse安装目录下的elicpse.ini文件中的内存大小.但我试了之后发现然并软,后 ...

  9. webpack学习--安装

    webpack需要在node环境运行,可以去node官网进行下载安装包:http://nodejs.cn/download/ 1.打开cmd命令窗口,运行node -v 2.全局安装webpack:n ...

  10. python爬虫中scrapy框架是否安装成功及简单创建

    判断框架是否安装成功,在新建的爬虫文件夹下打开盘符中框输入cmd,在命令中输入scrapy,若显示如下图所示,则说明成功安装爬虫框架: 查看当前版本:在刚刚打开的命令框内输入scrapy versio ...