1. props和state比較
1.1 props
是在父組件中指定的令杈,一經(jīng)指定,那么在被指定的組件的生命周期中是不再改變的,一般是組件在創(chuàng)建的時(shí)候叹坦,使用props
去做定制。
1.2 對(duì)于需要改變的數(shù)據(jù)卑雁,可以使用state
募书,ES6中在constructor
中初始化state
(早期ES5的例子中會(huì)使用getInitialState
做初始化),然后在修改的地方調(diào)用setState
即可测蹲。
2.ReactNative component生命周期:
component生命周期
3. ReactNative 使用flex
做實(shí)現(xiàn)彈性寬高
在組件樣式中使用flex
可以使其在可利用的空間中動(dòng)態(tài)地?cái)U(kuò)張或收縮莹捡。一般而言我們會(huì)使用flex:1
來(lái)指定某個(gè)組件擴(kuò)張以撐滿(mǎn)所有剩余的空間。如果有多個(gè)并列的子組件使用了flex:1
扣甲,則這些子組件會(huì)平分父容器中剩余的空間篮赢。如果這些并列的子組件的flex
值不一樣,則誰(shuí)的值更大文捶,誰(shuí)占據(jù)剩余空間的比例就更大(即占據(jù)剩余空間的比等于并列組件間flex
值的比)荷逞。
注意:組件能夠撐滿(mǎn)剩余空間的前提是其父容器的尺寸不為零。如果父容器既沒(méi)有固定的
width
和height
粹排,也沒(méi)有設(shè)定flex
种远,則父容器的尺寸為零。其子組件如果使用了flex
顽耳,也是無(wú)法顯示的坠敷。
4.ReactNative 使用flexBox
指定組件的布局
4.1一般來(lái)說(shuō)使用flexDriection
(定義布局排列方向,默認(rèn)為縱向排列column
)射富、justifyContent
(定義主軸的排列方式:flex-start膝迎、center、flex-end胰耗、space-around
以及space-between
)和alignItem
(定義與主軸垂直的次軸排列方式:flex-start限次、center、flex-end
以及stretch
)即可完成基本布局柴灯,更多布局字段見(jiàn)布局樣式屬性
5.ReactNative中使用到的列表控件
5.1常用的列表控件FlatList
卖漫,FlatList
組件必須的兩個(gè)屬性是data
和renderItem
。data
是列表的數(shù)據(jù)源赠群,而renderItem
則從數(shù)據(jù)源中逐個(gè)解析數(shù)據(jù)羊始,然后返回一個(gè)設(shè)定好格式的組件來(lái)渲染。FlatList
相對(duì)于ListView
的優(yōu)點(diǎn)就是會(huì)優(yōu)先渲染屏幕上可見(jiàn)的元素查描,而不是一次性渲染全部元素突委。
5.2對(duì)于需要做分組的列表控件柏卤,可以使用SectionList
,那么相對(duì)于FlatList
匀油,SectionList
的data
就會(huì)更加復(fù)雜了缘缚,同時(shí)還多了一個(gè)屬性renderSection
用于渲染區(qū)的頭部試圖。
6.Native項(xiàng)目中集成RN頁(yè)面(使用cocoapods集成)
6.1新建一個(gè)native+reactnative的文件夾(以Native+ReactNativeDemoRoot
為例)钧唐,在該文件夾中建子文件夾/ios
忙灼,再把native工程拷貝到ios
文件夾中。
6.2在Native+ReactNativeDemoRoot
中創(chuàng)建package.json
文件(也可以使用npm init
創(chuàng)建钝侠,但是內(nèi)容需要一步一步輸入该园,而且key值可能會(huì)忘記,有模板的話(huà)直接創(chuàng)建最方便了帅韧,package.json中的key值可以使用npm help json
去查詢(xún))里初,注意package.json
中的react-native
的版本號(hào),這個(gè)會(huì)影響n(yōu)ative工程中podfile需要引入的文件忽舟。
"dependencies": {
"react": "16.0.0-alpha.6",
"react-native": "0.44.3"
}
6.3在根目錄(即包含有package.json
文件的目錄)中執(zhí)行命令npm install
來(lái)安裝React和React Native模塊双妨,這些模塊會(huì)被安裝到根目錄下的node_modules/目錄中(所有通過(guò)npm install
命令安裝的模塊都會(huì)放在這個(gè)目錄中。這個(gè)目錄我們?cè)瓌t上不復(fù)制叮阅、不移動(dòng)刁品、不修改、不上傳浩姥,隨用隨裝)挑随。
6.4進(jìn)入到native工程中,執(zhí)行命令pod init
初始化Podfile
文件勒叠,可以拷貝ReactNative中文網(wǎng)/集成到現(xiàn)有原生應(yīng)用中的Podfile模板兜挨,Podfile文件完成后使用命令pod install
安裝React Native的pod包。
# target的名字一般與你的項(xiàng)目名字相同
target 'NumberTileGame' do
# 'node_modules'目錄一般位于根目錄中
# 但是如果你的結(jié)構(gòu)不同眯分,那你就要根據(jù)實(shí)際路徑修改下面的`:path`
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge', # 如果RN版本 >= 0.45則加入此行
'DevSupport', # 如果RN版本 >= 0.43拌汇,則需要加入此行才能開(kāi)啟開(kāi)發(fā)者菜單
'RCTText',
'RCTNetwork',
'RCTWebSocket', # 這個(gè)模塊是用于調(diào)試功能的
# 在這里繼續(xù)添加你所需要的RN模塊
]
# 如果你的RN版本 >= 0.42.0,則加入下面這行
pod "yoga", :path => "../node_modules/react-native/ReactCommon/yoga"
# 如果RN版本 >= 0.45則加入下面三個(gè)第三方編譯依賴(lài)
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
end
注意:
1.需要根據(jù)項(xiàng)目路徑修改path
2.需要根據(jù)package.json
中的react-native
版本對(duì)引入的文件做修改
6.5接下來(lái)就開(kāi)始寫(xiě)JS的代碼了弊决,在根目錄中創(chuàng)建index.js文件(注意在0.49版本之前是index.ios.js文件)噪舀,在文件中添加ReactNative的代碼,ReactNative中使用到的模塊都需要在Native的Podfile中對(duì)相應(yīng)的引入哦飘诗!
index.js是React Native應(yīng)用在iOS上的入口文件傅联。而且它是不可或缺的!它可以是個(gè)很簡(jiǎn)單的文件疚察,簡(jiǎn)單到可以只包含一行require/import導(dǎo)入語(yǔ)句。本教程中為了簡(jiǎn)單示范仇奶,把全部的代碼都寫(xiě)到了index.js里(當(dāng)然實(shí)際開(kāi)發(fā)中我們并不推薦這樣做)貌嫡。注意index.js中函數(shù)
registerComponent
注冊(cè)的模塊比驻,在Native工程中會(huì)用到
6.6在Native項(xiàng)目中添加一個(gè)事件處理,跳轉(zhuǎn)到ReactNative頁(yè)面岛抄,這里會(huì)使用到一個(gè)類(lèi)RCTRootView
别惦,debug時(shí)使用下面的代碼加載ReactNative的界面,release時(shí)URL需要改變夫椭,具體后續(xù)補(bǔ)充掸掸。。蹭秋。
NSURL *reactNativeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];
//moduleName就是在index.js中使用registerComponent注冊(cè)的模塊
//initialProperties用于把native界面的數(shù)據(jù)傳輸給ReactNative界面扰付,ReactNative界面使用this.props即可獲取
//launchOptions有待補(bǔ)充
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:reactNativeLocation
moduleName:@"ReactNativePage"
initialProperties:nil
launchOptions:nil];
UIViewController *rootViewController = [[UIViewController alloc] init];
rootViewController.view = rootView;
[self.navigationController pushViewController:rootViewController animated:YES];
6.7在根目錄中執(zhí)行命令npm start
啟動(dòng)開(kāi)發(fā)服務(wù)器(即Packager,它負(fù)責(zé)實(shí)時(shí)監(jiān)測(cè)js文件的變動(dòng)并實(shí)時(shí)打包仁讨,輸出給客戶(hù)端運(yùn)行)羽莺,最后編譯運(yùn)行Native項(xiàng)目即可。
Packager只是在開(kāi)發(fā)時(shí)需要洞豁,便于你快速開(kāi)發(fā)迭代盐固。在正式發(fā)布應(yīng)用時(shí),所有的js文件都會(huì)被打包為一整個(gè)jsbundle文件離線(xiàn)運(yùn)行丈挟,此時(shí)客戶(hù)端不再需要Packager服務(wù)刁卜。