WdBly Blog

懂事、有趣、保持理智

WdBly Blog

懂事、有趣、保持理智

周维 | Jim

603927378@qq.com

React Native 开发实践(二)

从环境搭建,项目实战,到总结的文章 webView 高度问题,网络图片处理,mobx 监听数据 错误处理等

环境搭建

项目

1:克隆项目

2:yarn下载依赖

3:注意node版本问题

android

1:安装android studio(注意版本,要和项目兼容)

2:参看官方环境安装文档

ios

使用react-native init创建一个新项目时,默认是使用最新稳定的react-native版本,当然也可以指定版本如 react-native init --version 0.59.0

使用xcode打开项目,在虚拟设备上运行debug或者是release的包

ios 开发者账号,平台,证书等

安装 React Native Debugger

开发事项

ios端borderRadius只适合View组件

背景图片实现

render (){ return ( <Image source={'./background.png'} > <Text>这个文本下面有背景哦</Text> </Image> ) }

webView 高度问题

网络图片

<Image source={{uri: 'https://www.a.aa/image/a.jpg'}}
注意需要指定宽高

mobx 监听数据

Observable Objects
如果使用observable来修饰一个Javascript的简单对象,那么其中的所有属性都将变为可观察的,如果其中某个属性是对象或者数组,那么这个属性也将被observable进行观察,说白了就是递归调用。
需要注意,只有对象上已经存在的属性,才能被observable所观测到。
若是当时不存在,后续添加的属性值,则需要使用extendObservable来进行添加。

transform

对Animated.View等组件添加transform translateY可以让其有一个吸顶的效果。

需要添加useNativeDriver: true, 需要在Animated.ScrollView中。

若是需要ref的scrollTo方法 则需要在this.myScrollView._component中去调用

Animated.event可以设置useNativeDriver: true, 但是与此同时不能对backgroundColor等样式设置动画。

由于安装插件导致的报错问题

getaddrinfo ENOTFOUND registry.npm.taobao.org registry.npm.taobao.org:443

1:找到 registry.npm.taobao.org的ip地址, mac中使用命令:

 nslookup registry.npm.taobao.org

添加hosts:

vim /etc/hosts

x.x.x.x    registry.npm.taobao.org

2: 同理可以在hosts中添加 registry.npmjs.org

3:运行命令查看结果:

npm info express --verbose

npm install Could not resolve host: github.com

同上个问题: 添加github.com的hosts解决

npm install maximum call stack size exceeded

1: npm cache clean --force //无效

2: npm rebuild //无效

3: rm package-lock.json rm -r node_modules //无效

4: rm /User/用户/.npmrc , 然后重启机器解决。

xcode 添加sdk framework文件夹。

  1. 下载sdk
  2. xcode - file - add file to …
  3. option
  4. 选中sdk文件, 点击Add

Connection to http://localhost:8081/debugger-proxy?role=client timed out. Are you running node proxy? If you are running on the device, check if you have the right IP address in RCTWebSocketExecutor.m.

react native 真机调试报错

  1. 首先确保手机和电脑在同一网络下
  2. 修改Libraries/RCTWebScoket.xcodeproj/RCTWebsocketExecutor.m
  3. 将 *host后的 localhost 修改为电脑的ip地址
  4. 重新run

React Native 使用FormData实现文件图片上传

  1. 在axios的请求拦截中,不要格式化parmas,FormData格式的数据不用格式化。
  2. 从相册中获取到的图片,RN可以支持uri的方式上传如:
var body = new FormData(); body.append("image", { uri: img.path, type: img.mime, name: "image.jpg" })
  1. 但是,React-Native-Debugger在开启网络检查后,不支持uri的方式上传FormData。
  2. 关闭方法, 删除代码中的下面的部分
    // global.XMLHttpRequest = global.originalXMLHttpRequest
    // ? global.originalXMLHttpRequest
    // : global.XMLHttpRequest;
    // global.FormData = global.originalFormData
    // ? global.originalFormData
    // : global.FormData;
  3. 打开Debugger客户端,右键关闭network inspect
  4. image.png

注意点,若是上传图片时后端获取不到图片, 上传显示的内容是[object object] ,请查看是否是对FormData数据进行了格式化。

react native android 中webview无法滑动

android中的webview无法滚动, 需要设置webview高度后,在外层添加一个ScrollView. ios不用这个操作。

react native webview loading

如果需要给webview添加loading需要注意给loading组件添加高度。

Task :react-native-screens:compileDebugJavaWithJavac FAILED

这是由于androidx的不兼容导致的

解决:android project -> app -> build.gradle文件

// 在dependencies 添加这一句 dependencies { ... annotationProcessor 'androidx.annotation:annotation:1.0.0' }

某些定位元素在视觉上在上方,而实际交互不能触摸到。

react native中的层级是根据组件出现的顺序来确定的,将定位的组件置于页面的底部即可。

拦截webview中的链接

// 注入如下js var a = document.getElementsByTagName("a"); for(var i = 0; i < a.length; i++){ a[i].onclick = function (event) { var href = this.href; window.ReactNativeWebView.postMessage(JSON.stringify({ type: "routeJump", href: href, })); event.preventDefault(); } } // onMessage监听 onMessage = event => { try { const action = JSON.parse(event.nativeEvent.data); switch(action.type) { case "routeJump": Linking.openURL(action.href); break; } } catch (error) { console.log(error); } }

断网提示问题

使用全局高层浮窗显示提醒用户断网了

react navigation drawer使用

不太适用于需要传参动态显示的路由

react native Image 动态加载本地图片require无法使用变量的解决

这样使用会报错:

var src = "../../img/common.png" <Image source(require(src)) />

修改后:

var src = require("../../img/common.png"); <Image source(src) />

xcode报错某个node_modules中的模块没有找到时的查找路线, ‘RNSplashScreen.h’ file not found, xxx.h file not found

1: 查找Libraries 下是否包含此目录:
image.png

正常 npm install 或者 yarn安装后,需要react-native link 仓库。

link的步骤就是从node_modules向Libraries添加.xcodeproj文件。

如不不包含,请先确认node_modules中是否包含库:
image.png

npm在下载时往往会丢失部分仓库, 推荐使用yarn 安装依赖

2:是否link仓库

3:react-native remove 仓库,然后yarn, 然后link。
如果还是不行就手动 将.xodeproj文件从node_modules移动到Libraries目录

React Native Webview 页面加载缓慢解决:

在实际使用中,我们的webview 加载loading使用的是webview的renderLoading组件,并在webview的onLoadEnd事件中 取消loading。

但在实际操作中出现了一些问题, 我们的webview加载太慢了, loading时间非常长。

起初我以为是网站资源过多,且webview没有缓存导致加载时间过长,从而一直loading。

最后研究发现:
image.png

大部分资源都是从缓存中获取的,但是为什么loading时间这么久呢?

原因在于部分资源加载时间太长,导致onLoadEnd事件迟迟无法触发导致的:

<WebView renderLoading={() => ( <Loading value={this.state.loading} height={height - scaleWidth(88) - global.statusBarHeight} /> )} onLoadEnd={() => { injectJs && this.webViewRef.injectJavaScript(injectJs); // 这里迟迟没有执行 this.setState({loading: false}) }} />

解决方案: 通过注入一段js代码,当执行此代码时取消loading即可。

this.BaseScript = ` window.ReactNativeWebView.postMessage(JSON.stringify({ type: "loadingEnd" })); true; `; // 在onMessage中监听。

解决方案不成立,测试发现,注入的js代码同样会在资源加载完毕后才会执行。

解决方案二: 暂无;

React Native 接口请求后的回调不执行,点击后执行

这是开发环境 连接调试工具的问题。取消远程调试试试。

React Native webview 中的视频自动播放, 阻止webview视频自动播放 disable auto play in WebView React Native:

<Webview mediaPlaybackRequiresUserAction={true} />

React Native 和 webview的通讯

1:在RN中点击一个按钮,需要触发webview中的点击事件, 可以直接执行点击事件的函数,但是这样拿不到事件对象,同时一些框架封装的事件不能直接在外边环境执行,除非将事件挂载到window上。 使用 .click()方法模拟点击,前提是被点击的元素必须是 input或button元素。

React 通过ref执行子组件的方法

ref={ref => (this.children = ref)} //调用 this.children.methodName()