RN學(xué)習(xí)筆記之Navigator

接觸了RN之后啡莉,必不可免得要接觸界面之間跳轉(zhuǎn)之類的需求逃默,而這一類需求的實(shí)現(xiàn)必須要使用到Navigator這個(gè)導(dǎo)航器攀圈,這次記錄一下使用過程中對(duì)于Navigator導(dǎo)航器的認(rèn)知。

首先要理解這個(gè)導(dǎo)航器凛篙,可以通俗的理解和Android中activity的堆棧管理一樣黍匾,導(dǎo)航器除了界面導(dǎo)航功能之外,還提供界面棧的管理呛梆,界面的跳入和跳出锐涯。(RN中每一個(gè)component都相當(dāng)于一個(gè)組件,一個(gè)或多個(gè)component共同構(gòu)成場(chǎng)景(Scene)填物,場(chǎng)景通俗的理解就是一個(gè)占據(jù)整個(gè)屏幕的界面)

RN中的入口是index.android.js(以Android為例)纹腌,這個(gè)index.js可以看成整個(gè)RN組建的框架,一些基礎(chǔ)的東西都在這里實(shí)例化滞磺、定義升薯。我們的導(dǎo)航器也需要在這個(gè)文件中被創(chuàng)建。(后文中提到的BackAndroid也在這里面定義)

Navigator屬性介紹

Navigator中包含如下屬性:

initialRoute

初始化路由击困,初始化需要顯示的Component涎劈,其中的component參數(shù)必須要有,定義如下:

initialRoute={{title:'main',id:'main',component:defaultComponent}}

configureScene

配置場(chǎng)景動(dòng)畫阅茶,系統(tǒng)提供了很多動(dòng)畫蛛枚,如從底部彈出,從左彈出等目派,參數(shù)如下:

組件中定義:

configureScene={this._configureScence.bind(this)}


_configureScence(route) {

console.log("AndroidTestComponent=====configureScenceAndroid"+ route.type)

if(route.type =='Bottom') {

returnNavigator.SceneConfigs.FloatFromBottom;// 底部彈出

}else if(route.type =='Left') {

returnNavigator.SceneConfigs.FloatFromLeft// 右側(cè)彈出

}else if(route.type =='Right') {

returnNavigator.SceneConfigs.FloatFromRight//左側(cè)彈出

}

returnNavigator.SceneConfigs.PushFromRight;// 默認(rèn)右側(cè)彈出

}

renderScene

場(chǎng)景渲染坤候,根據(jù)路由來確定要掛載渲染的場(chǎng)景胁赢,設(shè)置如下:

組件中定義

renderScene={this._scene.bind(this)}


//場(chǎng)景渲染方法企蹭,傳入路由器和導(dǎo)航器兩個(gè)方法

_scene(route, navigator) {

console.log(route)

//這個(gè)里面如果不做處理,默認(rèn)返回的是initialRoute初始化的component

letComponent= route.component;

//路由器的params可以攜帶參數(shù)

//將改導(dǎo)航器傳遞給下一個(gè)Component

return

//或者直接引入一個(gè)現(xiàn)成的Component

//return

}

ref

這個(gè)屬性有點(diǎn)很微妙智末,網(wǎng)上很多介紹Navigator的博客代碼中沒有寫這個(gè)屬性谅摄,這個(gè)屬性相當(dāng)于給一個(gè)組件添加一個(gè)label標(biāo)簽,然后通過該標(biāo)簽可以找到對(duì)應(yīng)的組件系馆,發(fā)現(xiàn)這個(gè)屬性的原因是我在寫B(tài)ackAndroid的時(shí)候送漠,需要使用到navigator這個(gè)對(duì)象,在監(jiān)聽物理返回鍵的時(shí)候判斷是否還有路由存在由蘑,通常在方法中獲取navigator的方法如下:

_pressButton(){

const {navigator} = this.props;

}

這么寫的前提是_pressButton該方法一般都會(huì)被bind闽寡,而且該Component在掛載前已經(jīng)把navigator傳遞過來了代兵,所以可以獲得到,但是我們?cè)趇ndex.js中使用BackAndroid爷狈,定義方法不管是使用箭頭函數(shù)或者在構(gòu)造方法中bind對(duì)應(yīng)的方法植影,這個(gè)時(shí)候this.props都沒有navigator這個(gè)屬性,所以這個(gè)時(shí)候是找不到的涎永,也就沒辦法實(shí)現(xiàn)導(dǎo)航回退的功能思币,而使用ref就很好的解決這個(gè)問題了,即子組件獲取父組件通過props羡微、父組件獲取子組件通過refs谷饿。如下設(shè)置:

在組建中添加:

ref="navigator"

方法中調(diào)用:

onBackAndroid=()=>{

constnavigator=this.refs.navigator;

...

}

Navigator方法

getCurrentRoutes() - 獲取當(dāng)前棧里的路由列表,也就是push進(jìn)來妈倔,沒有pop掉的那些

jumpBack() - 跳回之前的路由博投,保留現(xiàn)在的,還可以再跳回來盯蝴。相當(dāng)于瀏覽器的回退

jumpForward() - 結(jié)合jumpBack贬堵,此方法再重新打開回退前的,相當(dāng)于瀏覽器的前進(jìn)

jumpTo(route) - 跳轉(zhuǎn)到一個(gè)沒有被取消掛載的已存在場(chǎng)景

push(route) - push一個(gè)新的路由場(chǎng)景

pop() - 移除并取消掛載當(dāng)前的場(chǎng)景结洼,回到上一個(gè)場(chǎng)景

replace(route) -用一個(gè)新的路由場(chǎng)景替代當(dāng)前的場(chǎng)景黎做,該方法之后當(dāng)前的場(chǎng)景就被取消掛載了

replaceAtIndex(route,index) -通過制定index下標(biāo)replace

replacePrevious(route) -replace前一個(gè)場(chǎng)景

immediatelyResetRouteStack(routeStack) -用新的路由場(chǎng)景Stack重置堆棧中的每一個(gè)場(chǎng)景

popToRoute(route) - 移除并取消掛載當(dāng)前場(chǎng)景到制定場(chǎng)景之間的對(duì)

popToTop() - 移除并取消掛載出堆棧中第一個(gè)場(chǎng)景外的其他場(chǎng)景

其中route路由最基本的就是

var route = {component: LoginComponent}


完整代碼如下

//component是從react中來的

importReact, {Component}from'react';

//Text以及View等都是從react-native中來的

import{

AppRegistry,

StyleSheet,

Navigator,

BackAndroid,

Dimensions

}from'react-native';

importsplashfrom'./app/mainview/splash'

importguidefrom'./app/mainview/guide'

//定義一個(gè)Component,按照ES6的語法來,就和java語法中定義class一樣松忍,繼承component

export? default? classAndroidTestComponentextendsComponent{

//構(gòu)造函數(shù)

constructor(props) {

super(props)

//如果_onBackAndroid不是一個(gè)箭頭函數(shù)蒸殿,需要在構(gòu)造函數(shù)中bind this,要不然在添加監(jiān)聽和移除監(jiān)聽時(shí)操作的對(duì)象是不同的

// this._onBackAndroid = this.onBackAndroid.bind(this)

}

//場(chǎng)景動(dòng)畫

_configureScence(route) {

console.log("AndroidTestComponent=====configureScenceAndroid"+ route.type)

if(route.type =='Bottom') {

returnNavigator.SceneConfigs.FloatFromBottom;// 底部彈出

}else if(route.type =='Left') {

returnNavigator.SceneConfigs.FloatFromLeft// 右側(cè)彈出

}else if(route.type =='Right') {

returnNavigator.SceneConfigs.FloatFromRight//左側(cè)彈出

}

returnNavigator.SceneConfigs.PushFromRight;// 默認(rèn)右側(cè)彈出

}

//場(chǎng)景渲染

_scene(route, navigator) {

letComponent= route.component;

//傳遞參數(shù)以及導(dǎo)航器

return

}

//使用箭頭函數(shù)鸣峭,直接綁定this宏所,不需要再構(gòu)造函數(shù)中再去bind

onBackAndroid=()=>{

//使用refs來獲取導(dǎo)航器

constnavigator=this.refs.navigator;

if(!navigator){

return false;

}

constrouters=navigator.getCurrentRoutes();

if(routers.length>1){

navigator.pop();

return true;

}else{

return false;

}

}

//compoment將要掛載的函數(shù),這個(gè)時(shí)候可以在繼續(xù)更新state 添加監(jiān)聽

componentWillMount() {

console.log("AndroidTestComponent=====componentWillMount")

BackAndroid.addEventListener('hardwareBackPress',this.onBackAndroid)

}

//render屬性對(duì)應(yīng)的函數(shù)會(huì)返回一段JSX來表示該組件的結(jié)構(gòu)和布局。該部分是一個(gè)組件必不可少的地方摊溶,沒有這些內(nèi)容爬骤,就無法構(gòu)成一個(gè)組件。

//render方法必須返回單個(gè)根元素

//compoment掛載渲染的函數(shù)

render() {

//定義默認(rèn)閃屏界面

letdefaultComponent= splash;

return(

configureScene={this._configureScence.bind(this)}

renderScene={this._scene.bind(this)}

ref="navigator"

/>

);

}

//compoment已經(jīng)掛載的函數(shù)

//界面渲染完之后莫换,在進(jìn)行一些數(shù)據(jù)處理霞玄,比如網(wǎng)絡(luò)數(shù)據(jù)加載,比如本地?cái)?shù)據(jù)加載

componentDidMount() {

console.log("AndroidTestComponent=====componentDidMount")

}

//作為子控件時(shí)拉岁,當(dāng)期屬性被改變時(shí)調(diào)用

componentWillReceiveProps(nextProps) {

console.log("AndroidTestComponent=====componentWillReceiveProps")

}

//component將要更新時(shí)調(diào)用

componentWillUpdate(nextProps, nextState) {

console.log("AndroidTestComponent=====componentWillUpdate")

}

//component更新后調(diào)用

componentDidUpdate(prevProps, prevState) {

console.log("AndroidTestComponent=====componentDidUpdate")

}

//component銷毀時(shí)調(diào)用

componentWillUnmount() {

console.log("AndroidTestComponent=====componentWillUnmount")

BackAndroid.removeEventListener('hardwareBackPress',this.onBackAndroid)

}

}

conststyles=StyleSheet.create({

container: {

flex:1,

justifyContent:'flex-start',

alignItems:'stretch',

backgroundColor:'white'

},

lineStyle: {

backgroundColor:'grey',

height:0.3,

},

loadText: {

fontSize:20,

textAlign:'center',

margin:10

},

loadView: {

flex:1,

alignItems:'center',

justifyContent:'center'

},

});

//另一種定義props的方法坷剧,如果static defaultProps也定義了,這個(gè)會(huì)覆蓋上面的

// AndroidTestComponent.defaultProps = {

//? ? name:'xiaoerlang'

// }

//進(jìn)行注冊(cè) 'RNProject'為項(xiàng)目名稱 AndroidTestComponent 為啟動(dòng)的component

AppRegistry.registerComponent('RNProject', () => AndroidTestComponent);

過程中遇到的問題及解決方案:

react native - expected acomponent class, got [object Object]

該錯(cuò)誤是引用了小寫的組件喊暖,組件首字母一定要大寫惫企,比如<splash/>應(yīng)該寫成<Splash>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市陵叽,隨后出現(xiàn)的幾起案子狞尔,更是在濱河造成了極大的恐慌丛版,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偏序,死亡現(xiàn)場(chǎng)離奇詭異硼婿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)禽车,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門寇漫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人殉摔,你說我怎么就攤上這事州胳。” “怎么了逸月?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵栓撞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我碗硬,道長(zhǎng)瓤湘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任恩尾,我火速辦了婚禮弛说,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翰意。我一直安慰自己木人,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布冀偶。 她就那樣靜靜地躺著醒第,像睡著了一般。 火紅的嫁衣襯著肌膚如雪进鸠。 梳的紋絲不亂的頭發(fā)上稠曼,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音客年,去河邊找鬼霞幅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搀罢,可吹牛的內(nèi)容都是我干的蝗岖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼榔至,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了欺劳?” 一聲冷哼從身側(cè)響起唧取,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤铅鲤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后枫弟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邢享,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年淡诗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骇塘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡韩容,死狀恐怖款违,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情群凶,我是刑警寧澤插爹,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站请梢,受9級(jí)特大地震影響赠尾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜毅弧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一气嫁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧够坐,春花似錦杉编、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛾坯,卻和暖如春光酣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脉课。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工救军, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人倘零。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓唱遭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親呈驶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拷泽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 前言 學(xué)習(xí)本系列內(nèi)容需要具備一定 HTML 開發(fā)基礎(chǔ),沒有基礎(chǔ)的朋友可以先轉(zhuǎn)至 HTML快速入門(一) 學(xué)習(xí) 本人...
    珍此良辰閱讀 7,287評(píng)論 33 15
  • 一.簡(jiǎn)介 使用導(dǎo)航器可以讓你在應(yīng)用的不同場(chǎng)景(頁(yè)面)間進(jìn)行切換。導(dǎo)航器通過路由對(duì)象來分辨不同的場(chǎng)景司致。利用rende...
    飛奔的小馬閱讀 814評(píng)論 0 0
  • 早應(yīng)過了彷徨的年紀(jì)拆吆,卻遭遇令人感傷的細(xì)雨,也許有意或許無意的話語脂矫,觸動(dòng)已收藏起來的情感記憶枣耀,久久不能平息。 若...
    菩集閱讀 231評(píng)論 0 0
  • 中國(guó)有句古話叫禮尚往來庭再,但有些時(shí)候禮尚往來卻厚重的有來無往捞奕。禮尚往來是一種和諧的狀態(tài),是彼此惺惺相惜的平等尊重拄轻,是...
    昏塵居士閱讀 275評(píng)論 0 1
  • 文靜 雨一路狂奔颅围, 只為思太久,念太執(zhí)哺眯。 好急谷浅,好急, 就這樣扎入媽媽的懷里奶卓。 大地用干裂的手撫摸雨滴一疯, 我也想你...
    文靜_5c0c閱讀 330評(píng)論 4 10