React-Native 隨筆

學(xué)習(xí)基礎(chǔ):
  1. js的基礎(chǔ)知識(shí),
  2. rect.js基礎(chǔ)
  3. JSX語(yǔ)法基礎(chǔ)
  4. FlexBox布局

安裝
  1. 安裝node.js
    下載地址: https://nodejs.org/en/
  2. 運(yùn)行 npm install -g react-native-cli安裝react-native-cli。
  3. 運(yùn)行react-native init [your project name],這樣就會(huì)自動(dòng)生成一個(gè)基本的ReactNative項(xiàng)目。
  4. cd到項(xiàng)目中執(zhí)行 react-native start,會(huì)部署本地的package服務(wù)。
  5. 重新啟動(dòng)一個(gè)命令行, cd到項(xiàng)目中, 執(zhí)行react-native run-android

注意:android項(xiàng)目可能會(huì)沒有缺少local.properties文件,項(xiàng)目運(yùn)行時(shí)會(huì)報(bào)錯(cuò),可以從本地別的項(xiàng)目里拷貝一份放進(jìn)去。


兼容性
  1. JS文件中平臺(tái)區(qū)分
var { Platform} = React;
if(Platform.OS === 'ios'){
   //ios相關(guān)操作
}else{
   //android相關(guān)操作
}

Platform不止可以區(qū)分平臺(tái),還可以區(qū)分Android版本號(hào)等。

  1. 文件后綴區(qū)分不同平臺(tái)
    你有my-icon.ios.png和my-icon.android.png,Packager就會(huì)根據(jù)平臺(tái)而選擇不同的文件, 同理js文件也會(huì)根據(jù)后綴的不同.ios.js和.android.js,自動(dòng)找到匹配相應(yīng)的文件。
  2. 圖片適配不同屏幕
    可以使用@2x,@3x這樣的文件名后綴,來(lái)為不同的屏幕精度提供圖片。
├── button.js
 └── img 
       ├── check@2x.png
       └── check@3x.png
<Image source={require('./img/check.png')} />

Android打包
  1. 確保Android項(xiàng)目中有assets目錄
  2. 執(zhí)行:
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/

成功后會(huì)在assets目錄中生成index.android.bundle和index.android.bundle.meta兩個(gè)文件表示已經(jīng)打包成功了。
放在js目錄下的圖片會(huì)自動(dòng)打包到android項(xiàng)目的drawable目錄下。比如我在
*\MyReactDemo\js\login\img
目錄下為了適配不同屏幕有三張圖片

login-background.png
login-background@2x.png
login-background@3x.png

打包后會(huì)自動(dòng)修改名稱并添加到相應(yīng)的drawable目錄下

Paste_Image.png

打包的時(shí)候只會(huì)把js里用到的圖片導(dǎo)入到drawable,其他相應(yīng)的圖片并沒有導(dǎo)進(jìn)去, 這里應(yīng)該是做了檢查,防止導(dǎo)入不用圖片資源。


增量熱更新

由于官方?jīng)]有提供熱更新方案, 可以使用微軟推出的Codepush,但是服務(wù)器在國(guó)外,可能會(huì)有些問(wèn)題,沒有增量更新。
想實(shí)現(xiàn)增量熱更新:
參考http://www.itdecent.cn/p/2cb3eb9604ca
注意文章有些地方需要注意:

  1. 更換index.android.bundle目錄應(yīng)該是重寫Application中的ReactNativeHost的getJsBundleFile()方法。


    Paste_Image.png
  2. bundle位置變化后圖片地址訪問(wèn)不到。
    當(dāng)下載后的bundle文件放入SDCard,會(huì)出現(xiàn)圖片不能加載的問(wèn),這是因?yàn)閎undel文件存在不同位置,路徑解析方式會(huì)有不同。
    找到Image.ios.js或者Image.android.js文件,查看render方法。


    發(fā)現(xiàn)通過(guò)resolveAssetSource來(lái)做地址解析,打開resolveAssetSource.js

    發(fā)現(xiàn)通過(guò)resolver.defaultAsset返回資源地址, 在AssetSourceResolver.js中找到defaultAsset()函數(shù)。

    這里會(huì)根據(jù)bundle文件加載方式不同,圖片路徑會(huì)通過(guò)不同的方式加載。如果路徑而不是從assets里面加載的話,會(huì)從文件bundle文件所在路徑下加載圖片。

    通過(guò)注釋我們知道只要把圖片資源和bundle文件放到同一個(gè)目錄下面就可以訪問(wèn)到, 但是我實(shí)際操作后發(fā)現(xiàn)有些特殊情況需要注意。
    比如開發(fā)的項(xiàng)目中:
    訪問(wèn)圖片的js文件路徑: /js/login/LoginPage.js
    圖片的訪問(wèn)方式: <Image style={styles.container} source={require("./img/icon_search.png")}>
    圖片放到同級(jí)目錄img下: /js/login/img/icon_search.png
    正確的文件路徑應(yīng)該是在sdcard中在bundle包同級(jí)目錄下的/drawable-mdpi/js_login_img_icon_search.png

    這是因?yàn)樵趃etAssetPathInDrawableFolder方法中會(huì)通過(guò)屏幕deviceScale的屬性找到對(duì)應(yīng)的drawable目錄,然后再做一個(gè)拼接。最后拼接出來(lái)的圖片地址:

  3. 這種方式如果用戶清理緩存數(shù)據(jù)后js文件又回到了原始狀態(tài),這個(gè)可以可以通過(guò)每次啟動(dòng)檢查更新來(lái)避免。


常見問(wèn)題

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

Q:可以使用現(xiàn)有的js庫(kù)嗎?
A:由于RN理論上更接近nodejs的運(yùn)行環(huán)境,所以對(duì)nodejs的庫(kù)兼容更好一些。瀏覽器端的js庫(kù),涉及到DOM、BOM、CSS等功能的模塊無(wú)法使用,因?yàn)镽N的環(huán)境中沒有這些東西。

Q: 可以使用現(xiàn)有的objc/swift/java庫(kù)嗎
A: 可以但是要做更改。

Q:可以熱更新嗎?蘋果允許嗎?
A:官方?jīng)]有提供熱更新方案, 蘋果目前的政策明確允許基于javascriptCore的熱更新,可以使用微軟推出的Codepush來(lái)更新文件。

報(bào)錯(cuò)

** 1.invariant violation:expected a component class,got[object object]**
創(chuàng)建自定義組件首字母要大寫,否則會(huì)報(bào)錯(cuò).**

** 2. Module 0 is not a registered callable module.**
將gradle升級(jí)成最新版本(cd Android) 進(jìn)入android目錄執(zhí)行:sudo ./gradlew clean) 或者通過(guò)android studio工具升級(jí).

** 3. android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?**
該錯(cuò)誤屬于安卓Native的錯(cuò)誤,如果引用的Activity不存在或者已經(jīng)銷毀,再次引用就會(huì)報(bào)該錯(cuò)誤,如果是React Native調(diào)用原生控件的話,創(chuàng)建控件需要引用:getCurrentActivity()

** 4.android.app.Application cannot be cast to com.facebook.React.ReactApplication.**
需要將創(chuàng)建的MainApplication在AndroidManifest.xml配置好.

** 5. Element type is invalid: expected a string (for built-in components) or a class/function but got: object**
發(fā)生原生一般是你引用了無(wú)效的組件,如果組件確實(shí)正確,看下引用的組件是否正常導(dǎo)出:(export defalut)

** 6. react native undefined is not an object (evaluating this....**
發(fā)生該錯(cuò)誤的一般是忘記bind(this),只要回調(diào)函數(shù)中需要用到this的,一般都需要bind.

** 7. react native - expected a component class, got [object Object]**
該錯(cuò)誤可能是你引用了小寫的組件,組件首字母一定要大寫,比如<login/>應(yīng)該寫成<Login/>**

** 8. Invariant Violation:Application XXXX has not been registered.**
請(qǐng)確保index.*.js中的
AppRegistry.registerComponent('項(xiàng)目名',() => ...);
MainActivity.java中的
@Overrideprotected String getMainComponentName() { return "項(xiàng)目名";}
都保持一致。

** 9. 遇到403 Forbidden錯(cuò)誤.**
首先運(yùn)行netstat -ano 檢查默認(rèn)端口8081被占用的情況,如果被占用可以關(guān)掉占用的程序或者修改端口。
修改端口方法:

  1. 找到\node_modules\react-native\local-cli\server\server.js修改default端口號(hào)

    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調(diào)試會(huì)有問(wèn)題, 這是因?yàn)檎{(diào)試走的端口并沒有被修改,抱歉沒有找到修改的地方,哪位大神找到了麻煩告訴我一聲,我的解決方法是在調(diào)試的時(shí)候手動(dòng)修改debugerWorker.js加載bundle地址的端口號(hào)。



學(xué)習(xí)資料

Flex布局學(xué)習(xí):
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
資源集合:
https://github.com/reactnativecn/react-native-guide#%E7%BB%84%E4%BB%B6

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容