1.對于React-Native開發(fā),僅僅有基礎前端開發(fā)的知識是不夠的,你還需要了解和掌握的有:
? Node.js基礎
? JSX語法基礎
? Flexbox布局
2.分為兩部分:
渲染器 ( renderer ) 和全新的 React
第一部分是全新的 React ,它只負責啟用 React 范式。第二部分叫做 ReactDOM ,它唯一的任務就是與瀏覽器中的 DOM 進行交互。因為 ReactDOM 負責更新 DOM ,而 DOM 又決定了瀏覽器渲染的內(nèi)容,所以我們將 ReactDOM 稱之為渲染器。
在調(diào)用react-native run-android命令時,其實這個命令就是執(zhí)行的兩部分操作一是是構(gòu)建你的android項目并生成apk,另外一個是打開react-native的package管理工具同時編譯你的js文件,其實可以在項目根目錄的package.json下找到
其實是執(zhí)行了另外一條命令node node_modules\react-native\packager\packager.js來打開package的管理工具,有些可能沒打開一個新的命令行窗口,自己手動執(zhí)行這條node命令也是可以的。在這條命令執(zhí)行完之后,node就會開啟一個服務,同時把js文件編譯成jsbundle文件,我們可以通過http://localhost:8081/index.android.bundle?platform=android來訪問到這個文件,可以簡單將這個文件理解成一個html,android就是通過解析這個html來達到渲染的目的,將該文件部署到CDN可供android app從網(wǎng)絡獲取,即可實現(xiàn)不用發(fā)版本讓app的UI隨時更新,并且可獲得接近native的體驗,這也是react-native最吸引開發(fā)者的亮點之一。
3.
相比于 Web 上的 React ,React Native 包括更多東西:
? 全新的 React 作為核心庫 (我們的超級英雄,只不過沒穿斗篷)
? iOS 和安卓的渲染器
? 將代碼轉(zhuǎn)換成可安裝應用的工具
? 原生 UI 組件 (狀態(tài)欄、列表等等)和動畫
? UI 的樣式和布局工具箱 (flexbox)
? 構(gòu)建大多數(shù)應用的基礎部分 (比如網(wǎng)絡)
? 提供原生功能的部分,比如粘貼板、加速計和存儲
4.原生 UI 是讓 React Native 大放異彩的原因之一。
在react-native中一個文件也是一個組件?
React Native 中的尺寸都是無單位的,表示的是與設備像素密度無關(guān)的邏輯像素點。
require中的字符串是相對地址或者絕對地址,require()中的參數(shù)必須是一個字面量而不能是一個變量活常量
不存在zIndex,后面的元素覆蓋前面的元素;內(nèi)層元素覆蓋外層元素等等,borderRadius的設置,需要考慮到內(nèi)層元素的位置等等。
在React-Native中圖片的大小是不會根據(jù)給定一個寬度或者高度而自適應大小的,因此我們需要讓圖片根據(jù)寬度或者高度來自適應,那么可以使用resizeMode:Image.resizeMode.contain
5.
props和state共同控制了一個組件,props在父組件中指定,在指定組件的生命周期中不在改變。對于需要改變的數(shù)據(jù)我們使用state
一般來說,需要在constructor中初始化state
? 一切界面變化都是狀態(tài)state變化
? state的修改必須通過setState()方法
○ this.state.likes = 100; // 這樣的直接賦值修改無效!
○ setState 是一個 merge 合并操作,只修改指定屬性,不影響其他屬性
○ setState 是異步操作,修改不會馬上生效
6.??
通過exports去暴露模塊的成員或方法(暴露公開的api)
有兩種方式:
1.module.exports.xxx = 模塊里面的某個接口
2.exports.xxx = 模塊里面的某個接口
這兩者的區(qū)別:
1.
exports是module.exports的一個引用
2.require需要返回的是module.exports,而不是exports,如果此時exports仍為module.exprots的引用則沒有關(guān)系,如果不是則會報錯。
所謂的引用是指指向同一個內(nèi)存地址
eg. var personA = {Name:'TOM'};
? ? ? var personB = personA;
? ? ?此時personB是personA的引用
? ? ?如果此時將personB的屬性Name 修改personA同樣也會修改因為他們指向同一個內(nèi)存地址,若此時將personB = {Name:'Candy'},則此時personA不會被改變,因為已將personB重新賦值,personB不再是personA的引用了,這里可以解釋上的exports和module.exports的關(guān)系。
var market = require('./Market.js')//.代表當前目錄下
這段代碼表達用require加載Market.js這個模塊,返回了module.exports暴露出來的所有方法到market這個對象上
ES5用require, ES6用import
注意導入和導出的寫法必須配套,不能混用!
7.
關(guān)于樣式
(1)普通內(nèi)聯(lián)樣式:{{}},第一層{}是表達式,第二層{}是js對象;
<View style={{fontSize:40, width:80,}}> </View>
(2)調(diào)用樣式表:{樣式類.屬性}
<View style={styles.container}></View>
(3)樣式表和內(nèi)聯(lián)樣式共存:{[]}
<View style={[styles.container, {fontSize:40, width:80}]}>
(4)多個樣式表:{[樣式類1, 樣式類2]}
<View style={[styles.container, styles.color]}>
8.
React進行了虛擬DOM的封裝,所有的視圖的更新都是虛擬DOM做了一個校驗(diff)后最小更新。為什么這么做,因為現(xiàn)在機器的內(nèi)存已經(jīng)足以支撐這樣視圖UI的diff計算,用內(nèi)存計算換取UI渲染效率。
9.AppRegistry是JS運行所有React Native應用的入口?
AppRegistry模塊則是用來告知React Native哪一個組件被注冊為整個應用的根容器。
使用AppRegistry.registerComponent進行注冊自己,然后原生系統(tǒng)就可以進行加載運行bundle文件包,最后就會可以調(diào)用AppRegistry.runApplication進行運行起來應用。當一個視圖被摧毀的時候,為了結(jié)束應用需要調(diào)用AppRegistry.unmountApplictionComponentAtRootTag方法。
AppRegistry.registerComponent('Allen', () => Allen);
這段代碼中系統(tǒng)自動創(chuàng)建了一個組件叫做Allen 然后這個組件會被Appregistry?這個API的注冊函數(shù)顯示出來。
? ?帶引號的這個“Allen”代表的是這個APP的名稱(?init 時創(chuàng)建的項目名) ,后面的Allen代表的是所要顯示的組件名稱(class名稱),?那么我們就可以在創(chuàng)建一個xxx.js文件 (在react-native中一個文件也是一個組件) 那么我們就可以將這個組件注冊到這里來 則可以顯示這個js所呈現(xiàn)的內(nèi)容 ?
9.
箭頭函數(shù)實際上是在這里定義了一個臨時的函數(shù),箭頭函數(shù)的箭頭=>之前是一個空括號、單個的參數(shù)名、或用括號括起的多個參數(shù)名,而箭頭之后可以是一個表達式(作為函數(shù)的返回值),或者是用花括號括起的函數(shù)體(需要自行通過return來返回值,否則返回的是undefined)。
不論是bind還是箭頭函數(shù),每次被執(zhí)行都返回的是一個新的函數(shù)引用,因此如果你還需要函數(shù)的引用去做一些別的事情(譬如卸載監(jiān)聽器),那么你必須自己保存這個引用
10.
在ES6中,如果在自定義的函數(shù)里使用了this關(guān)鍵字,則需要對其進行“綁定”操作,否則this的指向不對
this.fetchData = this.fetchData.bind(this);
11.
? <Image source={{uri:'http://xxxxxxxx'}} style={{width: 90, height: 90}}/>
這里需要注意兩點:
1)、圖片地址關(guān)鍵字是 uri 不是 url,
2)、
加載網(wǎng)絡圖片需要指定圖片的size,否則無法顯示,我們了解到,在瀏覽器中,如果你不給圖片指定尺寸,那么瀏覽器會首先渲染一個0x0大小的元素占位,然后下載圖片,在下載完成后再基于正確的尺寸來渲染圖片。這樣做的最大問題是UI會在圖片加載的過程中上下跳動,使得用戶體驗非常糟糕。
3).
原生資源指的我們開發(fā)android的時候再res目錄下的drawable或者mipmap目錄
默認加載的是drawable下的圖片資源,如果想加載mipmap中的資源
需要在資源前面加目錄名mipmap/
子view會默認根據(jù)父view來absolute,這里有個技巧,如果想讓子view實現(xiàn)100%的效果可以設置left:0 ,right :0,同理height可以用top:0,bottom:0。
使用text的numberOfLines可以實現(xiàn)文本截取省略號,即css的text-overflow屬性。
-------------------
12.
setInterval、setTimeout?
每次調(diào)用setState時, 都會重新執(zhí)行 render 方法重新渲染。
13.
FlatList組件用于顯示一個垂直的滾動列表,其中的元素之間結(jié)構(gòu)近似而僅數(shù)據(jù)不同。
FlatList更適于長列表數(shù)據(jù),且元素個數(shù)可以增刪。和ScrollView不同的是,F(xiàn)latList并不立即渲染所有元素,而是優(yōu)先渲染屏幕上可見的元素。
FlatList組件必須的兩個屬性是data和renderItem。
data是列表的數(shù)據(jù)源,而renderItem則從數(shù)據(jù)源中逐個解析數(shù)據(jù),然后返回一個設定好格式的組件來渲染。
如果要渲染的是一組需要分組的數(shù)據(jù),也許還帶有分組標簽的,那么SectionList將是個不錯的選擇
ScrollView是一個通用的可滾動的容器,你可以在其中放入多個組件和視圖,而且這些組件并不需要是同類型的。ScrollView 不僅可以垂直滾動,還能水平滾動(通過horizontal屬性來設置)。
ScrollView適合用來顯示數(shù)量不多的滾動元素
14.
需要注意的是,安全機制與網(wǎng)頁環(huán)境有所不同:在應用中你可以訪問任何網(wǎng)站,沒有跨域的限制。
15.
Promise是一個構(gòu)造函數(shù),自己身上有all、reject、resolve這幾個眼熟的方法,原型上有then、catch等同樣很眼熟的方法。
Promise的構(gòu)造函數(shù)接收一個參數(shù),是函數(shù),并且傳入兩個參數(shù):resolve,reject,分別表示異步操作執(zhí)行成功后的回調(diào)函數(shù)和異步操作執(zhí)行失敗后的回調(diào)函數(shù)。強大之處:處理 多層回調(diào)。
getNumber()
.then(function(data){
? ? console.log('resolved');
? ? console.log(data);
? ? console.log(somedata); //此處的somedata未定義
})
.catch(function(reason){
? ? console.log('rejected');
? ? console.log(reason);
});
catch效果和寫在then的第二個參數(shù)里面一樣。不過它還有另外一個作用:在執(zhí)行resolve的回調(diào)(也就是上面then中的第一個參數(shù))時,如果拋出異常了(代碼出錯了),那么并不會報錯卡死js,而是會進到這個catch方法中
Promise的all方法提供了并行執(zhí)行異步操作的能力,并且在所有異步操作執(zhí)行完后才執(zhí)行回調(diào)。
用Promise.all來執(zhí)行,all接收一個數(shù)組參數(shù)
all方法的效果實際上是「誰跑的慢,以誰為準執(zhí)行回調(diào)」,那么相對的就有另一個方法「誰跑的快,以誰為準執(zhí)行回調(diào)」,這就是race方法
16.
注意在rn版本0.46版本的時候添加了ImageBackground控件,在0.46版本以后使用Image的時候不能在嵌套使用,使用會報錯,ImageBackground就是解決這個問題的。ImageBackground的使用和Image一樣,只不過可以嵌套其他組件了。
如果要在<Image>組件里面嵌套布局,后面需要用<ImageBackground>組件替代(現(xiàn)在在<Image>里面嵌套子元素,會報警告),目的是為了解決前面使用<Image>組件時,必須明確賦值圖片的大?。╳idth和height),<ImageBackground>可以根據(jù)圖片的實際大小計算整個容器的大小
return (
<ImageBackground
source={require('./image/icon.png')}
style={{flex:1,width:200, height:100,
resizeMode: Image.resizeMode.stretch}}>
<Text style={{marginTop: 60, backgroundColor: 'red'}}>
下面是背景圖片
</Text>
</ImageBackground>
);
17.
require語法也可以用來靜態(tài)地加載你項目中的聲音、視頻或者文檔文件。大多數(shù)常見文件類型都支持,包括.mp3,?.wav,?.mp4,?.mov,?.htm?和?.pdf等
18.
? requestAnimationFrame(): 用來執(zhí)行在一段時間內(nèi)控制視圖動畫的代碼
? setImmediate/setTimeout/setInterval(): 在稍后執(zhí)行代碼。注意這有可能會延遲當前正在進行的動畫。
? runAfterInteractions(): 在稍后執(zhí)行代碼,不會延遲當前進行的動畫。
19.
有些時候你必須要重新編譯應用才能使修改生效:
? 增加了新的資源(比如給 iOS 的Images.xcassets或是 Andorid 的res/drawable文件夾添加了圖片)
? 更改了任何的原生代碼(objective-c/swift/java)
20.
你可以使用console.error()來手動觸發(fā)紅屏錯誤,console.warn()來手動觸發(fā)黃屏警告
21.
在開發(fā)者菜單中選擇"Debug JS Remotely"選項,即可以開始在 Chrome 中調(diào)試 JavaScript 代碼。點擊這個選項的同時會自動打開調(diào)試頁面?http://localhost:8081/debugger-ui.(如果地址欄打開的是 ip 地址,則請自行改為 localhost)
Chrome 中并不能直接看到 App 的用戶界面,而只能提供 console 的輸出,以及在 sources 項中斷點調(diào)試 js 腳本
22.
在終端中運行如下命令來查看控制臺的日志
react-native log-android
23.
開發(fā)服務器(官方名稱 metro,但我們更常稱之為 Packager)
24.
生成一個簽名密鑰
$ keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
設置 gradle 變量
1. 把my-release-key.keystore文件放到你工程中的android/app文件夾下。
2. 編輯~/.gradle/gradle.properties(全局配置,對所有項目有效)或是項目目錄/android/gradle.properties(項目配置,只對所在項目有效)。如果沒有g(shù)radle.properties文件你就自己創(chuàng)建一個,添加如下的代碼(注意把其中的****替換為相應密碼)
把簽名配置加入到項目的 gradle 配置中
android/app/build.gradle
生成發(fā)行 APK 包
$ cd android $
$ ./gradlew assembleRelease
請確保 gradle.properties 中沒有包含_org.gradle.configureondemand=true_,否則會跳過 js 打包的步驟,導致最終生成的 apk 是一個無法運行的空殼。
生成的 APK 文件位于android/app/build/outputs/apk/release/app-release.apk
測試應用的發(fā)行版本
$ react-native run-android --variant=release
針對不同的 CPU 架構(gòu)生成 APK 以減小 APK 文件的大小
def enableSeparateBuildPerCPUArchitecture = true
universalApk true // 額外生成一個適用不同CPU架構(gòu)的通用APK
def enableProguardInReleaseBuilds = true//
//Proguard 是一個 Java 字節(jié)碼混淆壓縮工具,它可以移除掉 React Native Java(和它的依賴庫中)中沒有被使用到的部分,最終有效的減少 APK 的大小。
25.移除不需要的權(quán)限
android/app/src/main/AndroidManifest.xml
android/app/src/release/AndroidManifest.xml
26.把 React Native 組件集成到 Android 應用中有如下幾個主要步驟:
1. 配置好 React Native 依賴和項目結(jié)構(gòu)。
2. 創(chuàng)建 js 文件,編寫 React Native 組件的 js 代碼。
3. 在應用中添加一個RCTRootView。這個RCTRootView正是用來承載你的 React Native 組件的容器。
4. 啟動 React Native 的 Packager 服務,運行應用。
5. 驗證這部分組件是否正常工作。
27.render中必須有標簽,標簽中才能包含構(gòu)造子標簽的函數(shù)。
#####精彩稍后繼續(xù),盡請點贊打賞.