本地持久化
在涉及如主题变更等操作时,需要将状态信息保存,这时就需要用到类似于iOS 中的NSUserDefault, AsyncStorage 是React Native中的 Key-Value 存储系统,可以做本地持久化。
首先看它主要的几个接口:
根据键来获取值,获取的结果会放在回调函数中:
static geItem(key: string, callback:(error, result))
根据键来设置值:
static setItem(key: string, value: string, callback:(error))
根据键来移除项:
static removeItem(key: string, callback:(error))
获取所有的键:
static getAllKeys(callback:(error, keys))
设置多项,其中 keyValuePairs 是字符串的二维数组,比如:[['k1', 'val1'], ['k2', 'val2']]:
static multiSet(keyValuePairs, callback:(errors))
获取多项,其中 keys 是字符串数组,比如:['k1', 'k2']:
static multiGet(keys, callback:(errors, result))
删除多项,其中 keys 是字符串数组,比如:['k1', 'k2']:
static multiRemove(keys, callback:(errors))
清除所有的项目:
static clear(callback:(error))
网络请求封装
在React Native中,经常使用Fetch函数来实现网络请求,它支持GET和POST请求并返回一个Promise对象,这个对象包含一个正确的结果和一个错误的结果。
来看一下用Fetch发起的POST请求封装:
static post(url,data){ return new Promise((resolve,reject)=>{ fetch(url,{ method:'POST', header:{ 'Accept':'application/json', 'Content-Type':'application/json' }, body:JSON.stringify(data) }) .then(response=>response.json()) .then(result=>{ resolve(result); }) .catch(error=>{ reject(error); }) }) }
从上面的代码中,我们可以大致看到:Fetch函数中,第一个参数是请求url,第二个参数是一个字典,包括方法,请求头,请求体等信息。
随后的then和catch分别捕捉了fetch函数的返回值:一个Promise对象的正确结果和错误结果。注意,这里面有两个then,其中第二个then把第一个then的结果拿了过来。而第一个then做的事情是把网络请求的结果转化为JSON对象。
那么什么是Promise对象呢?
Promise 是异步编程的一种解决方案,Promise对象可以获取某个异步操作的消息。它里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
它分为三种状态:
Pending(进行中)、Resolved(已成功)和Rejected(已失败)
它的构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject:
- resolve函数的作用:将Promise对象的状态从“未完成”变成“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
- reject函数的作用:将Promise对象的状态从“未完成”变成“成功”(即从Pending变为Rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
GET 请求封装:
static get(url){ return new Promise((resolve,reject)=>{ fetch(url) .then(response=>response.json()) .then(result=>{ resolve(result); }) .catch(error=>{ reject(error); }) }) }
因为只是GET请求,所以不需要配置请求体,而且因为这个fetch函数返回值是一个Promise对象, 所以我们可以用.then和.catch来捕捉正确和错误的结果。
功能调试
我们可以使用浏览器的开发者工具来调试React Native项目,可以通过打断点的方式来看数据信息以及方法的调用:
- 首先在iOS模拟器中点击command + D,然后再弹出菜单里点击Debug JS Remotely。随后就打开了浏览器进入了调试。
- 浏览器一般会展示下面的页面,然后点击command + option + J进入真生的调试界面。
双平台适配
因为React Native讲求的是一份代码跑在两个平台上,而客观上这两个平台又有一些不一样的地方,所以就需要在别要的时候做一下两个平台的适配。
例如导航栏:在iOS设备中是存在导航栏的,而安卓设备上是没有的。所以在定制导航栏的时候,在不同平台下给导航栏设置不同的高度:
const NAV_BAR_HEIGHT_IOS = 54; const NAV_BAR_HEIGHT_ANDROID = 50; // css navBar: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', height: Platform.OS === 'ios' ? NAV_BAR_HEIGHT_IOS : NAV_BAR_HEIGHT_ANDROID, },
上面的Platform是React Native内置的用于区分平台的库,可以在引入后直接使用。
建议在调试程序的时候,同时打开iOS和Android的模拟器进行调试,因为有些地方可能在某个平台上是没问题的,但是另一个平台上有问题,这就需要使用Platform来区分平台。
开源组件库的使用
ReactNative 的组件与原生的组件有许多共同之处,如下拉刷新,同样的 Github 中开源组件已经相当完善。
开源组件库方法如下,安装最新版本:
npm install react-native-tab-navigator --save
安装指定版本:
npm install --save react-native-tab-navigator@0.4.0
react-native 集成组件绑定(ReactNative 0.27以后,自集成RNPM):
react-native link react-native-splash-screen
常用开源库:
npm install --save react-native-tab-navigator@0.4.0 npm install --save react-native-scrollable-tab-view@0.7.0 npm install --save react-native-check-box@1.0.4 npm install --react-native-easy-toast@1.0.9 npm install --save GitHubTrending@2.0.0 npm install --save react-native-htmlview@0.5.0 npm install --save react-native-popover@0.5.0 npm install --react-native-splash-screen@2.0.0
下图为使用 react-native-splash-screen 后的效果演示:
热更新
CodePush 是微软提供的一套用于热更新 React Native 和 Cordova 应用的服务。
CodePush 是提供给 React Native 和 Cordova 开发者直接部署移动应用更新给用户设备的云服务。CodePush 作为一个中央仓库,开发者可以推送更新 (JS, HTML, CSS and images),应用可以从客户端 SDK 里面查询更新。
Code-Push 推包命令:
code-push release-react <appName> <platform> [options]
示例:
code-push release-react RNAPPGithub ios --t 1.0.0 --dev false --d Staging --des "1.热更新我的页面背景色" --m true
code-push release-react RNAPPGithub ios --t 1.0.1 --dev false --d Staging --des "1.热更新相关设置" --m true
Code-Push 线上查看更新:
code-push deployment ls RNAPPGithub
Code-Push 查看项目Key:
code-push deployment ls RNAPPGithub -k
Code-Push iOS更新打包方法:
react-native bundle --platform ios --entry-file index.ios.js --bundle-output release_ios/main.jsbundle --assets-dest release_ios/ --dev fasle
总结
之前也有零零散散的调研这门技术,但是经过系统的 15 个下午的坚持学习,深感跨平台技术的独到之处,特别是在与原生交互的编写上简直让人欲生欲死,还好在 Github 上已经有各路大神开源的各种方便开发的组件库可以供我们使用。
分享链接
《React Native 开发常用命令行(持续更新)》(https://juejin.cn/post/6844903585038204941)
《ReactNative 开发常用的三方模块》(https://www.jianshu.com/p/53ff78168acc)
《使用VS Code调试React-Native程序》(https://jingyan.baidu.com/article/ad310e80fb13fc1849f49ed1.html)
参考资料
- React Native中文网
- 贾鹏辉的技术博客
- 从一个实战项目来看一下React Native开发的几个关键技术点
- Marno:给所有开发者的React Native详细入门指南
- 大漠:一个完整的Flexbox指南
- 阮一峰:Flex 布局教程:语法篇
- 八段代码彻底掌握 Promise
- 阮一峰:Promise对象
- asce1885:React Native 高质量学习资料汇总
- 世锋日上:ReactNative 学习资源大汇集