原文链接 https://reactnavigation.org/docs/en/navigation-prop.html
你的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组件才自动接收该属性(被screen属性声明过的组件),例如:如果你定义了一个MyBackButton组件,并且将其在一个screen组件中作为子组件渲染,那么就不会接收到navigation属性。
当前导航器是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就是备选项
以下这些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);