本篇博客主要记录windows下使用react native的一些经验。
当前最新版本为0.56(截至2018.8.1),使用命令:npm info react-native 可以查看最新版本。
环境搭建
按照搭建开发环境来搭建起环境。
对已经有Android开发环境的,只需安装说明安装好Chocolatey、Python 2、NodeJS、yarn,并配置好相应的代理就可以了,期间需要多次重启命令行。
注意点:
- 需要以管理员运行命令行;
- 执行完命令后,最好重启下命令行,使配置的环境生效;
- 将管理员启动命令行加入右键快捷方式的方法:Win10 Shift 右键打开命令行窗口
运行第一个react native项目
项目初始化
环境完全配好后,重启命令行,切换到指定目录,然后执行如下命令,可以在指定目录下创建react native项目。
react-native init 项目名
目录结构
init命令执行完成后,项目即创建完成,我们看下目录结构。
按照目录,将对应的代码写在相应的地方。也可以再建一个js目录,在index.js里指定对应目录下的js文件即可,后面可以看到对应的示例。
开发方式
建议采用webstorm+as的方式来进行开发。二者都是基于idea的集成开发环境,快捷键、界面风格等都一致。我们用webstorm写js代码,用as写Android代码。
WebStorm下载
WebStorm激活
运行
将android目录作为project用Android Studio导入,需要修改gradle配置的可按照我们正常写Android的方式来修改,以下是我自己根据自己的Android开发环境在相应地方做的修改:
用AS导入后,会自动下载所需的包,下好之后我们可以直接run一下,看看能否将apk装到手机上。这里我的已经可以正常安装到手机上了。
但是app启动后,红屏报错,这是由于js的服务器没有起、本地也找不到js的bundle文件,导致的js加载失败造成的。
输入如下命令启动nodejs的服务器:
npm start
或
react-native start
来启动服务器,成功启动结果如下图:
然后再手机上点RELOAD,重新加载,仍然报错,说是连接不到服务:
长按手机上的menu键,弹窗:
选择最下面的Dev Settings,选择里面的“Debug server host & port for device”来输入服务器的地址,端口默认8081:
然后在手机上点RELOAD,重新加载,加载的同时,pc上命令行窗口会有js解析进度条展示进度,我这里运行报错:
好吧,说是缺少库,是初始化时候生成的node_modules里面的js库报错,改也不知道怎么改……
半个月前还能跑起来呢……
打开package.json查看配置,发现版本库都有所升级,半个月前是0.55的。
0.56版本配置:
0.55版本配置:
经公司多位同事安装体验后,发现windows下0.56.0版本确实跑不起来,估计是下载地址上缺少了部分内容。故决定切换到上个版本,(上个版本为0.55.4,已经比较稳定),果断将package.json替换为0.55版本的,然后执行命令:
npm install
重新下载0.55版本的js库。
下载完成后,将之前的apk删掉,Android项目clean,然后管理员命令行下执行命令:
react-native run-android
或直接用Androidstudio运行即可。
重新编译、安装apk,并运行服务器,即可成功跑起hello word:
调试
上面已经初步在真机上跑起应用了,如果仅仅是js代码有改动,不需要重新编译,直接长按menu,在菜单上选择reload即可重新加载js代码;如果图片资源有改动,需重启服务;如果原生代码有改动,需重新编译apk。
阅读Hello Word代码
hello word跑起来了,我们先来看一下代码结构和大概的内容。
Android代码
Android部分的代码很简单,只有一个MainApplication和一个MainActivity,跟我们纯原生的Android项目基本是一样的。
先看MainApplication:
看到没有,还是跟我们平常写Java版的application一个样,同样继承Android自带的Application类,只不过同时实现了Facebook自定义的ReactApplication接口。
再来看MainActivity:
仍然是在Android原有的Activity上封装了一层,从而使一个Activity可以作为容器,呈现js编写的内容。
Android部分的代码也就这么点,我们Android开发者看这部分代码应该没有什么压力。
Js代码
接下来看js部分的内容。
先用webstorm将整个RN项目导入:
前文已经说了,android目录对应android代码,ios目录对应ios代码,node_modules对应js库。我们在Android代码的MainApplication看到入口的js文件名为“index”,所以我们来看index.js文件:
这个index.js的主要作用是用来注册你所写的js模块的。
import语句用来导入组件,你在一个js文件中要使用哪个组件,就需要先把它导入进来,跟我们写Java代码,用到哪个类的对象就要先导包类似。
import {AppRegistry} from 'react-native';
导入react-native库里的注册组件AppRegistry,后面要使用它来注册内容;
import App from './App';
导入与index.js同一路径下的App.js里的所声明的组件,并将该组件命名为App。这里命名随意,后面代码就是通过你命名的名字来引用App.js里组件的内容的。
import {name as appName} from './app.json';
从app.json文件中导入name,并将name映射为appName,后面就可以用appName来带指name了。
app.json里的内容如下:
{
"name": "TestJRRR",
"displayName": "TestJRRR"
}
这里引用的name的值就是TestJRRR,可以看到,这里的名字与Android代码里MainActivity里getMainComponentName方法返回的字符串是一致的。
然后这个index.js代码正文其实只有一句话:
AppRegistry.registerComponent(appName, () => App);
看英文单词的意思,我们大概就能猜到是什么用途了,结合上面导入组件的语句,解释如下:
用注册组件来注册一个名字为TestJRRR的组件,这个组件指向App.js文件。
需要注意,这里的注册的是入口js的组件,也就是Android部分MainActivity里getMainComponentName方法返回的字符串对应的js组件。两者必须保持一致,不然原生部分的代码会找不到js部分的代码,也就无法执行js代码里的内容。
然后我们来看App.js部分的内容:
稍微有点前端基础的同学,大概都可以看明白这里的内容,具体就不再赘述了。
主要强调下,每一个js文件必须导出一个组件出来(要export出一个component),在使用的时候,引用的就是这个export出的component。
可以看到,这里的js代码其实跟我们写java代码有很大相似之处,这是按照最近几年定制的js语法标准ECMAScript来写的。现在主要遵循es6及以上版本规定的的写法标准了。学习可以看阮一峰es6,良心之作。
好了,入门介绍就先到这里了。后续会根据自己在工作中的使用,一点点来总结下使用react native的经验。
题外话
react natvie是一个框架,是在原生的Android和ios上面各自封装了一层代码,按照规定的写法来写的js,就可以被这个框架解释执行,主要是为了实现一端开发、多端复用、快速迭代的目的。js效果的执行,还是由原生的Android和ios层代码自己来完成的。意思即是:js要实现的效果,必须原生代码支持……当你需要实现一些官方框架不支持的效果的时候,你就必须按照框架的要求,来写对应原生的代码了……