У меня есть вкладка навигации. На одной из моих вкладок есть форма, и я хотел бы отключить событие навигации, если данные моей формы не сохранены.
В версии 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
Любые решения, как отключить переключение вкладок, прежде чем покинуть вкладку?
Вы можете сохранить предыдущий, текущий экран с помощью React-Navigation onNavigationStateChangereactnavigation.org/docs/en/screen-tracking.html. Я не уверен, что он будет вызываться после или до tabBarOnPress. Вы можете отладить это.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Объект 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.
Кроме того, я надеюсь, что я был прав с экранным именем, если не только отладить его.
Звучит хорошо, но есть одна проблема. Я могу установить детскую коляску под названием isNavigationDisabled на свой главный экран, но когда я нажимаю на другую вкладку и перехожу в этот tabBarOnPress, я получаю состояние нажатой вкладки, а не выхода, поэтому я не могу получить доступ к свойству isNavigationDisabled
@HristoEftimov tabBarOnPress вызывается перед переходом. Не передавайте isNavigationDisabled в params, лучше сохраните его в redux и установите в конструкторе формы. Затем не вызывайте defaultHandler, если установлен isNavigationDisabled.
Я нашел гораздо более простой способ, используя 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.
это помогает? reactnavigation.org/docs/en/…