mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-24 04:25:34 +08:00
Implement default navigationOptions (#1)
* Bring back 222 impl. * Add it for TabNavigator * Fix eslint issues and flow in the file * First attempt at the docs * Include docs * Fix some typos
This commit is contained in:
@@ -72,6 +72,7 @@ Options for the router:
|
||||
|
||||
- `initialRouteName` - Sets the default screen of the stack. Must match one of the keys in route configs.
|
||||
- `initialRouteParams` - The params for the initial route
|
||||
- `navigationOptions` - Default navigation options to use for screens
|
||||
- `paths` - A mapping of overrides for the paths set in the route configs
|
||||
|
||||
Visual options:
|
||||
|
||||
@@ -32,7 +32,6 @@ class ProfileScreen extends React.Component {
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
#### Generic Navigation Options
|
||||
|
||||
The `title` navigation option is generic between every navigator. It is used to set the title string for a given screen.
|
||||
@@ -47,6 +46,54 @@ class MyScreen extends React.Component {
|
||||
|
||||
Unlike the other nav options which are only utilized by the navigator view, the title option can be used by the environment to update the title in the browser window or app switcher.
|
||||
|
||||
#### Default Navigation Options
|
||||
|
||||
You can configure the default `navigationOptions` for all the screens within particular navigator to save you needing
|
||||
to specify same properties all over the place.
|
||||
|
||||
```js
|
||||
StackNavigator(routeConfig, {
|
||||
navigationOptions: {
|
||||
header: {
|
||||
visible: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The above example will automatically hide navigation bar on all screens.
|
||||
|
||||
To override it on per-screen basis, you could define `navigationOptions` on a component itself:
|
||||
|
||||
```js
|
||||
class ProfileScreen extends React.Component {
|
||||
static navigationOptions = {
|
||||
header: {
|
||||
title: 'Profile Screen',
|
||||
},
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
When `navigationOptions` are present on a component like in the above example, default settings are completely ignored.
|
||||
|
||||
**Extending defaults:** In order to extend default config with screen-specific properties instead of overriding it, you
|
||||
could dynamically configure an option:
|
||||
|
||||
```js
|
||||
class ProfileScreen extends React.Component {
|
||||
static navigationOptions = {
|
||||
header: (navigation, defaultHeader) => ({
|
||||
...defaultHeader,
|
||||
title: 'Profile Screen',
|
||||
}),
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
The 2nd argument passed to the function is the default config as found on the navigator.
|
||||
|
||||
## Tab Navigation Options
|
||||
|
||||
|
||||
@@ -248,6 +248,7 @@ export type NavigationStackRouterConfig = {
|
||||
initialRouteName?: string,
|
||||
initialRouteParams?: NavigationParams,
|
||||
paths?: NavigationPathsConfig,
|
||||
navigationOptions?: NavigationScreenOptions,
|
||||
};
|
||||
|
||||
export type NavigationStackAction =
|
||||
@@ -292,8 +293,9 @@ export type NavigationPathsConfig = {
|
||||
export type NavigationTabRouterConfig = {
|
||||
initialRouteName?: string,
|
||||
paths?: NavigationPathsConfig,
|
||||
navigationOptions?: NavigationScreenOptions,
|
||||
order?: Array<string>, // todo: type these as the real route names rather than 'string'
|
||||
|
||||
|
||||
// Does the back button cause the router to switch to the initial tab
|
||||
backBehavior?: 'none' | 'initialRoute', // defaults `initialRoute`
|
||||
};
|
||||
|
||||
@@ -27,11 +27,13 @@ export default (routeConfigMap: NavigationRouteConfigMap, stackConfig: StackNavi
|
||||
headerComponent,
|
||||
headerMode,
|
||||
mode,
|
||||
navigationOptions,
|
||||
} = stackConfig;
|
||||
const stackRouterConfig = {
|
||||
initialRouteName,
|
||||
initialRouteParams,
|
||||
paths,
|
||||
navigationOptions,
|
||||
};
|
||||
const router = StackRouter(routeConfigMap, stackRouterConfig);
|
||||
return createNavigationContainer(createNavigator(router)(props => (
|
||||
|
||||
@@ -288,7 +288,7 @@ export default (
|
||||
};
|
||||
},
|
||||
|
||||
getScreenConfig: createConfigGetter(routeConfigs),
|
||||
getScreenConfig: createConfigGetter(routeConfigs, stackConfig.navigationOptions),
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -242,6 +242,6 @@ export default (
|
||||
}).find(action => !!action) || null;
|
||||
},
|
||||
|
||||
getScreenConfig: createConfigGetter(routeConfigs),
|
||||
getScreenConfig: createConfigGetter(routeConfigs, config.navigationOptions),
|
||||
};
|
||||
};
|
||||
|
||||
@@ -12,12 +12,18 @@ import type {
|
||||
NavigationRoute,
|
||||
NavigationAction,
|
||||
NavigationRouteConfigMap,
|
||||
NavigationScreenConfig,
|
||||
NavigationScreenOptions,
|
||||
} from '../TypeDefinition';
|
||||
|
||||
|
||||
export default (routeConfigs: NavigationRouteConfigMap) =>
|
||||
(navigation: NavigationScreenProp<NavigationRoute, NavigationAction>, optionName: string, config?: Object) => {
|
||||
export default (
|
||||
routeConfigs: NavigationRouteConfigMap,
|
||||
defaultOptions?: NavigationScreenOptions
|
||||
) =>
|
||||
(
|
||||
navigation: NavigationScreenProp<NavigationRoute, NavigationAction>,
|
||||
optionName: string,
|
||||
config?: Object
|
||||
) => {
|
||||
const route = navigation.state;
|
||||
invariant(
|
||||
route.routeName &&
|
||||
@@ -30,7 +36,7 @@ export default (routeConfigs: NavigationRouteConfigMap) =>
|
||||
let outputConfig = config || null;
|
||||
|
||||
if (Component.router) {
|
||||
const {state, dispatch} = navigation;
|
||||
const { state, dispatch } = navigation;
|
||||
invariant(
|
||||
state && state.routes && state.index != null,
|
||||
`Expect nav state to have routes and index, ${JSON.stringify(route)}`
|
||||
@@ -44,29 +50,19 @@ export default (routeConfigs: NavigationRouteConfigMap) =>
|
||||
|
||||
const routeConfig = routeConfigs[route.routeName];
|
||||
|
||||
if (
|
||||
Component &&
|
||||
Component.navigationOptions &&
|
||||
Component.navigationOptions[optionName] !== undefined
|
||||
) {
|
||||
if (typeof Component.navigationOptions[optionName] === 'function') {
|
||||
outputConfig = Component.navigationOptions[optionName](navigation, outputConfig);
|
||||
} else {
|
||||
outputConfig = Component.navigationOptions[optionName];
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
routeConfig &&
|
||||
routeConfig.navigationOptions &&
|
||||
routeConfig.navigationOptions[optionName] !== undefined
|
||||
) {
|
||||
if (typeof routeConfig.navigationOptions[optionName] === 'function') {
|
||||
outputConfig = routeConfig.navigationOptions[optionName](navigation, outputConfig);
|
||||
} else {
|
||||
outputConfig = routeConfig.navigationOptions[optionName];
|
||||
}
|
||||
}
|
||||
|
||||
return outputConfig;
|
||||
return [
|
||||
defaultOptions,
|
||||
Component.navigationOptions,
|
||||
routeConfig.navigationOptions,
|
||||
].reduce(
|
||||
(acc: Object, options: NavigationScreenOptions) => {
|
||||
if (options && options[optionName] !== undefined) {
|
||||
return typeof options[optionName] === 'function'
|
||||
? options[optionName](navigation, acc)
|
||||
: options[optionName];
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
outputConfig,
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user