React Native之坑總結(持續更新)
Genymotion安裝與啟動
之前我用的是藍疊(BlueStack
)模擬器,跑RN程序也遇到了一些問題,都通過搜索引擎解決了,不過沒有記錄。
但是BlueStack
有一些問題,比如沒有菜單鍵,模擬器默認是橫向的,商業化太嚴重(本來是用來玩游戲的),界面太丑,等等......
於是我按照RN中文網的推薦下載了Genymotion模擬器,這一下,就是萬劫不復......
我是在官網下載的Genymotion,自帶VirtualBox 5.0.4
版本。下載安裝好后,我創建了一個virtual device
,一切看起來都很正常。然而,當我點擊Start
后,卻彈出錯誤提示,內容如下:
Unable to start the virtual device.
VirtualBox cannot start the virtual device.
To find out the cause of the problem, start the virtual device from VirtualBox.
我去百度以上信息,結果都是讓我打開VirtualBox,設置balabala雲雲。悲劇的是,我的VirtualBox根本打不開。去搜索也沒有什么有效信息。無奈我下了個4.3版本的VirtualBox重裝了下,這次輪到Genymotion打不開了。提示如下:
Unable to load VirtualBox engine.
Make sure that it is properly installed before starting Genymotion.
這個問題也是找了各種辦法都沒有用。
最后,我去官網下載了最新版的VirtualBox 5.18,結果好了。
內心真是崩潰。。花了近兩個小時終於搞定了。。
Genymotion模擬器啟動后,adb devices中顯示找不到設備
解決辦法:在Genymotion中Settings->ADB中選中Use custom Android SDK tools,選擇Android SDK路徑即可。
啟動應用顯示could not get batchedBridge
完整信息如下:
Could not get BatchedBridge, make sure your bundle is packaged correctly.
解決方法:點擊模擬器的選項鍵或點擊搖晃按鈕,會彈出一個菜單,選擇Dev Settings
,在彈出的頁面中點擊Debug server host & port for device
,填入本機IP + ":8081",如:10.138.253.3:8081
。
獲取本機IP的方法是在cmd中輸入ipconfig
。
啟動RN應用后,提示找不到packager
我自然是啟動了packager的,而且應用的Debug server host & port for device
中也填了本機IP:10.138.253.3:8081。
然后出現這個問題就很奇怪了,后來我在網上找到了這篇帖子,里面提到了localhost與127.0.0.1,於是我去查了這兩個東西。
發現127.0.0.1一定是本機IP,但是localhost有可能被解析成完全不同的IP地址,也就出現了上面找不到packager的情況。
於是我將應用的Debug地址改為了127.0.0.1:8081。果然成功了。
但是很奇怪的問題是為什么我使用BlueStack模擬器的時候填本機IP是沒問題的,到了Genymotion就不行了。這個問題暫且擱置。。。
又一波血與淚的教訓
其實大部分是自己寫代碼的時候沒有注意小細節,RN的IDE又沒有這么智能,所以出現了很多奇怪的錯誤。最后的錯誤報告可能和你寫錯的地方一點關系都沒有,很蛋疼。。。
-
類名要大寫
-
有一句
let Component = route.component;
中的第一個Component的首字母要大寫。 -
antd-mobile的tabs組件有個bug:如果一個子頁面中有輸入框,輸入任意一個字符后,tabs會自動向左滑動(最左邊的子頁面沒有這個問題)。於是我把滑動的tabs換成了react-native-scrollable-tab
-
如果不用ant design的form代碼,就無法輸入字符。下面是一個示例:
import React, { Component } from 'react'; import { Text, View } from 'react-native'; import Button from 'antd-mobile/lib/button'; import WhiteSpace from 'antd-mobile/lib/white-space'; import List from 'antd-mobile/lib/list'; import InputItem from 'antd-mobile/lib/input-item'; import WingBlank from 'antd-mobile/lib/wing-blank'; import { createForm } from 'rc-form'; class Register extends Component { render() { const {getFieldProps} = this.props.form; return ( <View style={{flex: 1}}> <List> <InputItem {...getFieldProps('registerusername', { initialValue: '' })} clear placeholder="6-12位字母或數字" >用戶名</InputItem> <InputItem {...getFieldProps('registernickname', { initialValue: '' })} clear placeholder="6-14位字符,一個漢字為兩個字符" >昵稱</InputItem> <InputItem {...getFieldProps('registerpassword', { initialValue: '' })} type="password" clear placeholder="******" >密碼</InputItem> </List> <WhiteSpace size="lg"/> <WingBlank> <Button type="default" color="'#000000">注冊</Button> </WingBlank> <WhiteSpace size="lg"/> </View> ); } } Register = createForm()(Register); module.exports = Register;
不過這里的InputItem輸入之后如何提交還需要研究。。
持續更新中……
Component類的一些方法
- 在組件的生命周期中,
getInitialState()
只執行一次,它負責對組件的state進行初始化。 - 這里的
componentDidMount
是一個在React組件渲染以后將被React調用的方法。
一個坑
const { dispatch, room } = props;
這里的props更新之后,就不能再用room來訪問更新的內容了,因為room是之前就確定的一個常量。