RN 版本:0.50
操作環境:Windows 10
React Navigation 版本:1.0.0-beta.20
文章同步自簡書:http://www.jianshu.com/p/6d178490b164
之前已經說過,每個在 navigator 中注冊過的頁面都會接受一個 navigation 屬性,它包含以下幾屬性:
-
- (helper) 連接配接其他頁面navigate
-
- 頁面目前的狀态/路由state
-
- (helper) 更新路由的參數setParams
-
- (helper) 關閉目前活動頁面并傳回goBack
-
- 給路由器發送指令行為dispatch
在之前的幾篇文章中,我們已經接觸過
navigate
(用來跳轉頁面)、
state
(用來擷取傳遞的參數)和
setParams
(用來改變參數),這篇文章将會對它們進行更詳細的說明。
注意:
navigation
屬性被傳遞給了每一個導航相關元件并且包括導航器。不過需要注意的不同點是導航器 navigator 的
navigation
屬性不會包含那些 helper 類的函數(
navigate
,
goBack
等),它隻有
state
和
dispatch
屬性。如果你想要使用導航器
navigation
屬性中的
navigate
函數,你必須使用
dispatch
來傳遞一個導航操作意圖(關于 Navigation Actions 下一篇文章會講)。
與 Redux 內建時的注意事項
注:這段文字直接翻譯自官方文檔,由于我還沒有了解過 redux,是以看得不是太懂。有興趣的可以看看 原文。
由于許多人對 navigator 頂級 API 的了解錯誤,他們并不能很好地正确使用 navigation 屬性與 redux 的關聯。導航器 navigator 如果沒有接收到 navigation 屬性話它會保持自己的狀态,但這個并不是你通常情況下關聯 redux 時想要的特征。對于嵌套在主導航器裡面的各個導航器,你總是會想把 navigation 屬性傳遞下去。這就允許你的頂級導航器去傳達并給子導航器提供狀态。這個時候你隻需要将頂級路由與 redux 內建,因為其他的路由都被包含在了它的裡面。
navigate - 連結其他螢幕
在 app 中跳轉其它頁面時調用的方法。它有如下參數:
navigate(routeName, params, action)
-
- 在你的 app 中已經注冊過的打算跳轉的目的路由名稱routeName
-
- 傳給目的路由的參數params
-
- (進階)如果螢幕是導航器,則在子路由中運作的操作。有關支援的操作的完整清單,請參閱 操作文檔,暫時打算下一篇文章再介紹。action
class HomeScreen extends React.Component {
render() {
const {navigate} = this.props.navigation;
return (
<View>
<Text>This is the home screen of the app</Text>
<Button
// 跳轉到 Profile 頁面并傳遞參數 name
onPress={() => navigate('Profile', {name: 'Brent'})}
title="Go to Brent's profile"
/>
</View>
)
}
}
state - 螢幕目前狀态/路由
一個螢幕可以通過
this.props.navigation.state
擷取它的路由,它傳回的是一個如下類型的對象:
{
// the name of the route config in the router
// 路由器中設定的路由名稱
routeName: 'Profile',
// a unique identifier used to sort routes
// 為友善管理路由而産生的唯一辨別
key: 'main0',
// an optional object of string options for this screen
// 給目前螢幕可供選擇的參數對象
params: { hello: 'world' }
}
class ProfileScreen extends React.Component {
render() {
const {state} = this.props.navigation;
// state.routeName === 'Profile'
return (
// 擷取參數 name,我們之前已經見到過這種用法了
<Text>Name: {state.params.name}</Text>
);
}
}
setParams - 改變路由參數
觸發
setParams
方法允許頁面改變路由中的參數,這對于更新頭部标題及按鈕很有用處。上一篇文章中我們曾經介紹過這個方法。
class ProfileScreen extends React.Component {
render() {
const {setParams} = this.props.navigation;
return (
<Button
onPress={() => setParams({name: 'Lucy'})}
title="Set title name to 'Lucy'"
/>
)
}
}
goBack - 關閉目前活動頁面并傳回
給該方法提供一個 key,來決定要從哪個路由傳回(即要關閉哪個頁面)。預設情況下,會關閉掉調用該方法的目前路由。如果目标是想要回到 anywhere 而不具體地說明要關閉哪個頁面,可以調用
goBack(null)
。
class HomeScreen extends React.Component {
render() {
const {goBack} = this.props.navigation;
return (
<View>
<Button
// 關閉目前的 HomeScreen
onPress={() => goBack()}
title="Go back from this HomeScreen"
/>
<Button
// 這裡測試的結果也是關閉了目前的 HomeScreen
onPress={() => goBack(null)}
title="Go back anywhere"
/>
<Button
// 關閉從 'screen-123' 到棧頂的所有路由
onPress={() => goBack('screen-123')}
title="Go back from screen-123"
/>
</View>
)
}
}
從指定的頁面傳回
假設我們有四個路由 A B C D 依次入棧:
navigation.navigate(SCREEN_KEY_A);
...
navigation.navigate(SCREEN_KEY_B);
...
navigation.navigate(SCREEN_KEY_C);
...
navigation.navigate(SCREEN_KEY_D);
假如你在 screen D 并且想要傳回到 screen A(關閉 D, C 和 B),那麼你就需要這麼寫:
// will go to screen A FROM screen B
navigation.goBack(SCREEN_KEY_B)
注意:這個方法裡面的 key 值,并不是定義 navigator 時我們給頁面自定義的 key,而是上面 state 裡面的
state.key
。并且我們在 D 中不能直接通過
this.props.navigation.state.key
來擷取,因為它擷取的是 D 的 key,是以我們要在 B 中擷取到它,然後一級一級的傳遞給 D,最後調用
navigation.goBack(SCREEN_KEY_B)
來回到 A。
dispatch - 給路由發送一個行為
使用 dispatch 給路由指派任意的 navigation 行為,其它的 navigation 函數使用背景的 dispatch 來實作。記住如果你想指派 react-navigation 行為的話,你應該使用庫裡提供的 action creators。檢視 Navigation Actions 來擷取完整的可指派行為(具體行為會在下一篇文章進行說明)。
import { NavigationActions } from 'react-navigation'
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
params: {},
// navigate can have a nested navigate action that will be run inside the child router
// navigate 可以嵌套 navigate action,它會在子路由裡面執行
action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigateAction)