React Native開發中遇到的坑(持續更新中...)
由於近期在進行React Native開發,遇到了不少坑,在此列出來。
1、使用Android的GenyMotion模擬器時,雙擊”R”出現”Could not connect to development server”紅屏的解決方法.
答:由於模擬器和伺服器不在同一個網路下,最有可能的是模擬器沒有連線WiFi,將模擬器連線WIFI即可,如下圖所示:
2、出現”Could not get BatchedBridge, make sure your bundle is packaged correctly”紅屏的解決方法.
答:(1)開啟終端,進入ReactNative 初始化的根目錄裡面。
(2) 執行下面這行命令
curl "http://localhost:8081/index.android.bundle?platform=android" -o "android/app/src/main/assets/index.android.bundle"
Tips:如果沒有 assets目錄的自己新建一個就可以了!
3、元件封裝後屬性的傳遞,例如元件A想要給元件B中的元件C傳遞一個屬性prop,如何實現?
答:第一種:層級傳遞屬性,一級一級傳遞,如下所示:
/**
* 這個例子是講"這是一個標題"這個屬性值從A通過B傳遞到C,以下方法可以實現
*/
class C extends Component{
...
render(){
return(
<View>this.props.title</View>
);
}
}
class B extends Component{
...
render(){
return(
<C title = {this.props.title}/>
)
}
}
class A extends Component{
...
render(){
return(
<B title = "這是一個標題"/>
)
}
}
第二種:使用上下文Context物件,有興趣的小夥伴可以自行了解以下,限於筆者水平,在此不做研究。
4、為什麼TextInput元件設定邊框在Android平臺顯示無效?
答:將TextInput外圍使用一層<View></View>
包裹,然後設定該View的邊框即可。
5、如何設定ListView中的item的選中狀態?
答:筆者由於為初學者,因此並不清楚必須改變dataSource,renderRow方法才會呼叫,上網查詢資料,方知如此,不多說,直接上程式碼:
class myComponent extends Component{
//...
constructor(props) {
super(props);
// 初始狀態
this.state = {
dataSource: new ListView.DataSource({rowHasChanged: (row1, row2)=>row1 !== row2}),
};
this.renderRow = this.renderRow.bind(this);
}
//...
renderRow(rowData, sectionID, rowID, highlightRow){
<TouchableOpacity style={styles.row} onPress={()=> {
if (this.lastRowID) {
tabs[this.lastRowID].hidden = true;
} else {
tabs[0].hidden = true;
}
tabs[rowID].hidden = false;
var newTabs = JSON.parse(JSON.stringify(tabs));
this.setState({
dataSource:
this.state.dataSource.cloneWithRows(newTabs)
});
this.lastRowID = rowID;
} }>
//...
}
}
如此便可通過更改dataSource觸發renderRow方法。
6、在ScrollView中切換輸入框<TextInouput>,為什麼需要點選兩次才能實現?
答:這是由於ScrollView也會相應點選事件,解決這個問題,只需要在ScrollView元件中新增兩個屬性:keyboardShouldPersistTaps={true}
和keyboardDismissMode={'on-drag'}
即可。
7、為什麼當介面消失時不會觸發componentWillUnMount()
方法?
答:這是由於拼寫錯誤,在IDE中,有時會提示componentWillUnMount()
這個方法,但這個方法拼寫是錯誤的,正確的應該是:componentWillUnmount()
,即mount的’m’是小寫!
8、怎麼在ES6語法中使用定時器以及如何取消定時器?
答:
下面是實現一個倒計時的效果:
程式碼如下:
const totalCount = 10;
class Register extends Component {
...
// 構造
constructor(props) {
super(props);
// 初始狀態
this.state = {
count: totalCount
};
}
componentWillUnMount() {
//介面解除安裝的時候停止定時器
this.timer && clearInterval(this.timer);
}
count() {
this.timer = setInterval(()=> {
this.setState({
count: this.state.count - 1
});
//這裡通過條件判斷是否停止計時器
if (this.state.count == 0) {
clearInterval(this.timer);
}
}, 1000);
}
render() {
return(
...
<TouchableOpacity onPress={this.count.bind(this)} disabled={!(this.state.count == totalCount || this.state.count == 0)}>
...
</TouchableOpacity>
)
}
}
9、出現“‘View’has no propType for native prop ‘RCTView.flexGrow’ of native type…”紅屏的解決辦法
答:這是因為同時在做兩個專案,當退出第一個專案時,npm仍然為第一個專案的,所以啟動第二個專案時就會報錯。如下圖:
。
此時,只需要開啟終端,將執行中的npm關閉,輸入命令react-native run-ios
或react-native run-android
重新啟動npm即可。
10、出現“underfined is not an object(evaluating ‘ViewProptypes.style’)”紅屏的解決版本
答:首先回答幾個問題:
1、是否使用了react-native-scrollable-tab-view
第三方庫?
2、react-native
的版本是否在0.44以下?
3、package-json
檔案中的react-native-scrollable-tab-view
的描述是否類似於"react-native-scrollable-tab-view": "^0.x.x"
?
如果是,進行如下操作:
1、將
package-json
中的"react-native-scrollable-tab-view": "^0.x.x"
修改為
"react-native-scrollable-tab-view": "0.x.x"
(去掉了版本號前的^
);
2、終端執行npm install
.
注:其他第三方庫若出現類似問題,解決方法同上。
接下來解釋一下,為什麼會出現這個問題:首先react-native
在0.44版本以後將View.PropTypes.style
屬性修改成了ViewPropTypes.style
,而類似於react-native-scrollable-tab-view
這樣的第三方庫為了適配react-native
新版本,也做了如此修改,然而由於我們的package-json
檔案中第三方庫版本描述類似於"^0.6.0"
,而這個^
號表示指定從左面起第一個非零位置的範圍。比如:"^0.6.0"
表示你下載的版本是區間為[0.6.0,0.7.0)
的最新版本。現在答案就很明顯了,你只需要將pack-json
中將第三方庫的版本指定為你最初新增的版本比如我的就是"react-native-scrollable-tab-view": "0.6.0"
,去掉了這個^
號,表示指定了這0.6.0
版本。關於版本號的解釋,參見https://segmentfault.com/q/1010000006124708/a-1020000006124855。