前言
這段時間晶框,項目中某些模塊嘗試了下react-native
也遇到過一些坑點拐纱,這里做個記錄挺益,希望如我一樣的前端新人不會再被這些問題折磨到涕蚤。
- 環(huán)境搭建
在學(xué)習資料以及社區(qū)方面RN的資料還是相比比較豐富的宪卿,只需要按著官方的文檔來操作一般不會有啥問題。
官方文檔地址
- 初始化項目
環(huán)境搭建后之后万栅,就可以創(chuàng)建我們的RN項目了佑钾,
react-native init 項目名稱
等項目初始化完成之后,我一般是找到項目目錄里面iOS
目錄直接使用Xcode
來啟動項目 也可以使用
react-native run-ios
或者react-native run-Android
來啟動烦粒。
當服務(wù)器了鏈接完成程序也就啟動了
*項目結(jié)構(gòu)以及加載過程
剛開始的時候我其實有點疑惑的休溶,就是我們運行
Xcode
時是怎么和這些js
文件鏈接到一起的。
在我們打開的Xcode``appDelegate
的文件中可以看到
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"RNDemo"
initialProperties:nil
launchOptions:launchOptions];
這里指定了加載的包名以及根文件index
根據(jù)moduleName 來初始化一個View
最后渲染到主窗口上來顯示扰她。也就是說操作所有的js
代碼的布局樣式 最后都是經(jīng)由RCTRootView
來顯示的兽掰。
現(xiàn)在我們打開rn
的項目
可以看到在
rn
的工程中有一個index
的js文件在這個文件中有兩個重要的方法。
// 注冊程序入口組件, 程序啟動時根據(jù)這個注冊的組件名稱去加載
// // 第一個參數(shù) 'RNDemo' 要跟載xocde 工程里注冊的一致,
// 第二個參數(shù) 返回當前創(chuàng)建的模塊名稱徒役、孽尽、class RNDemo extends Component
AppRegistry.registerComponent('RNDemo', ()=>RNDemo);
另一個就是render
方法。所有的UI展示需要通過這個方法來渲染
當組件要顯示時忧勿,系統(tǒng)也會自動調(diào)用這個方法
render(){
return(
)
}
現(xiàn)在我們可以在這個方法里返回一個UI組件看看會有什么效果杉女。
render(){
return(
<View></View>
)
}
當然在運行之前我們需要導(dǎo)入一些相應(yīng)的組件
import React, {Component} from 'react'
// 2.導(dǎo)入常用組件,注冊組件,樣式組件,View組件,Text組件
import
{
AppRegistry,
StyleSheet,
Text,
View
}
這里忍不住吐槽一句,在RN里貌似沒有我們
iOS
的主頭文件一說鸳吸,用到一個控件就要導(dǎo)入一次還是蠻麻煩的
現(xiàn)在應(yīng)該可以啟動起來了熏挎。。晌砾。坎拐。。养匈。
但是應(yīng)該是一片空白哼勇,因為我們沒有設(shè)置樣式。
return(
<View style={{flex:1, backgroundColor: 'red'}}></View>
)
這里我將頁面設(shè)置為沾滿全屏呕乎,背景顏色為紅色猴蹂。
樣式的設(shè)置也可以單獨抽取到StyleSheet
中去設(shè)置,這樣更容易閱讀楣嘁。
const styles = StyleSheet.create({
mainStyles:{
flex:1,
backgroundColor: 'red'
},
這里遇到一個坑 應(yīng)該是只有想我這樣的新手才會碰到這樣的傻瓜問題磅轻。
當時我根據(jù)文檔在render
方法中返回一個View
組件
但是運行的時候一直報錯珍逸,用我稀有的單詞儲備量來推算說的意思是字符串必須在Text
組件中。 但是我明明返回的只是一個單純的View
組件啊聋溜。
運行報錯
對照了下代碼也沒發(fā)現(xiàn)有啥不對谆膳。
class RNDemo extends Component {
// 當一個組件要顯示的時候,就會自動調(diào)用render,渲染組件
render(){
return(
<View> </View>
)
}
}
就這兩句代碼 也不可能寫錯啊。真是百思不得七姐啊撮躁。后來觀察和實例代碼的差別發(fā)現(xiàn)貌似只有
<View> </View>
這里的中間有一個空格的差別啊漱病,遂刪掉多余的空格,竟然真的人運行起來了把曼。杨帽。真的是郁悶好久。 后來發(fā)現(xiàn)嗤军,關(guān)于這些UI組件注盈。
可以這么寫
<View style={styles.mainStyles}></View>
也可以
<View style={styles.mainStyles}>
</View>
但是就是不能 <View> </View>
你說氣人不氣人。叙赚。
- 生命周期
我們都知道iOS
的每個頁面都有生命周期老客,而rn
也不例外。
在組件初始化的時候調(diào)用震叮,類屬于我們OC的[[alloc]init]
constructor(props){
super(props)
}
// 組件將要被加載到視圖之前調(diào)用
componentWillMount() {
}
// 當一個組件要顯示的時候,就會自動調(diào)用render,渲染組件
render(){
return(
<View> </View>
)
}
//在調(diào)用了render方法胧砰,組件加載成功并被成功渲染出來之后,所要執(zhí)行的后續(xù)操作苇瓣,一般都會在這個函數(shù)中進行尉间,比如經(jīng)常要面對的網(wǎng)絡(luò)請求等加載數(shù)據(jù)操作
// 可以看做是oc中的ViewDidLoad
componentDidMount() {
}
// 當程序即將要卸載時會調(diào)用,類似于OC的delloc方法
componentWillUnmount() {
}
(這些只是沒有數(shù)據(jù)更改時的調(diào)用順序如果涉及到,State
或者props
發(fā)生改變時击罪,則會觸發(fā)其他的函數(shù))
// 組件被更新之前會自動觸發(fā)此函數(shù) 哲嘲,根據(jù)這個函數(shù)中返回值,來決定是否刷新頁面外邓。
// 如果返回false 則不會重新調(diào)用render函數(shù)撤蚊,重新渲染頁面
shouldComponentUpdate() {
return true
}
// 組件即將刷新的時候被觸發(fā)古掏,如果shouldComponentUpdate返回的是false 則不會回調(diào)此函數(shù)
componentWillUpdate() {
}
// 組件開始刷新
render() {
console.log('app輸入')
return (
<div>
{this.state.name}
<Test />
<button onClick={this.renderText.bind(this)}>touch me</button>
</div>
);
}
// 組件刷新完成調(diào)用
componentDidUpdate() {
}
// 最后說下這個
// 當一個組件從父控件中接收到參數(shù)损话,如果這個子組件第一次存在于父控件中,不會執(zhí)行這個函數(shù)槽唾。
// 只有當這個子組件再次存在于父組件上時才會觸發(fā)
componentWillReceiveProps() {
}
另外說一個要點丧枪,創(chuàng)建
react-native
組件時,組件名稱首字母必須是大寫的庞萍。被坑過拧烦。。钝计。恋博。