fix: show error when beforeRemove is used to prevent action in naive stack

This commit is contained in:
Satyajit Sahoo
2021-07-28 15:31:27 +02:00
parent d2d7f8d95e
commit 6d518a46b8
2 changed files with 23 additions and 7 deletions

View File

@@ -1,6 +1,5 @@
import {
CommonActions,
NavigationAction,
ParamListBase,
useTheme,
} from '@react-navigation/native';
@@ -69,10 +68,7 @@ const InputScreen = ({
React.useEffect(
() =>
navigation.addListener('beforeRemove', (e) => {
const action: NavigationAction & { payload?: { confirmed?: boolean } } =
e.data.action;
if (!hasUnsavedChanges || action.payload?.confirmed) {
if (!hasUnsavedChanges) {
return;
}
@@ -84,7 +80,7 @@ const InputScreen = ({
);
if (discard) {
navigation.dispatch(action);
navigation.dispatch(e.data.action);
}
} else {
Alert.alert(
@@ -95,7 +91,7 @@ const InputScreen = ({
{
text: 'Discard',
style: 'destructive',
onPress: () => navigation.dispatch(action),
onPress: () => navigation.dispatch(e.data.action),
},
]
);

View File

@@ -93,6 +93,24 @@ type Props = {
};
function NativeStackViewInner({ state, navigation, descriptors }: Props) {
const [nextDismissedKey, setNextDismissedKey] =
React.useState<string | null>(null);
const dismissedRouteName = nextDismissedKey
? state.routes.find((route) => route.key === nextDismissedKey)?.name
: null;
React.useEffect(() => {
if (dismissedRouteName) {
const message =
`The screen '${dismissedRouteName}' was removed natively but didn't get removed from JS state. ` +
`This can happen if the action was prevented in a 'beforeRemove' listener, which is not fully supported in native-stack.\n\n` +
`Consider using 'gestureEnabled: false' to prevent back gesture and use a custom back button with 'headerLeft' option to override the native behavior.`;
console.error(message);
}
}, [dismissedRouteName]);
return (
<ScreenStack style={styles.container}>
{state.routes.map((route, index) => {
@@ -173,6 +191,8 @@ function NativeStackViewInner({ state, navigation, descriptors }: Props) {
source: route.key,
target: state.key,
});
setNextDismissedKey(route.key);
}}
>
<HeaderConfig