我有一个标签导航。我的一个标签中有一个表单,如果我的表单数据未保存,我想禁用导航事件。
在第1版中,tabBarOnPress
方法提供了previousScene
,scene
和jumpToIndex
,因此我能够检查我要离开哪个场景并访问其道具。
现在在版本2中,tabBarOnPress
方法为场景提供了navigation
道具,但是缺少了先前的场景道具:/
navigationOptions: {
tabBarOnPress: ({ navigation, defaultHandler }) => {
// Check the previous screen
// If I am leaving the home screen and the user has unsaved data
// disable tab navigation
// else change to the pressed tab
},
},
我还尝试了使用导航事件侦听器,但是已经调度了NAVIGATE
操作:
props.navigation.addListener('willBlur', () => {
// Disable tab switching;
}),
简单的零食:https://snack.expo.io/@hristoeftimov/handle-tab-changes-in-react-navigation-v2
任何解决方案如何在离开标签前禁用标签切换?
答案 0 :(得分:1)
我发现使用getStateForAction
更简单。
const defaultGetStateForAction = MainStack.router.getStateForAction;
MainStack.router.getStateForAction = (action, state) => {
if (!state) {
return defaultGetStateForAction(action, state);
}
if (
action.type === NavigationActions.NAVIGATE
&& state.routes[state.index].key === 'HomeTab'
) {
const tab = state.routes[state.index];
const currentRoute = tab.routes[tab.index];
const currentRouteParams = currentRoute.params;
if (currentRouteParams && currentRouteParams.isNavigationDisabled) {
return currentRouteParams.showConfirmationDialog(action);
}
}
return defaultGetStateForAction(action, state);
}
每次在选项卡之间切换时,它都会跳到getStateForAction
中,在那里我可以访问离开选项卡(从state
)和下一个屏幕(从action
)。
因此,当我的操作为NAVIGATE
并且离开屏幕/路线为HoneTab
时,我可以更改/禁用操作的默认状态并触发showConfirmationDialog()
-此功能可以我可以将路由参数设置为HomeTab
屏幕。
答案 1 :(得分:0)
navigation
对象包含您需要的数据,因为它在导航到新选项卡之前保留导航状态。此导航状态同时包含您要导航的屏幕及其参数。
要获取状态,可以使用以下功能:
function getCurrentRoute(navState) {
if (!navState) {
return null;
}
const route = navState.routes[navState.index];
if (route.routes) {
return getCurrentRoute(route); // nested routes
} else {
return {
name: route.routeName,
params: { ...route.params }
};
}
}
因此,现在您可以在onPress处理程序中使用此函数。像这样:
navigationOptions: {
tabBarOnPress: ({ navigation, defaultHandler }) => {
const currentRoute = getCurrentRoute(navigation.state);
if (currentRoute.name !== 'Home' || !currentRoute.params.isNavigationDisabled) {
defaultHandler();
}
}
}
当然,这意味着您需要使用isNavigationDisabled
方法在主屏幕中管理名为this.props.navigation.setParams
的导航参数。
此外,我希望我的屏幕名称正确,即使不是调试它。