mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-08 22:44:14 +08:00
fix: mark descriptors as optional properties
This commit is contained in:
@@ -124,6 +124,8 @@ export type SceneDescriptor = {
|
||||
getComponent(): React.ComponentType;
|
||||
};
|
||||
|
||||
export type SceneDescriptorMap = { [key: string]: SceneDescriptor | undefined };
|
||||
|
||||
export type HeaderBackButtonProps = {
|
||||
disabled?: boolean;
|
||||
onPress: () => void;
|
||||
|
||||
@@ -21,9 +21,10 @@ import {
|
||||
Route,
|
||||
Layout,
|
||||
HeaderMode,
|
||||
SceneDescriptor,
|
||||
NavigationProp,
|
||||
HeaderScene,
|
||||
SceneDescriptorMap,
|
||||
NavigationStackOptions,
|
||||
} from '../../types';
|
||||
|
||||
type ProgressValues = {
|
||||
@@ -33,7 +34,7 @@ type ProgressValues = {
|
||||
type Props = {
|
||||
mode: 'card' | 'modal';
|
||||
navigation: NavigationProp;
|
||||
descriptors: { [key: string]: SceneDescriptor };
|
||||
descriptors: SceneDescriptorMap;
|
||||
routes: Route[];
|
||||
openingRoutes: string[];
|
||||
closingRoutes: string[];
|
||||
@@ -56,7 +57,7 @@ type Props = {
|
||||
|
||||
type State = {
|
||||
routes: Route[];
|
||||
descriptors: { [key: string]: SceneDescriptor };
|
||||
descriptors: SceneDescriptorMap;
|
||||
scenes: HeaderScene<Route>[];
|
||||
progress: ProgressValues;
|
||||
layout: Layout;
|
||||
@@ -135,11 +136,14 @@ export default class Stack extends React.Component<Props, State> {
|
||||
|
||||
const progress = props.routes.reduce(
|
||||
(acc, curr) => {
|
||||
const descriptor = props.descriptors[curr.key];
|
||||
|
||||
acc[curr.key] =
|
||||
state.progress[curr.key] ||
|
||||
new Animated.Value(
|
||||
props.openingRoutes.includes(curr.key) &&
|
||||
props.descriptors[curr.key].options.animationEnabled !== false
|
||||
descriptor &&
|
||||
descriptor.options.animationEnabled !== false
|
||||
? 0
|
||||
: 1
|
||||
);
|
||||
@@ -264,15 +268,21 @@ export default class Stack extends React.Component<Props, State> {
|
||||
previous: { index: number };
|
||||
}) => {
|
||||
const { onTransitionStart, descriptors } = this.props;
|
||||
const options = descriptors[route.key].options;
|
||||
const descriptor = descriptors[route.key];
|
||||
|
||||
onTransitionStart && onTransitionStart(current, previous);
|
||||
options.onTransitionStart && options.onTransitionStart();
|
||||
|
||||
descriptor &&
|
||||
descriptor.options.onTransitionStart &&
|
||||
descriptor.options.onTransitionStart();
|
||||
};
|
||||
|
||||
private handleTransitionEnd = ({ route }: { route: Route }) => {
|
||||
const options = this.props.descriptors[route.key].options;
|
||||
options.onTransitionEnd && options.onTransitionEnd();
|
||||
const descriptor = this.props.descriptors[route.key];
|
||||
|
||||
descriptor &&
|
||||
descriptor.options.onTransitionEnd &&
|
||||
descriptor.options.onTransitionEnd();
|
||||
};
|
||||
|
||||
render() {
|
||||
@@ -298,7 +308,8 @@ export default class Stack extends React.Component<Props, State> {
|
||||
const { scenes, layout, progress, floatingHeaderHeights } = this.state;
|
||||
|
||||
const focusedRoute = navigation.state.routes[navigation.state.index];
|
||||
const focusedOptions = descriptors[focusedRoute.key].options;
|
||||
const focusedDescriptor = descriptors[focusedRoute.key];
|
||||
const focusedOptions = focusedDescriptor ? focusedDescriptor.options : {};
|
||||
|
||||
let defaultTransitionPreset =
|
||||
mode === 'modal' ? ModalTransition : DefaultTransition;
|
||||
@@ -348,7 +359,9 @@ export default class Stack extends React.Component<Props, State> {
|
||||
transitionSpec = defaultTransitionPreset.transitionSpec,
|
||||
cardStyleInterpolator = defaultTransitionPreset.cardStyleInterpolator,
|
||||
headerStyleInterpolator = defaultTransitionPreset.headerStyleInterpolator,
|
||||
} = descriptor.options;
|
||||
} = descriptor
|
||||
? descriptor.options
|
||||
: ({} as NavigationStackOptions);
|
||||
|
||||
return (
|
||||
<MaybeScreen
|
||||
|
||||
@@ -7,16 +7,14 @@ import HeaderContainer, {
|
||||
} from '../Header/HeaderContainer';
|
||||
import {
|
||||
NavigationProp,
|
||||
SceneDescriptor,
|
||||
NavigationConfig,
|
||||
Route,
|
||||
SceneDescriptorMap,
|
||||
} from '../../types';
|
||||
|
||||
type Descriptors = { [key: string]: SceneDescriptor };
|
||||
|
||||
type Props = {
|
||||
navigation: NavigationProp;
|
||||
descriptors: Descriptors;
|
||||
descriptors: SceneDescriptorMap;
|
||||
navigationConfig: NavigationConfig;
|
||||
onTransitionStart?: (
|
||||
current: { index: number },
|
||||
@@ -39,7 +37,7 @@ type State = {
|
||||
replacing: string[];
|
||||
// Since the local routes can vary from the routes from props, we need to keep the descriptors for old routes
|
||||
// Otherwise we won't be able to access the options for routes that were removed
|
||||
descriptors: Descriptors;
|
||||
descriptors: SceneDescriptorMap;
|
||||
};
|
||||
|
||||
class StackView extends React.Component<Props, State> {
|
||||
@@ -91,9 +89,14 @@ class StackView extends React.Component<Props, State> {
|
||||
// We only need to animate routes if the focused route changed
|
||||
// Animating previous routes won't be visible coz the focused route is on top of everything
|
||||
|
||||
const isAnimationEnabled = (route: Route) =>
|
||||
(props.descriptors[route.key] || state.descriptors[route.key]).options
|
||||
.animationEnabled !== false;
|
||||
const isAnimationEnabled = (route: Route) => {
|
||||
const descriptor =
|
||||
props.descriptors[route.key] || state.descriptors[route.key];
|
||||
|
||||
return descriptor
|
||||
? descriptor.options.animationEnabled !== false
|
||||
: true;
|
||||
};
|
||||
|
||||
if (!previousRoutes.find(r => r.key === nextFocusedRoute.key)) {
|
||||
// A new route has come to the focus, we treat this as a push
|
||||
@@ -156,7 +159,7 @@ class StackView extends React.Component<Props, State> {
|
||||
|
||||
return acc;
|
||||
},
|
||||
{} as Descriptors
|
||||
{} as SceneDescriptorMap
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -209,7 +212,13 @@ class StackView extends React.Component<Props, State> {
|
||||
};
|
||||
|
||||
private renderScene = ({ route }: { route: Route }) => {
|
||||
const descriptor = this.state.descriptors[route.key];
|
||||
const descriptor =
|
||||
this.state.descriptors[route.key] || this.props.descriptors[route.key];
|
||||
|
||||
if (!descriptor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { navigation, getComponent } = descriptor;
|
||||
const SceneComponent = getComponent();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user