应用中使用React Navigtation管理的每个screen
组件都会被自动提供一个属性navigation
。它看起来是这个样子的 :
this.props.navigation
navigate
– 跳到其他屏goBack
– 关掉当前活跃屏addListener
– 订阅导航生命周期事件isFocused
– 一个函数,指出该屏是否处于聚焦状态(focused)state
– 当前状态和路由 state/routesetParams
– 设置路由参数getParam
– 获取某个参数,带fallback机制dispatch
– 发送一个指令Action到路由route需要重点指出的是,navigation
不是传递给所有组件;而是只有screen
组件会自动接收该属性! React Navigation在这里没有用任何魔法。比如,如果你想定义一个MyBackButton
组件用作一个screen
组件的子节点,在这个MyBackButton
组件上,你是访问不到navigation
属性的。
如果是StackNavigator
,this.props.navigation
上还会有一些其他的功能函数。这些函数可以作为navigate
和goBack
的替代,你喜欢用哪个就用哪个。这些函数是 :
this.props.navigation
push
- 在导航栈中向前导航到一个新的路由pop
- 在导航栈中返回popToTop
- 回到导航栈的顶部replace
- 使用新的路由替换当前路由你使用navigation
进行的绝大多数交互会涉及到 navigate
, goBack
, state
和 setParams
。
navigate
– 跳到其他屏调用该函数跳转到你应用中的其他某屏。参数如下 :
navigation.navigate({routeName, params, action, key})
或者
navigation.navigate(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
onPress={() => navigate('Profile', { name: 'Brent' })}
title="Go to Brent's profile"
/>
</View>
);
}
}
goBack()
– 关闭当前活跃屏的返回带一个可选参数key,指出从哪个路由返回。缺省情况下,goBack
会关闭调用它的那个路由。
译注: 这里一定要注意两点 :
- 参数key 是路由的key属性,而不是路由名称
- 参数key 指出的是返回动作的起点路由,而不是目标路由
如果目标路由是返回任何地方而不指定关闭什么,调用 .goBack(null)
;Note that the null parameter is useful in the case of nested StackNavigators to go back on a parent navigator when the child navigator already has only one item in the stack. Don’t be concerned if this is confusing, this API needs some work.
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')}
/* 注意,这里 screen-123是返回动作起点路由的key,而不是路由名称 */
title="Go back from screen-123"
/>
</View>
);
}
}
goBack(key)
– 指定起始屏的返回考虑一下如下导航栈历史:
navigation.navigate(SCREEN_KEY_A);
navigation.navigate(SCREEN_KEY_B);
navigation.navigate(SCREEN_KEY_C);
navigation.navigate(SCREEN_KEY_D);
现在在屏D(也就是路由D)想返回屏A(需要弹出屏D,C,B)。想达到该效果,你需要提供一个参数指定返回起始路由给goBack
:
navigation.goBack(SCREEN_KEY_B) // 会从屏B回到屏A,注意:这里参数用的不是当前屏D
addListener
– 订阅导航生命周期事件变化React Navigation 会向做了订阅的screen屏组件发送事件:
willBlur
– 屏幕将要被取消聚焦didBlur
– 屏幕被取消了聚焦(如果有过渡动画,在过渡完成时)willFocus
– 屏幕将要被聚焦didFocus
– 屏幕被聚焦(如果有过渡动画,在过渡完成时)例子 :
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
payload => {
console.debug('didBlur', payload);
}
);
// Remove the listener when you are done
didBlurSubscription.remove();
JSON 格式的参数 payload
:
{
action: { type: 'Navigation/COMPLETE_TRANSITION', key: 'StackRouterRoot' },
context: 'id-1518521010538-2:Navigation/COMPLETE_TRANSITION_Root',
lastState: undefined,
state: undefined,
type: 'didBlur',
};
isFocused
– 查看屏的聚焦状态如果屏处于聚焦状态返回true
,否则返回false
。
let isFocused = this.props.navigation.isFocused();
你可能不想直接使用该方法,而是使用[withNavigationFocus
]{https://reactnavigation.org/docs/navigation-prop.html},它会传递一个isFocused
布尔变量属性到你的组件。
state
– 平的当前状态/路由一个屏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
中传递的params
的最常用的方法 :
class ProfileScreen extends React.Component {
render() {
return <Text>Name: {this.props.navigation.state.params.name}</Text>;
}
}
setParams
– 设置路由参数调用setParams
允许一个屏幕组件修改路由中的参数params
,该功能再修改屏幕头部按钮和标题文字时很有用,比如:
class ProfileScreen extends React.Component {
render() {
return (
<Button
onPress={() => this.props.navigation.setParams({ name: 'Lucy' })}
title="Set title name to 'Lucy'"
/>
);
}
}
getParam
– 获取指定参数值或用缺省值过去,你可能遇到过这中可怕的场景,想访问一个params
中的一个参数时却发现整个params
都未被定义。现在,不用再直接访问参数了,你可以调用getParam
。
以前:
const { name } = this.props.navigation.state.params;
// 想直接访问params中的参数name,但有可能发现整个params都是undefined
现在:
const name = this.props.navigation.getParam('name', 'Peter');
// 即使params或者params.name未定义,也不会有问题,会使用指定的fallback缺省值Peter
译注 : Action 在这里我不并清楚翻译成什么最准确,暂时使用指令来对应这个Action。
以下指令工作在StackNavigator
中:
Push
跟navigate
类似,push
会帮你导航到栈中一个新的路由。
navigation.push(routeName, params, action)
Pop
带你到导航栈中的上一屏。如果你提供一个数字n
,它会指定从导航栈中帮你调回多少屏。
navigation.pop(n)
PopToTop
调用该函数会跳回到导航栈最顶级路由,丢掉其他所有屏。
Replace
调用该函数会使用指定路由替换当前屏,可以带参数params
和sub-action
。
navigation.replace(routeName, params, action)
dispatch
函数通常用的比较少,但是如果navigate
或者goBack
搞不定,它是一个很好的逃生舱口。
dispatch
– 发送指令给路由使用 dispatch
可以向路由发送任何导航指令。其他的导航函数背后使用的都是dispatch
。
注意如果你想使用dispatch
,你需要使用该库提供的指令创建器(action creator)。
导航指令文档中列出了所有可用的指令。
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);