react-native(以下簡稱RN)的文檔比較詳細(xì)叠赐,但是有些知識點很零碎實際做起項目會有些磕磕絆絆践啄,今天從做一個Demo(地址)的思路走下去汇跨,講解一下RN(based on V0.3)
環(huán)境配置和創(chuàng)建工程不是重點晦墙,直接看這里就好挪拟。
IDE可以使用WebStorm或者Visual Studio Code择葡,我用的后者紧武,免費而且插件比較多,如果你也用這個IDE的話推薦下載安裝React Native Tools這個插件敏储,有代碼提示阻星,而且可以debug RN。
環(huán)境都搞定了就可以開始了虹曙,打開index.ios.js(index.android.js)這是程序的入口迫横,工程會在init時自動幫你在這里創(chuàng)建一個繼承自component的“類”(多說一句,js本身沒有類的概念酝碳,所以用js實現(xiàn)OO思想可以有許多種寫法矾踱,class關(guān)鍵字是從ES6開始引入,詳細(xì)看這里)疏哗,程序會從這里開始呛讲。
接下來我們要找到合適的地方寫我們的業(yè)務(wù)邏輯,關(guān)于component類的生命周期回調(diào)返奉,有這篇文檔
簡單總結(jié)幾個關(guān)鍵的回調(diào)函數(shù):
- constructor(): 構(gòu)造函數(shù)
- render(): 把你需要顯示的View返回給RN渲染
- componentDidMount(): component加載完畢后調(diào)用贝搁,render方法之后
所以我們實現(xiàn)render函數(shù),返回一個導(dǎo)航視圖芽偏,再新建一個AlbumListView雷逆,作為導(dǎo)航視圖的根視圖。
(RN的語法叫JSX污尉,可以在JS里面寫類似XML的DOM節(jié)點膀哲,你可以這樣理解:<類名 屬性1...屬性2...> subview </類名>)
來到AlbumListView.js里,定義AlbumListView類被碗,之后重寫render函數(shù)某宪,這個頁面的結(jié)構(gòu)比較簡單,是一個ListView加一個Button(非默認(rèn)提供的控件锐朴,自己寫的話就是對一個View進行簡單封裝兴喂,包括監(jiān)聽手勢、加文字控件之類的,這里是用的apsl-react-native-button)衣迷。
(設(shè)置refreshControl屬性是讓ListView集成下拉刷新控件畏鼓,style屬性會在后面介紹)
每一個Component里有一個state對象比較特殊,盡管你可以把它當(dāng)作普通對象對待蘑险,但是在調(diào)用setState之后滴肿,UI會被標(biāo)記為需要重新render一次(不是立即刷新,并且如果當(dāng)你在調(diào)setState之后又馬上調(diào)this.state(get方法)是不會觸發(fā)刷新的)佃迄,所以最好用來存放一些關(guān)于刷新UI的內(nèi)容泼差,ListView要想展示出來,必須要有DataSource呵俏,這里我們把ListView的DataSource存放到state對象中堆缘。
關(guān)于DataSource有這篇文檔,這里簡單介紹一下普碎,應(yīng)該叫ListView.DataSource吼肥,用來存放ListView將要展示的內(nèi)容(比如從網(wǎng)絡(luò)回來的數(shù)據(jù)、Model等等)麻车,把它作為一個類使用就好缀皱,如果想更新DataSource就調(diào)用它的cloneWithRows(參數(shù)傳新的數(shù)據(jù)),同時它有幾個比較常用的回調(diào)方法我們可以自定義:
- rowHasChanged():返回Bool值动猬,每次刷新數(shù)據(jù)源的時候會回調(diào)到這里啤斗,返回true會觸發(fā)ListView刷新這一行,實現(xiàn)這個方法用來比對ListView是否需要刷新
- getRowData():返回每一行需要的data赁咙,讓你自己解析你傳給DataSource的數(shù)據(jù)結(jié)構(gòu)钮莲,如果不重寫這個方法,會默認(rèn)給你提供一個方法實現(xiàn)彼水,但不一定他解析的數(shù)據(jù)結(jié)構(gòu)和你的相符
有了DataSource后崔拥,ListView還需要一個renderRow()方法,讓你渲染每一行的View凤覆,道理和render函數(shù)一樣链瓦,有一個地方值得注意就是,如果你不想用匿名函數(shù)的方式重寫這個方法盯桦,那么你傳入的方法在被回調(diào)的過程中是獲取不到this這個對象的澡绩,也就是說你也沒法操作this里的任何屬性,這時候就需要在傳入方法后面加上.bind(this)綁定上下文
接下來我們在componentDidMount里請求網(wǎng)絡(luò)數(shù)據(jù)俺附,然后緩存到本地,下次啟動程序先展示本地緩存數(shù)據(jù)溪掀。RN里的網(wǎng)絡(luò)請求事镣,可以用fetch,
如果不想用這種方法,RN還提供了從原生到RN通信機制璃哟,比如你是適配iOS工程的話氛琢,就可以自定義一個類,然后用AFN請求随闪,之后再回調(diào)給RN阳似。
關(guān)于本地緩存這塊,目前沒有看到有相關(guān)的API铐伴,同時也想試試與原生模塊通信這個機制撮奏,于是就把本地緩存的邏輯放到了原生類里面,具體做法參考這里当宴。
最后一個頁面和前面基本相同畜吊,有一點就是關(guān)于style屬性,每一個View都有style屬性户矢,用來設(shè)置布局玲献、樣式等,具體參考這里梯浪,挑幾個比較常用的介紹一下:
paddingBottom:如果你想讓一個View根據(jù)內(nèi)容適應(yīng)高度捌年,那么在style里限制它距底部的距離就行。
flexDirection : 傳row代表橫向布局挂洛,默認(rèn)為column縱向布局礼预。
當(dāng)alignItems、justifyContent傳center時與flexDirection的關(guān)系:
flexDirection | alignItems | justifyContent |
---|---|---|
column | 水平居中 | 垂直居中 |
row | 垂直居中 | 水平居中 |
到這里抹锄,剩下的就是一些重復(fù)的UI和業(yè)務(wù)邏輯了逆瑞,不多說了。
react-native版本在火熱更新著伙单,及時關(guān)注每個版本的改動是可取的获高。