mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-01-12 22:51:18 +08:00
feat: improve types for options and support a function
This commit is contained in:
@@ -173,7 +173,11 @@ And then we can use it:
|
||||
```js
|
||||
<Stack.Navigator initialRouteName="profile">
|
||||
<Stack.Screen name="settings" component={Settings} />
|
||||
<Stack.Screen name="profile" component={Profile} />
|
||||
<Stack.Screen
|
||||
name="profile"
|
||||
component={Profile}
|
||||
options={{ title: 'My profile' }}
|
||||
/>
|
||||
<Stack.Screen name="home" component={Home} />
|
||||
</Stack.Navigator>
|
||||
```
|
||||
|
||||
@@ -28,6 +28,13 @@ type Action =
|
||||
}
|
||||
| { type: 'POP_TO_TOP' };
|
||||
|
||||
export type StackNavigationOptions = {
|
||||
/**
|
||||
* Title text for the screen.
|
||||
*/
|
||||
title?: string;
|
||||
};
|
||||
|
||||
export type StackNavigationProp<
|
||||
ParamList extends ParamListBase
|
||||
> = NavigationProp<ParamList> & {
|
||||
@@ -236,7 +243,10 @@ const StackRouter: Router<CommonAction | Action> = {
|
||||
};
|
||||
|
||||
export function StackNavigator(props: Props) {
|
||||
const { state, descriptors } = useNavigationBuilder(StackRouter, props);
|
||||
const { state, descriptors } = useNavigationBuilder<StackNavigationOptions>(
|
||||
StackRouter,
|
||||
props
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={{ position: 'relative' }}>
|
||||
@@ -277,4 +287,6 @@ export function StackNavigator(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
export default createNavigator(StackNavigator);
|
||||
export default createNavigator<StackNavigationOptions, typeof StackNavigator>(
|
||||
StackNavigator
|
||||
);
|
||||
|
||||
@@ -23,6 +23,13 @@ type Action = {
|
||||
payload: { name?: string; key?: string; params?: object };
|
||||
};
|
||||
|
||||
export type TabNavigationOptions = {
|
||||
/**
|
||||
* Title text for the screen.
|
||||
*/
|
||||
title?: string;
|
||||
};
|
||||
|
||||
export type TabNavigationProp<ParamList extends ParamListBase> = NavigationProp<
|
||||
ParamList
|
||||
> & {
|
||||
@@ -196,4 +203,6 @@ export function TabNavigator(props: Props) {
|
||||
);
|
||||
}
|
||||
|
||||
export default createNavigator(TabNavigator);
|
||||
export default createNavigator<TabNavigationOptions, typeof TabNavigator>(
|
||||
TabNavigator
|
||||
);
|
||||
|
||||
@@ -149,14 +149,14 @@ function App() {
|
||||
<MyStack.Screen
|
||||
name="first"
|
||||
component={First}
|
||||
options={{ title: 'Foo' }}
|
||||
options={({ route }) => ({
|
||||
title: `Foo (${route.params ? route.params.author : ''})`,
|
||||
})}
|
||||
initialParams={{ author: 'Jane' }}
|
||||
/>
|
||||
<MyStack.Screen
|
||||
name="second"
|
||||
component={Second}
|
||||
options={{ title: 'Bar' }}
|
||||
/>
|
||||
<MyStack.Screen name="second" options={{ title: 'Bar' }}>
|
||||
{props => <Second {...props} />}
|
||||
</MyStack.Screen>
|
||||
<MyStack.Screen name="third" options={{ title: 'Baz' }}>
|
||||
{() => (
|
||||
<MyTab.Navigator initialRouteName="fifth">
|
||||
|
||||
@@ -19,8 +19,13 @@ type Props = {
|
||||
setState: (state: NavigationState) => void;
|
||||
};
|
||||
|
||||
export default function SceneView(props: Props) {
|
||||
const { screen, route, navigation: helpers, getState, setState } = props;
|
||||
export default function SceneView({
|
||||
screen,
|
||||
route,
|
||||
navigation: helpers,
|
||||
getState,
|
||||
setState,
|
||||
}: Props) {
|
||||
const { performTransaction } = React.useContext(NavigationStateContext);
|
||||
|
||||
const navigation = React.useMemo(
|
||||
|
||||
@@ -2,17 +2,19 @@ import * as React from 'react';
|
||||
import { ParamListBase, RouteConfig, TypedNavigator } from './types';
|
||||
import Screen from './Screen';
|
||||
|
||||
export default function createNavigator<N extends React.ComponentType<any>>(
|
||||
RawNavigator: N
|
||||
) {
|
||||
export default function createNavigator<
|
||||
Options extends object,
|
||||
N extends React.ComponentType<any>
|
||||
>(RawNavigator: N) {
|
||||
return function Navigator<ParamList extends ParamListBase>(): TypedNavigator<
|
||||
ParamList,
|
||||
Options,
|
||||
typeof RawNavigator
|
||||
> {
|
||||
return {
|
||||
Navigator: RawNavigator,
|
||||
Screen: Screen as React.ComponentType<
|
||||
RouteConfig<ParamList, keyof ParamList>
|
||||
RouteConfig<ParamList, keyof ParamList, Options>
|
||||
>,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -232,7 +232,7 @@ export type CompositeNavigationProp<
|
||||
(B extends NavigationProp<infer U> ? U : never)
|
||||
>;
|
||||
|
||||
export type Descriptor = {
|
||||
export type Descriptor<Options extends object> = {
|
||||
/**
|
||||
* Render the component associated with this route.
|
||||
*/
|
||||
@@ -244,18 +244,10 @@ export type Descriptor = {
|
||||
options: Options;
|
||||
};
|
||||
|
||||
export type Options = {
|
||||
/**
|
||||
* Title text for the screen.
|
||||
*/
|
||||
title?: string;
|
||||
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export type RouteConfig<
|
||||
ParamList extends ParamListBase = ParamListBase,
|
||||
RouteName extends keyof ParamList = string
|
||||
RouteName extends keyof ParamList = string,
|
||||
Options extends object = object
|
||||
> = {
|
||||
/**
|
||||
* Route name of this screen.
|
||||
@@ -265,7 +257,12 @@ export type RouteConfig<
|
||||
/**
|
||||
* Navigator options for this screen.
|
||||
*/
|
||||
options?: Options;
|
||||
options?:
|
||||
| Options
|
||||
| ((props: {
|
||||
route: RouteProp<ParamList, RouteName>;
|
||||
navigation: NavigationProp<ParamList>;
|
||||
}) => Options);
|
||||
|
||||
/**
|
||||
* Initial params object for the route.
|
||||
@@ -287,6 +284,7 @@ export type RouteConfig<
|
||||
|
||||
export type TypedNavigator<
|
||||
ParamList extends ParamListBase,
|
||||
Options extends object,
|
||||
Navigator extends React.ComponentType<any>
|
||||
> = {
|
||||
Navigator: React.ComponentType<
|
||||
@@ -297,5 +295,5 @@ export type TypedNavigator<
|
||||
initialRouteName?: keyof ParamList;
|
||||
}
|
||||
>;
|
||||
Screen: React.ComponentType<RouteConfig<ParamList, keyof ParamList>>;
|
||||
Screen: React.ComponentType<RouteConfig<ParamList, keyof ParamList, Options>>;
|
||||
};
|
||||
|
||||
@@ -25,9 +25,7 @@ type Options = {
|
||||
onRouteFocus: (key: string) => void;
|
||||
};
|
||||
|
||||
const EMPTY_OPTIONS = Object.freeze({});
|
||||
|
||||
export default function useDescriptors({
|
||||
export default function useDescriptors<ScreenOptions extends object>({
|
||||
state,
|
||||
screens,
|
||||
navigation,
|
||||
@@ -73,10 +71,18 @@ export default function useDescriptors({
|
||||
</NavigationBuilderContext.Provider>
|
||||
);
|
||||
},
|
||||
options: screen.options || EMPTY_OPTIONS,
|
||||
options: {
|
||||
...(typeof screen.options === 'function'
|
||||
? screen.options({
|
||||
// @ts-ignore
|
||||
route,
|
||||
navigation,
|
||||
})
|
||||
: screen.options),
|
||||
},
|
||||
};
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: Descriptor }
|
||||
{} as { [key: string]: Descriptor<ScreenOptions> }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ const getRouteConfigsFromChildren = (children: React.ReactNode) =>
|
||||
);
|
||||
}, []);
|
||||
|
||||
export default function useNavigationBuilder(
|
||||
export default function useNavigationBuilder<ScreenOptions extends object>(
|
||||
router: Router<any>,
|
||||
options: Options
|
||||
) {
|
||||
@@ -156,7 +156,7 @@ export default function useNavigationBuilder(
|
||||
actionCreators: router.actionCreators,
|
||||
});
|
||||
|
||||
const descriptors = useDescriptors({
|
||||
const descriptors = useDescriptors<ScreenOptions>({
|
||||
state,
|
||||
screens,
|
||||
navigation,
|
||||
|
||||
Reference in New Issue
Block a user