React Navigation(一)-Navigation屬性(API)
你的app每一個screen元件中都自動具有了navigation屬性:
this.props.navigation
navigate
- 跳轉到其他screen,goBack
- 關閉當前screen並且回退棧addListener
- subscribe to updates to navigation lifecycleisFocused
- 如果screen獲取了焦點返回true,反之false.state
- 當前的狀態/路由setParams
- 改變路由引數getParam
- 獲取指定引數dispatch
- 向路由傳送action
要強調的是navigation屬性並不是所有的元件裡都有,只有screen元件才自動接收該屬性(
當前導航器是stack navigator的時候,this.props.navigation中還有其他幾個函式,部分功能與navigate 和 goBack重合,可以按照個人喜好選擇使用,具體是:
this.props.navigation
push
- 導航到棧的新的路由pop
- 回退popToTop
- 回退到棧頂replace
- 替換當前路由
通用 API
絕大多數與navigation屬性的互動都有navigate, goBack, state, 和setParams參與。
1 navigate
- 連結到其他screen
呼叫方法:
navigation.navigate({routeName, params, action, key}) 或者
navigation.navigate(routeName, params, action)
routeName
- 已經註冊過的目標路由名稱params
- 引數action
- (高階選項) 如果當前screen是一個導航器,表示執行在子路由器中的行為. 更多資訊檢視 Actions Doc.key
- 可選的識別符,表示要導航到的路由. 如果已經存在,表示返回到這個路由。
class HomeScreen extends React.Component { render() { const { navigate } = this.props.navigation; return ( <View> <Text>This is the home screen of the app</Text> <Button onPress={() => navigate('Profile', { name: 'Brent' })} title="Go to Brent's profile" /> </View> ); } }
2 goBack
- 關閉當前screen並回退
可以給定一個key,指定要從那個路由回退。預設會關閉呼叫的路由。如果想回退到任意介面,並且不指明要關閉什麼,就呼叫.goBack(null);當StackNavigators巢狀使用,子navigator的棧中有且只有一項,父navigator中想要回退時,null引數很有用。如果你有點懵逼也不需要擔心,api還需要完善。
class HomeScreen extends React.Component {
render() {
const { goBack } = this.props.navigation;
return (
<View>
<Button onPress={() => goBack()} title="Go back from this HomeScreen" />
<Button onPress={() => goBack(null)} title="Go back anywhere" />
<Button
onPress={() => goBack('screen-123')}
title="Go back from screen-123"
/>
</View>
);
}
}
用goBack從指定screen回退
假設有如下導航棧:
navigation.navigate(SCREEN_KEY_A);
navigation.navigate(SCREEN_KEY_B);
navigation.navigate(SCREEN_KEY_C);
navigation.navigate(SCREEN_KEY_D);
你現在在screen D,向回退到A(將D,C,B彈出),你需要提供一個key,表明從哪裡回退:
navigation.goBack(SCREEN_KEY_B)// 將從B回退到A
因為A在棧頂,你也可以選擇使用navigation.popToTop();
3 addListener
- Subscribe to updates to navigation lifecycle
React Navigation向訂閱過的screen元件傳送事件:
willBlur
- screen 將要失去焦點willFocus
- screen 將要獲取焦點didFocus
- screen 獲取了焦點(if there was a transition, the transition completed)didBlur
- screen 失去了焦點(if there was a transition, the transition completed)
例如
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
payload => {
console.debug('didBlur', payload);
}
);
// Remove the listener when you are done
didBlurSubscription.remove();
jsonPayload:
{
action: { type: 'Navigation/COMPLETE_TRANSITION', key: 'StackRouterRoot' },
context: 'id-1518521010538-2:Navigation/COMPLETE_TRANSITION_Root',
lastState: undefined,
state: undefined,
type: 'didBlur',
};
4 isFocused
- 查詢screen的焦點狀態
如果screen獲取焦點返回true,反之返回false
let isFocused = this.props.navigation.isFocused();
如果向直接使用withNavigationFocus,將會向元件內傳入布林型別的isFocused屬性。
5 state
- screen當前的狀態/路由
screen能通過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' }
}
通過navigate和setParams傳入screen中的引數通常這樣來獲取:
class ProfileScreen extends React.Component {
render() {
return <Text>Name: {this.props.navigation.state.params.name}</Text>;
}
}
6 setParams
- 改變路由引數
setParams允許screen改變路由引數,這在更新頭部按鈕和標題時很有用
class ProfileScreen extends React.Component {
render() {
return (
<Button
onPress={() => this.props.navigation.setParams({ name: 'Lucy' })}
title="Set title name to 'Lucy'"
/>
);
}
}
7 getParam
- 獲取特定的引數值,引數未定義時有候選項
以前獲取引數時你可能遇到過引數未定義這種可怕的情況,可以用getParams來代替
以前是這樣的:
const { name } = this.props.navigation.state.params;
如果引數未定義這種方法就失敗了。
現在是這樣的:
const name = this.props.navigation.getParam('name', 'Peter');
如果name或者param未定義,Peter就是備選項
Stack Actions
以下這些actions在任何stack navigator中都可以使用:
1 Push
與navigate相似,push方法會跳轉到棧中的新路由
navigation.push(routeName, params, action)
routeName
- 已經註冊過的目標路由名稱params
- 引數action
- (高階選項) 子路由中的行為.
2 Pop
跳轉到棧中上一個screen。如果才一個數字引數“n”,指明要回退多少個screen
navigation.pop(n)
3 PopToTop
回退到棧頂,並關閉其他所有screen
navigation.popToTop()
4 Replace
用給定的路由替換當前screen,可以帶引數和子action
navigation.replace(routeName, params, action)
高階 API
dispatch函式並不常用,但是如果navigate和boBack無法滿足需求時也是很好的選擇
dispatch
- 向路由器傳送action
使用dispatch向路由器傳送任意navigation action。The other navigation functions use dispatch behind the scenes.
如果要dispatch一個action,記得使用庫中提供的action生成器。更多資訊檢視Navigation Action Docs
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
action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }),
});
this.props.navigation.dispatch(navigateAction);