mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-12 22:30:36 +08:00
Make Router({ RouteName: Component }) a valid way to configure a router (#3486)
* Make Router({routeName: Component}) a valid way to instantiate a route
* Update App.js in NavigationPlayground
* Fix route config flow type
This commit is contained in:
@@ -96,39 +96,19 @@ const ExampleInfo = {
|
||||
},
|
||||
};
|
||||
const ExampleRoutes = {
|
||||
SimpleStack: {
|
||||
screen: SimpleStack,
|
||||
},
|
||||
SimpleTabs: {
|
||||
screen: SimpleTabs,
|
||||
},
|
||||
Drawer: {
|
||||
screen: Drawer,
|
||||
},
|
||||
SimpleStack: SimpleStack,
|
||||
SimpleTabs: SimpleTabs,
|
||||
Drawer: Drawer,
|
||||
// MultipleDrawer: {
|
||||
// screen: MultipleDrawer,
|
||||
// },
|
||||
TabsInDrawer: {
|
||||
screen: TabsInDrawer,
|
||||
},
|
||||
CustomTabs: {
|
||||
screen: CustomTabs,
|
||||
},
|
||||
CustomTransitioner: {
|
||||
screen: CustomTransitioner,
|
||||
},
|
||||
ModalStack: {
|
||||
screen: ModalStack,
|
||||
},
|
||||
StacksWithKeys: {
|
||||
screen: StacksWithKeys,
|
||||
},
|
||||
StacksInTabs: {
|
||||
screen: StacksInTabs,
|
||||
},
|
||||
StacksOverTabs: {
|
||||
screen: StacksOverTabs,
|
||||
},
|
||||
TabsInDrawer: TabsInDrawer,
|
||||
CustomTabs: CustomTabs,
|
||||
CustomTransitioner: CustomTransitioner,
|
||||
ModalStack: ModalStack,
|
||||
StacksWithKeys: StacksWithKeys,
|
||||
StacksInTabs: StacksInTabs,
|
||||
StacksOverTabs: StacksOverTabs,
|
||||
LinkStack: {
|
||||
screen: SimpleStack,
|
||||
path: 'people/Jordan',
|
||||
@@ -137,9 +117,7 @@ const ExampleRoutes = {
|
||||
screen: SimpleTabs,
|
||||
path: 'settings',
|
||||
},
|
||||
TabAnimations: {
|
||||
screen: TabAnimations,
|
||||
},
|
||||
TabAnimations: TabAnimations,
|
||||
};
|
||||
|
||||
type State = {
|
||||
@@ -231,11 +209,16 @@ class MainScreen extends React.Component<any, State> {
|
||||
<TouchableOpacity
|
||||
key={routeName}
|
||||
onPress={() => {
|
||||
const { path, params, screen } = ExampleRoutes[routeName];
|
||||
const { router } = screen;
|
||||
const action =
|
||||
path && router.getActionForPathAndParams(path, params);
|
||||
navigation.navigate(routeName, {}, action);
|
||||
let route = ExampleRoutes[routeName];
|
||||
if (route.screen || route.path || route.params) {
|
||||
const { path, params, screen } = route;
|
||||
const { router } = screen;
|
||||
const action =
|
||||
path && router.getActionForPathAndParams(path, params);
|
||||
navigation.navigate(routeName, {}, action);
|
||||
} else {
|
||||
navigation.navigate(routeName);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<View style={styles.itemContainer}>
|
||||
|
||||
@@ -332,12 +332,15 @@ declare module 'react-navigation' {
|
||||
navigationOptions?: ?NavigationScreenConfig<Options>,
|
||||
};
|
||||
|
||||
declare export type NavigationRouteConfig = {
|
||||
declare export type NavigationRouteConfig =
|
||||
| NavigationComponent
|
||||
| {
|
||||
navigationOptions?: NavigationScreenConfig<*>,
|
||||
path?: string,
|
||||
} & NavigationScreenRouteConfig;
|
||||
|
||||
declare export type NavigationScreenRouteConfig =
|
||||
| NavigationComponent
|
||||
| {
|
||||
screen: NavigationComponent,
|
||||
}
|
||||
|
||||
@@ -175,23 +175,3 @@ test('should throw if the route does not exist', () => {
|
||||
"There is no route defined for key Settings.\nMust be one of: 'Home'"
|
||||
);
|
||||
});
|
||||
|
||||
test('should throw if the screen is not defined under the route config', () => {
|
||||
/* eslint-disable react/no-multi-comp */
|
||||
|
||||
const getScreenOptions = createConfigGetter({
|
||||
Home: {},
|
||||
});
|
||||
|
||||
const routes = [{ key: 'B', routeName: 'Home' }];
|
||||
|
||||
expect(() =>
|
||||
getScreenOptions(
|
||||
addNavigationHelpers({
|
||||
state: routes[0],
|
||||
dispatch: () => false,
|
||||
addListener: dummyEventSubscriber,
|
||||
})
|
||||
)
|
||||
).toThrowError('Route Home must define a screen or a getScreen.');
|
||||
});
|
||||
|
||||
@@ -39,9 +39,7 @@ describe('validateRouteConfigMap', () => {
|
||||
Home: {
|
||||
screen: ProfileNavigator,
|
||||
},
|
||||
Chat: {
|
||||
screen: ListScreen,
|
||||
},
|
||||
Chat: ListScreen,
|
||||
};
|
||||
validateRouteConfigMap(invalidMap);
|
||||
});
|
||||
|
||||
@@ -32,5 +32,5 @@ export default function getScreenForRouteName(routeConfigs, routeName) {
|
||||
return screen;
|
||||
}
|
||||
|
||||
throw new Error(`Route ${routeName} must define a screen or a getScreen.`);
|
||||
return routeConfig;
|
||||
}
|
||||
|
||||
@@ -14,44 +14,37 @@ function validateRouteConfigMap(routeConfigs) {
|
||||
routeNames.forEach(routeName => {
|
||||
const routeConfig = routeConfigs[routeName];
|
||||
|
||||
if (!routeConfig.screen && !routeConfig.getScreen) {
|
||||
throw new Error(
|
||||
`Route '${routeName}' should declare a screen. ` +
|
||||
'For example:\n\n' +
|
||||
"import MyScreen from './MyScreen';\n" +
|
||||
'...\n' +
|
||||
`${routeName}: {\n` +
|
||||
' screen: MyScreen,\n' +
|
||||
'}'
|
||||
);
|
||||
} else if (routeConfig.screen && routeConfig.getScreen) {
|
||||
throw new Error(
|
||||
`Route '${routeName}' should declare a screen or ` +
|
||||
'a getScreen, not both.'
|
||||
);
|
||||
}
|
||||
const screenComponent = routeConfig.screen
|
||||
? routeConfig.screen
|
||||
: routeConfig;
|
||||
|
||||
if (
|
||||
routeConfig.screen &&
|
||||
typeof routeConfig.screen !== 'function' &&
|
||||
typeof routeConfig.screen !== 'string'
|
||||
screenComponent &&
|
||||
typeof screenComponent !== 'function' &&
|
||||
typeof screenComponent !== 'string' &&
|
||||
!routeConfig.getScreen
|
||||
) {
|
||||
throw new Error(
|
||||
`The component for route '${routeName}' must be a ` +
|
||||
'React component. For example:\n\n' +
|
||||
"import MyScreen from './MyScreen';\n" +
|
||||
'...\n' +
|
||||
`${routeName}: {\n` +
|
||||
' screen: MyScreen,\n' +
|
||||
`${routeName}: MyScreen,\n` +
|
||||
'}\n\n' +
|
||||
'You can also use a navigator:\n\n' +
|
||||
"import MyNavigator from './MyNavigator';\n" +
|
||||
'...\n' +
|
||||
`${routeName}: {\n` +
|
||||
' screen: MyNavigator,\n' +
|
||||
`${routeName}: MyNavigator,\n` +
|
||||
'}'
|
||||
);
|
||||
}
|
||||
|
||||
if (routeConfig.screen && routeConfig.getScreen) {
|
||||
throw new Error(
|
||||
`Route '${routeName}' should declare a screen or ` +
|
||||
'a getScreen, not both.'
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user