ReactNative基礎(chǔ)篇-導(dǎo)航路由

1. 背景

通常一個(gè)應(yīng)用不會(huì)由單個(gè)界面組成壕曼,而是由多個(gè)模塊枣氧、多個(gè)頁面組成剩胁。react-navigation的功能就是負(fù)責(zé)RN導(dǎo)航條管理昂利、頁面跳轉(zhuǎn)以及中間的交互過程缚陷,這篇文章主要圍繞這個(gè)方案的使用介紹适篙。

image.png

2. 安裝

# 項(xiàng)目根目錄安裝
yarn add react-navigation
# or with npm
# npm install react-navigation
npm install --save react-navigation
npm install --save react-native-gesture-handler

注意:不同RN版本會(huì)有特定的配置,例如下面是大于0.60的注意點(diǎn)箫爷。
if you're on React Native >= 0.60, you need to disable autolinking for react-native-gesture-handler first.

更詳細(xì)可參考安裝教程

3. 使用

在react-navigation中有以下類型導(dǎo)航器:

  • StackNavigator: 類似于普通的Navigator嚷节,屏幕上方導(dǎo)航欄;
  • TabNavigator: 相當(dāng)于iOS里面的TabBarController虎锚,屏幕下方的標(biāo)簽欄硫痰;
  • DrawerNavigator: 抽屜效果,側(cè)邊滑出窜护;
  • SwitchNavigator
  • ...

創(chuàng)建

幾種導(dǎo)航器的創(chuàng)建方式是相似的效斑,這里以創(chuàng)建 StackNavigator 為例。
現(xiàn)在定義HomeComp組件路由為Home柱徙,LoginComp組件路由為L(zhǎng)ogin缓屠,LoginComp為默認(rèn)第一個(gè)顯示的組件。

# 創(chuàng)建底部標(biāo)簽欄為: const RootStack = createBottomTabNavigator(...)
# 創(chuàng)建測(cè)滑為: const RootStack = createDrawerNavigator(...)

# 創(chuàng)建上方導(dǎo)航欄
const RootStack = createStackNavigator(
    {
        Home:{//路由                       
            screen:HomeComp,//對(duì)應(yīng)組件
        },
        Login:{
            screen:LoginComp
        }
    },
    {
        initialRouteName: 'Login',  //第一個(gè)顯示組件頁面,填路由
        //默認(rèn)全局配置
        // defaultNavigationOptions: {
        //     headerStyle: {
        //         backgroundColor: '#f4511e',
        //     },
        //     headerTintColor: '#fff',
        //     headerTitleStyle: {
        //         fontWeight: 'bold',
        //     },
        // }

    }
)
const AppContainer = createAppContainer(RootStack);//創(chuàng)建容器

export default class App extends React.Component<IAppProps> {
  render() {
    return (
        <AppContainer />
    )
  }
}

跳轉(zhuǎn)&傳參

定義好路由之后坐搔,我們就可以嘗試跳轉(zhuǎn)了藏研。跳轉(zhuǎn)主要用的是StackActions方法,我們可以通過它傳入路由和參數(shù)進(jìn)行跳轉(zhuǎn)概行。

StackActions.push({routeName, params, action, key})

根據(jù)具體業(yè)務(wù)的不同蠢挡,會(huì)有不同的跳轉(zhuǎn)行為,StackActions跳轉(zhuǎn)行為有下面幾種:

方法 用法 例子
push 導(dǎo)航到堆棧中的一個(gè)新的路由 [A , B] push C == [A , B , C]
pop 返回堆棧中的上一個(gè)頁面 [A, B] pop == [A]
popToTop 返回堆棧中的第一個(gè)頁面 [A, B,C] popToTop == [A]
replace 用新路由替換當(dāng)前路由 [A , B] replace C == [A , C]
reset 擦除導(dǎo)航器狀態(tài)并將其替換為多個(gè)操作的結(jié)果 [A , B] reset C == [C]

并且需要我們傳入對(duì)應(yīng)參數(shù)凳忙。

參數(shù)解釋
  • routeName:要跳轉(zhuǎn)到的界面的路由名业踏,也就是在createStackNavigator中配置的路由名;
  • params:要傳遞給下一個(gè)界面的參數(shù)涧卵,可選勤家;
  • action:如果該界面是一個(gè)navigator的話,將運(yùn)行這個(gè)sub-action柳恐,可選伐脖;
  • key:要導(dǎo)航到的路由的可選標(biāo)識(shí)符。 如果已存在乐设,將后退到此路由讼庇,可選。
案例
# 跳轉(zhuǎn)Home組件&傳入?yún)?shù):
StackActions.push({routeName:'Home',params:{name:'張三'}})
# or
NavigationActions. navigation({routeName:'Home'})
# or
this.props.navigation.navigate('Home', { /* params go here */ })

# Home組件獲取跳轉(zhuǎn)參數(shù)
const ops = this.props.navigation.getParam('params')
# or 
const ops = this.props.navigation.state.params

除此之外近尚,navigationActions也包含部分跳轉(zhuǎn)方法蠕啄。

NavigationActions.navigation ({routeName, params, action, key})

方法 用法 例子
navigation 跳轉(zhuǎn)到當(dāng)前堆棧路由里存在的一個(gè)頁面 [A , B,C, D] navigate B == [A, B]
Back 返回到上一個(gè)頁面 [A, B] Back == [A]
popToTop 返回堆棧中的第一個(gè)頁面 [A, B,C] popToTop == [A]
Set Params 設(shè)置指定頁面的Params **
Init 初始化一個(gè) state 如果 state 是 undefined **

header bar設(shè)置

默認(rèn)導(dǎo)航跳轉(zhuǎn)的頁面是不帶頭部導(dǎo)航欄的再来,需要我們?cè)诮M件里面進(jìn)行設(shè)置个粱。
每個(gè)頁面組件可以有一個(gè)名為navigationOptions的靜態(tài)屬性邓嘹,它是一個(gè)對(duì)象或一個(gè)返回包含各種配置選項(xiàng)的對(duì)象的函數(shù)笼平,下面是一個(gè)操作實(shí)例殖侵。

class Home extends React.Component {
  static navigationOptions = ({ navigation }) => {
    return {
      //title:'標(biāo)題'
     headerTitle: <headerTitle/>,//自定義中間標(biāo)題控件
     headerRight: <LeftButton event={()=>{navigation.getParam('back')}}/>,//自定義左邊控件
     headerLeft: <RightButton/>,//自定義右邊控件
     headerStyle: {
        backgroundColor: '#f4511e',
     },
     headerTintColor: '#fff',
     headerTitleStyle: {
        fontWeight: 'bold',
     },
    };
  };

 componentDidMount() {
    this.props.navigation.setParams({ back: this. _back });
  }

  _back = () => {
    alert('back')
  };
}

需要注意的是:

  1. 由于navigationOptions 是個(gè)static方法夺饲,不能直接拿到this對(duì)象里的方法胡陪,需要先通過this.props.navigation.setParams設(shè)置件舵,navigationOptions里通過navigation.getParam('back')獲取叹卷。

  2. headerStyle撼港、headerTintColor、headerTitleStyle等屬性也可以直接在createStackNavigator全局設(shè)置骤竹。

模態(tài)跳轉(zhuǎn)

如果需要模態(tài)跳轉(zhuǎn)則需要修改配置帝牡。

const RootStack = createStackNavigator(
  {
    Main: {
      screen: MainStack,
    },
    MyModal: {
      screen: ModalScreen,
    },
  },
  {
    mode: 'modal',
    headerMode: 'none',
  }
);

4. 多模塊跳轉(zhuǎn)

通常在同一個(gè)模塊下面不容易出現(xiàn)路由重名的情況,這種情況通常出現(xiàn)在多個(gè)模塊開發(fā)蒙揣。并且當(dāng)跳轉(zhuǎn)只寫了一個(gè)路由名字時(shí)靶溜,是不清楚跳轉(zhuǎn)到哪個(gè)模塊下面的頁面,缺乏可讀性懒震。因此在react-navigation基礎(chǔ)上罩息,筆者團(tuán)隊(duì)做了一套簡(jiǎn)單的處理路由的邏輯。

  1. 每一個(gè)模塊下面會(huì)有一個(gè)routes.ts的文件个扰。在項(xiàng)目初始化時(shí)瓷炮,會(huì)獲取所有模塊下route.ts文件里定義的路由和對(duì)應(yīng)組件,并根據(jù)對(duì)應(yīng)模塊名字拼接路由路徑递宅。例如在home模塊目錄有個(gè)routes.ts娘香。下面的詳情路由經(jīng)過處理后的真實(shí)路由為home/homeDetail。
# home模塊下router.ts文件
export default [
  {
    path: '/homeDetail',
    component: HomeDetail,
  },
  {
    path: '/home',
    component: Home
  },
]
  1. 將1步驟中所有處理好的路由和相關(guān)配置在createStackNavigator中定義好办龄。

  2. 封裝一個(gè)負(fù)責(zé)跳轉(zhuǎn)的類topNavigator(內(nèi)部是StackActions和navigationActions跳轉(zhuǎn))烘绽,對(duì)于外部而言傳入?yún)?shù)分別為模塊名字,路由俐填,參數(shù)安接。

topNavigator.push(模塊名, 路由名, 參數(shù)})

# demo
topNavigator.push('home', '/homeDetial', {params: params})
topNavigator.replace(__onamespace, '/add-members', {params: params})
topNavigator.back()
  1. 又或者是每個(gè)模塊下面再創(chuàng)建一個(gè)文件暴露跳轉(zhuǎn)方法,如下示例英融,這樣就基本完成多個(gè)模塊間的路由跳轉(zhuǎn)問題盏檐。
/**
 *  跳轉(zhuǎn)到首頁詳情
 */
export default function goHomeDetail(detailOps: HomeDetaiOps) {
  topNavigator.push(__onamespace, '/homeDetail', { params: detailOps });
}

# 其他模塊文件跳轉(zhuǎn)直接調(diào)用goHomeDetail(...)

5. url跳轉(zhuǎn)

動(dòng)態(tài)解析服務(wù)器下發(fā)路由也是界面跳轉(zhuǎn)常用的一種方式,因此可以定義一套協(xié)議驶悟,例如:
pa://XX/home/homedetail?name='zhangsan'&age=10胡野。客戶端做一個(gè)專門解析路由的類撩银,將url解析模塊名字為home给涕,路由路徑為homedetail豺憔,參數(shù)為name和age额获,再執(zhí)行跳轉(zhuǎn)方法够庙。這樣就能成功跳轉(zhuǎn)到home模塊下面的homeDetail頁面,搞定抄邀!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耘眨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子境肾,更是在濱河造成了極大的恐慌剔难,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奥喻,死亡現(xiàn)場(chǎng)離奇詭異偶宫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)环鲤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門纯趋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冷离,你說我怎么就攤上這事吵冒。” “怎么了西剥?”我有些...
    開封第一講書人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵痹栖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我瞭空,道長(zhǎng)揪阿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任匙铡,我火速辦了婚禮图甜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鳖眼。我一直安慰自己黑毅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開白布钦讳。 她就那樣靜靜地躺著矿瘦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愿卒。 梳的紋絲不亂的頭發(fā)上缚去,一...
    開封第一講書人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音琼开,去河邊找鬼易结。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搞动。 我是一名探鬼主播躏精,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鹦肿!你這毒婦竟也來了矗烛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤箩溃,失蹤者是張志新(化名)和其女友劉穎瞭吃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涣旨,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡歪架,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了霹陡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牡拇。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖穆律,靈堂內(nèi)的尸體忽然破棺而出惠呼,到底是詐尸還是另有隱情,我是刑警寧澤峦耘,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布剔蹋,位于F島的核電站,受9級(jí)特大地震影響辅髓,放射性物質(zhì)發(fā)生泄漏泣崩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一洛口、第九天 我趴在偏房一處隱蔽的房頂上張望矫付。 院中可真熱鬧,春花似錦第焰、人聲如沸买优。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杀赢。三九已至,卻和暖如春湘纵,著一層夾襖步出監(jiān)牢的瞬間脂崔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工梧喷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砌左,地道東北人脖咐。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像汇歹,于是被迫代替她去往敵國(guó)和親文搂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

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