应用中使用React Navigtation管理的每个screen组件都会被自动提供一个属性navigation。它看起来是这个样子的 :
this.props.navigationnavigate– 跳到其他屏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.navigationpush- 在导航栈中向前导航到一个新的路由pop- 在导航栈中返回popToTop- 回到导航栈的顶部replace- 使用新的路由替换当前路由
通用API
你使用navigation进行的绝大多数交互会涉及到 navigate, goBack, state 和 setParams。
navigate – 跳到其他屏
调用该函数跳转到你应用中的其他某屏。参数如下 :
navigation.navigate({routeName, params, action, key}) 或者
navigation.navigate(routeName, params, action)
- routName – 目标屏的路由名称,已经注册到了应用程序的路由中
- params – 需要合并到目标路由的参数
- action – (高级参数)如果屏幕是一个navigator的话,需要在子路由中执行的sub-action。这里有所有支持的action的完整清单: Action 文档。
- 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>
);
}
}
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
Stack Actions – 栈指令
译注 : Action 在这里我不并清楚翻译成什么最准确,暂时使用指令来对应这个Action。
以下指令工作在StackNavigator中:
Push
跟navigate类似,push会帮你导航到栈中一个新的路由。
navigation.push(routeName, params, action)- routeName - 目标路由名称,已经在应用路由中注册过
- params - 将要合并到目标路由的参数
- action – (高级参数)如果屏幕是一个navigator的话,需要在子路由中执行的sub-action。这里有所有支持的action的完整清单: Action 文档。
- key – 目标路由的标识字符串,可选参数。如果该路由已经存在于导航栈中,则返回该路由
Pop
带你到导航栈中的上一屏。如果你提供一个数字n,它会指定从导航栈中帮你调回多少屏。
navigation.pop(n)
PopToTop
调用该函数会跳回到导航栈最顶级路由,丢掉其他所有屏。
Replace
调用该函数会使用指定路由替换当前屏,可以带参数params和sub-action。
navigation.replace(routeName, params, action)
高级API
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);

本文详细介绍了React Navigation中的navigation属性,包括navigate、goBack等方法的使用,以及如何通过addListener监听导航事件,isFocused检查屏幕聚焦状态,state访问当前路由状态。
5166

被折叠的 条评论
为什么被折叠?



