feat: add wildcard patterns for paths

Currently, if we don't have matching routes for a path, we'll reuse the path name for the route name. This doesn't produce an error, and renders the initial route in the navigator. However, the user doesn't have a way of handling this with the default configuration.

This PR adds support for a wildcard pattern ('*'). The wildcard pattern will be matched after all other patterns were matched and will always match unmatched screens. This allows the user to implement a 404 screen.

Example:

```js
{
  Home: '',
  Profile: 'user/:id',
  404: '*',
}
```

This config will return the `404` route for paths which didn't match `Home` or `Profile`, e.g. - `/test`

Closes #8019

Co-authored-by: Evan Bacon <baconbrix@gmail.com>
This commit is contained in:
Satyajit Sahoo
2020-06-05 04:03:48 +02:00
parent ab1f79c096
commit 4fe72e3ce7
4 changed files with 239 additions and 7 deletions

View File

@@ -0,0 +1,40 @@
import { StackNavigationProp } from '@react-navigation/stack';
import * as React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Button } from 'react-native-paper';
const NotFoundScreen = ({
navigation,
}: {
navigation: StackNavigationProp<{ Home: undefined }>;
}) => {
return (
<View style={styles.container}>
<Text style={styles.title}>404 Not Found</Text>
<Button
mode="contained"
onPress={() => navigation.navigate('Home')}
style={styles.button}
>
Go to home
</Button>
</View>
);
};
export default NotFoundScreen;
const styles = StyleSheet.create({
title: {
fontSize: 36,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 8,
},
button: {
margin: 24,
},
});

View File

@@ -48,6 +48,7 @@ import StackHeaderCustomization from './Screens/StackHeaderCustomization';
import BottomTabs from './Screens/BottomTabs';
import MaterialTopTabsScreen from './Screens/MaterialTopTabs';
import MaterialBottomTabs from './Screens/MaterialBottomTabs';
import NotFound from './Screens/NotFound';
import DynamicTabs from './Screens/DynamicTabs';
import AuthFlow from './Screens/AuthFlow';
import CompatAPI from './Screens/CompatAPI';
@@ -68,6 +69,7 @@ type RootDrawerParamList = {
type RootStackParamList = {
Home: undefined;
NotFound: undefined;
} & {
[P in keyof typeof SCREENS]: undefined;
};
@@ -231,7 +233,10 @@ export default function App() {
return acc;
},
{ Home: '' }
{
Home: '',
NotFound: '*',
}
),
},
Article: {
@@ -332,6 +337,11 @@ export default function App() {
</ScrollView>
)}
</Stack.Screen>
<Stack.Screen
name="NotFound"
component={NotFound}
options={{ title: 'Oops!' }}
/>
{(Object.keys(SCREENS) as (keyof typeof SCREENS)[]).map(
(name) => (
<Stack.Screen