diff --git a/packages/stack/example/App.js b/packages/stack/example/App.js
index e7c62057..d776cf4b 100644
--- a/packages/stack/example/App.js
+++ b/packages/stack/example/App.js
@@ -15,6 +15,7 @@ import ModalStack from './src/ModalStack';
import LifecycleInteraction from './src/LifecycleInteraction';
import GestureInteraction from './src/GestureInteraction';
import SwitchWithStacks from './src/SwitchWithStacks';
+import StackWithDrawer from './src/StackWithDrawer';
// Comment the following two lines to stop using react-native-screens
import { useScreens } from 'react-native-screens';
@@ -48,6 +49,11 @@ const data = [
title: 'Switch with Stacks',
routeName: 'SwitchWithStacks',
},
+ {
+ component: StackWithDrawer,
+ title: 'Stack with drawer inside',
+ routeName: 'StackWithDrawer',
+ },
];
// Cache images
diff --git a/packages/stack/example/package.json b/packages/stack/example/package.json
index e7bb1e28..56b7b09e 100644
--- a/packages/stack/example/package.json
+++ b/packages/stack/example/package.json
@@ -17,7 +17,9 @@
"react": "16.3.1",
"react-native": "~0.55.4",
"react-native-paper": "2.0.0-alpha.4",
- "react-native-screens": "^1.0.0-alpha.9"
+ "react-native-screens": "^1.0.0-alpha.9",
+ "react-navigation-drawer": "^1.0.0-alpha",
+ "react-navigation-tabs": "^1.0.0-alpha"
},
"devDependencies": {
"babel-plugin-module-resolver": "^3.0.0",
diff --git a/packages/stack/example/src/StackWithDrawer.js b/packages/stack/example/src/StackWithDrawer.js
new file mode 100644
index 00000000..26998086
--- /dev/null
+++ b/packages/stack/example/src/StackWithDrawer.js
@@ -0,0 +1,48 @@
+import React from 'react';
+import { Button, Text, View } from 'react-native';
+import { createStackNavigator } from 'react-navigation-stack';
+import { createDrawerNavigator } from 'react-navigation-drawer';
+import { createBottomTabNavigator } from 'react-navigation-tabs';
+
+function Menu({ navigation }) {
+ return (
+
+
+ );
+}
+
+class Fake extends React.Component {
+ render() {
+ return (
+
+
+ {this.props.navigation.getParam('title')}
+
+
+ );
+ }
+}
+
+const Tab = createBottomTabNavigator({
+ Home: { screen: Fake, params: { title: 'Home' } },
+ Other: { screen: Fake, params: { title: 'Other' } },
+});
+
+const Drawer = createDrawerNavigator(
+ {
+ TabScreen: {
+ screen: Tab,
+ },
+ },
+ {
+ contentComponent: props =>
,
+ }
+);
+
+const App = createStackNavigator({
+ Drawer: { screen: Drawer },
+ Top: { screen: Fake, params: { title: 'Top' } },
+});
+
+export default App;
diff --git a/packages/stack/example/yarn.lock b/packages/stack/example/yarn.lock
index 4fc31c04..3629bb67 100644
--- a/packages/stack/example/yarn.lock
+++ b/packages/stack/example/yarn.lock
@@ -4353,6 +4353,13 @@ react-native-svg@6.2.2:
lodash "^4.16.6"
pegjs "^0.10.0"
+react-native-tab-view@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-1.2.0.tgz#0cc26a1c8e49b6c0d58a30363dbbe43954907c31"
+ integrity sha512-lpiWi3dog86Fu/W60DU12RKrFv3XuTv0lHMC56t2jlDqxLfVzG9ufV7li6Afl2S2ZicNU1Bob8WPgxVZc8egAA==
+ dependencies:
+ prop-types "^15.6.1"
+
react-native-vector-icons@4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-4.5.0.tgz#6b95619e64f62f05f579f74a01fe5640df95158b"
@@ -4427,6 +4434,21 @@ react-native@~0.55.4:
xmldoc "^0.4.0"
yargs "^9.0.0"
+react-navigation-drawer@^1.0.0-alpha:
+ version "1.0.0-alpha.5"
+ resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-1.0.0-alpha.5.tgz#1ef75b5e9c7ae9c3011427a493bcc2714ea2c072"
+ integrity sha512-AD1AyqGpUb4coUw3KpJ7i/2RfTiE5RJfTDHVeBkpqc2wsXJ4PaWYGoxfvfWP910hJy8txYTnWWUinWmiD7aBgA==
+
+react-navigation-tabs@^1.0.0-alpha:
+ version "1.0.0-alpha.4"
+ resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-1.0.0-alpha.4.tgz#321c8cc19d14268d343a830689c741bb94c6ba80"
+ integrity sha512-ng8sCJmcQj1ciWaj0eJudQvYng/oL24konNPNudSrMyVKAfKr4+HcRPLY/rol+efLJ8UGjXGv2qdRNkBNeaLew==
+ dependencies:
+ hoist-non-react-statics "^2.5.0"
+ prop-types "^15.6.1"
+ react-lifecycles-compat "^3.0.4"
+ react-native-tab-view "^1.0.0"
+
react-proxy@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a"
diff --git a/packages/stack/src/views/ScenesReducer.js b/packages/stack/src/views/ScenesReducer.js
index 95f6f0cd..f5b45a08 100644
--- a/packages/stack/src/views/ScenesReducer.js
+++ b/packages/stack/src/views/ScenesReducer.js
@@ -94,7 +94,15 @@ export default function ScenesReducer(
});
const nextKeys = new Set();
- nextState.routes.forEach((route, index) => {
+ let nextRoutes = nextState.routes;
+ if (nextRoutes.length > nextState.index + 1) {
+ console.warn(
+ 'StackRouter provided invalid state, index should always be the top route'
+ );
+ nextRoutes = nextState.routes.slice(0, nextState.index + 1);
+ }
+
+ nextRoutes.forEach((route, index) => {
const key = SCENE_KEY_PREFIX + route.key;
let descriptor = descriptors && descriptors[route.key];
@@ -123,8 +131,15 @@ export default function ScenesReducer(
});
if (prevState) {
+ let prevRoutes = prevState.routes;
+ if (prevRoutes.length > prevState.index + 1) {
+ console.warn(
+ 'Stack provided invalid state, index should always be the top route'
+ );
+ prevRoutes = prevRoutes.slice(0, prevState.index + 1);
+ }
// Look at the previous routes and classify any removed scenes as `stale`.
- prevState.routes.forEach((route, index) => {
+ prevRoutes.forEach((route, index) => {
const key = SCENE_KEY_PREFIX + route.key;
if (freshScenes.has(key)) {
return;
diff --git a/packages/stack/src/views/Transitioner.js b/packages/stack/src/views/Transitioner.js
index 2479d926..acb8e93b 100644
--- a/packages/stack/src/views/Transitioner.js
+++ b/packages/stack/src/views/Transitioner.js
@@ -11,8 +11,6 @@ const DefaultTransitionSpec = {
timing: Animated.timing,
};
-const DEBUG = false;
-
class Transitioner extends React.Component {
constructor(props, context) {
super(props, context);
@@ -69,19 +67,14 @@ class Transitioner extends React.Component {
// eslint-disable-next-line react/no-deprecated
componentWillReceiveProps(nextProps) {
- if (this._isTransitionRunning && !this._queuedTransition) {
- this._queuedTransition = { prevProps: this.props };
+ if (this._isTransitionRunning) {
+ if (!this._queuedTransition) {
+ this._queuedTransition = { prevProps: this.props };
+ }
return;
}
- let nextScenes = this._computeScenes(this.props, nextProps);
-
- const indexHasChanged =
- nextProps.navigation.state.index !== this.props.navigation.state.index;
-
- if (nextScenes) {
- this._startTransition(nextProps, nextScenes, indexHasChanged);
- }
+ this._startTransition(this.props, nextProps);
}
_computeScenes = (props, nextProps) => {
@@ -106,26 +99,27 @@ class Transitioner extends React.Component {
return;
}
- if (__DEV__ && DEBUG) {
- console.log({ nextScenes: nextScenes.map(s => s.descriptor.key) });
- }
-
return nextScenes;
};
- _startTransition(nextProps, nextScenes, indexHasChanged) {
+ _startTransition(props, nextProps) {
+ const indexHasChanged =
+ props.navigation.state.index !== nextProps.navigation.state.index;
+ let nextScenes = this._computeScenes(props, nextProps);
+
+ if (!nextScenes) {
+ // prevTransitionProps are the same as transitionProps in this case
+ // because nothing changed
+ this._prevTransitionProps = this._transitionProps;
+ this._onTransitionEnd();
+ return;
+ }
+
const nextState = {
...this.state,
scenes: nextScenes,
};
- if (__DEV__ && DEBUG) {
- console.log({
- startTransition: true,
- nextScenes: nextScenes.map(s => s.descriptor.key),
- });
- }
-
// grab the position animated value
const { position } = nextState;
@@ -135,7 +129,6 @@ class Transitioner extends React.Component {
// compute transitionProps
this._prevTransitionProps = this._transitionProps;
this._transitionProps = buildTransitionProps(nextProps, nextState);
-
let { isTransitioning } = this._transitionProps.navigation.state;
// if the state isn't transitioning that is meant to signal that we should
@@ -205,17 +198,6 @@ class Transitioner extends React.Component {
}
render() {
- if (__DEV__ && DEBUG) {
- let key = this.props.navigation.state.key;
- let routeName = this.props.navigation.state.routeName;
-
- console.log({
- render: true,
- [key]: this.state.scenes.map(d => d.key),
- route: routeName,
- });
- }
-
return (
{this.props.render(this._transitionProps, this._prevTransitionProps)}
@@ -264,10 +246,6 @@ class Transitioner extends React.Component {
scenes,
};
- if (__DEV__ && DEBUG) {
- console.log({ onTransitionEnd: true, scenes: scenes.map(s => s.key) });
- }
-
this._transitionProps = buildTransitionProps(this.props, nextState);
this.setState(nextState, async () => {
@@ -283,20 +261,9 @@ class Transitioner extends React.Component {
}
if (this._queuedTransition) {
- const indexHasChanged =
- this.props.navigation.state.index !==
- this._queuedTransition.prevProps.navigation.state.index;
- let nextScenes = this._computeScenes(
- this._queuedTransition.prevProps,
- this.props
- );
-
- if (nextScenes) {
- this._startTransition(this.props, nextScenes, indexHasChanged);
- } else {
- this._isTransitionRunning = false;
- }
+ let { prevProps } = this._queuedTransition;
this._queuedTransition = null;
+ this._startTransition(prevProps, this.props);
} else {
this._isTransitionRunning = false;
}