React-Native 随笔

学习基础:
  1. js的基础知识,
  2. rect.js基础
  3. JSX语法基础
  4. FlexBox布局

安装
  1. 安装node.js
    下载地址: https://nodejs.org/en/
  2. 运行 npm install -g react-native-cli安装react-native-cli。
  3. 运行react-native init [your project name],这样就会自动生成一个基本的ReactNative项目。
  4. cd到项目中执行 react-native start,会部署本地的package服务。
  5. 重新启动一个命令行, cd到项目中, 执行react-native run-android

注意:android项目可能会没有缺少local.properties文件,项目运行时会报错,可以从本地别的项目里拷贝一份放进去。


兼容性
  1. JS文件中平台区分
var { Platform} = React;
if(Platform.OS === 'ios'){
   //ios相关操作
}else{
   //android相关操作
}

Platform不止可以区分平台,还可以区分Android版本号等。

  1. 文件后缀区分不同平台
    你有my-icon.ios.png和my-icon.android.png,Packager就会根据平台而选择不同的文件, 同理js文件也会根据后缀的不同.ios.js和.android.js,自动找到匹配相应的文件。
  2. 图片适配不同屏幕
    可以使用@2x,@3x这样的文件名后缀,来为不同的屏幕精度提供图片。
├── button.js
 └── img 
       ├── [email protected]
       └── [email protected]


Android打包
  1. 确保Android项目中有assets目录
  2. 执行:
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/

成功后会在assets目录中生成index.android.bundle和index.android.bundle.meta两个文件表示已经打包成功了。
放在js目录下的图片会自动打包到android项目的drawable目录下。比如我在
*\MyReactDemo\js\login\img
目录下为了适配不同屏幕有三张图片

login-background.png
[email protected]
[email protected]

打包后会自动修改名称并添加到相应的drawable目录下

React-Native 随笔_第1张图片
Paste_Image.png

打包的时候只会把js里用到的图片导入到drawable,其他相应的图片并没有导进去, 这里应该是做了检查,防止导入不用图片资源。


增量热更新

由于官方没有提供热更新方案, 可以使用微软推出的Codepush,但是服务器在国外,可能会有些问题,没有增量更新。
想实现增量热更新:
参考http://www.jianshu.com/p/2cb3eb9604ca
注意文章有些地方需要注意:

  1. 更换index.android.bundle目录应该是重写Application中的ReactNativeHost的getJsBundleFile()方法。


    React-Native 随笔_第2张图片
    Paste_Image.png
  2. bundle位置变化后图片地址访问不到。
    当下载后的bundle文件放入SDCard,会出现图片不能加载的问,这是因为bundel文件存在不同位置,路径解析方式会有不同。
    找到Image.ios.js或者Image.android.js文件,查看render方法。


    发现通过resolveAssetSource来做地址解析,打开resolveAssetSource.js
    React-Native 随笔_第3张图片

    发现通过resolver.defaultAsset返回资源地址, 在AssetSourceResolver.js中找到defaultAsset()函数。
    React-Native 随笔_第4张图片

    这里会根据bundle文件加载方式不同,图片路径会通过不同的方式加载。如果路径而不是从assets里面加载的话,会从文件bundle文件所在路径下加载图片。
    React-Native 随笔_第5张图片

    通过注释我们知道只要把图片资源和bundle文件放到同一个目录下面就可以访问到, 但是我实际操作后发现有些特殊情况需要注意。
    比如开发的项目中:
    访问图片的js文件路径: /js/login/LoginPage.js
    图片的访问方式:
    图片放到同级目录img下: /js/login/img/icon_search.png
    正确的文件路径应该是在sdcard中在bundle包同级目录下的/drawable-mdpi/js_login_img_icon_search.png
    React-Native 随笔_第6张图片

    这是因为在getAssetPathInDrawableFolder方法中会通过屏幕deviceScale的属性找到对应的drawable目录,然后再做一个拼接。最后拼接出来的图片地址:

  3. 这种方式如果用户清理缓存数据后js文件又回到了原始状态,这个可以可以通过每次启动检查更新来避免。


常见问题

Q:RN所支持的最低iOS和Android版本?
A:Android >= 4.1 (API 16) iOS >= 7.0

Q:可以使用现有的js库吗?
A:由于RN理论上更接近nodejs的运行环境,所以对nodejs的库兼容更好一些。浏览器端的js库,涉及到DOM、BOM、CSS等功能的模块无法使用,因为RN的环境中没有这些东西。

Q: 可以使用现有的objc/swift/java库吗
A: 可以但是要做更改。

Q:可以热更新吗?苹果允许吗?
A:官方没有提供热更新方案, 苹果目前的政策明确允许基于javascriptCore的热更新,可以使用微软推出的Codepush来更新文件。

报错

** 1.invariant violation:expected a component class,got[object object]**
创建自定义组件首字母要大写,否则会报错.**

** 2. Module 0 is not a registered callable module.**
将gradle升级成最新版本(cd Android) 进入android目录执行:sudo ./gradlew clean) 或者通过android studio工具升级.

** 3. android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?**
该错误属于安卓Native的错误,如果引用的Activity不存在或者已经销毁,再次引用就会报该错误,如果是React Native调用原生控件的话,创建控件需要引用:getCurrentActivity()

** 4.android.app.Application cannot be cast to com.facebook.React.ReactApplication.**
需要将创建的MainApplication在AndroidManifest.xml配置好.

** 5. Element type is invalid: expected a string (for built-in components) or a class/function but got: object**
发生原生一般是你引用了无效的组件,如果组件确实正确,看下引用的组件是否正常导出:(export defalut)

** 6. react native undefined is not an object (evaluating this....**
发生该错误的一般是忘记bind(this),只要回调函数中需要用到this的,一般都需要bind.

** 7. react native - expected a component class, got [object Object]**
该错误可能是你引用了小写的组件,组件首字母一定要大写,比如应该写成**

** 8. Invariant Violation:Application XXXX has not been registered.**
请确保index.*.js中的
AppRegistry.registerComponent('项目名',() => ...);
MainActivity.java中的
@Overrideprotected String getMainComponentName() { return "项目名";}
都保持一致。

** 9. 遇到403 Forbidden错误.**
首先运行netstat -ano 检查默认端口8081被占用的情况,如果被占用可以关掉占用的程序或者修改端口。
修改端口方法:

  1. 找到\node_modules\react-native\local-cli\server\server.js修改default端口号

    React-Native 随笔_第7张图片
    Paste_Image.png

  2. 在MainActivity中添加

@Override   
protected void onCreate(Bundle savedInstanceState) {      
      super.onCreate(savedInstanceState);       
      mSp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
      mSp.edit().putString("debug_http_host","localhost:7777").commit();      
}

端口修改后用chrome调试会有问题, 这是因为调试走的端口并没有被修改,抱歉没有找到修改的地方,哪位大神找到了麻烦告诉我一声,我的解决方法是在调试的时候手动修改debugerWorker.js加载bundle地址的端口号。


React-Native 随笔_第8张图片

学习资料

Flex布局学习:
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
资源集合:
https://github.com/reactnativecn/react-native-guide#%E7%BB%84%E4%BB%B6

你可能感兴趣的:(React-Native 随笔)