fix: mark descriptors as optional properties

This commit is contained in:
satyajit.happy
2019-07-11 02:02:32 +02:00
parent b685233f3a
commit 4be4ea0fb5
3 changed files with 44 additions and 20 deletions

View File

@@ -124,6 +124,8 @@ export type SceneDescriptor = {
getComponent(): React.ComponentType;
};
export type SceneDescriptorMap = { [key: string]: SceneDescriptor | undefined };
export type HeaderBackButtonProps = {
disabled?: boolean;
onPress: () => void;

View File

@@ -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

View File

@@ -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();