fix: don't pop routeKeyHistory when child handles back action (#75)

## Motivation

When pressing back in a StackNavigator nested inside the SwitchRouter, the screen would get popped, but the routeKeyHistory of the SwitchRouter gets popped even though the SwitchRouter doesn't handle the back action. This results in the next back action skipping the last opened tab.

## Fix

Before popping the `routeKeyHistory` stack, we check that the history actually changed. I also added a test for this
This commit is contained in:
Harry Yu
2019-11-18 04:00:10 -08:00
parent b4a6810235
commit 531dc30530
2 changed files with 25 additions and 3 deletions

View File

@@ -81,8 +81,8 @@ export default (routeConfigs, config = {}) => {
}
function getNextState(action, prevState, possibleNextState) {
function updateNextStateHistory(nextState) {
if (backBehavior !== 'history') {
function updateNextStateHistory(prevState, nextState) {
if (backBehavior !== 'history' || nextState.index === prevState.index) {
return nextState;
}
let nextRouteKeyHistory = prevState ? prevState.routeKeyHistory : [];
@@ -115,7 +115,7 @@ export default (routeConfigs, config = {}) => {
routes: nextRoutes,
};
}
return updateNextStateHistory(nextState);
return updateNextStateHistory(prevState, nextState);
}
function getInitialState() {

View File

@@ -117,6 +117,28 @@ describe('SwitchRouter', () => {
expect(getState().routeKeyHistory).toEqual(['B']);
});
it('handles history backBehavior without popping routeKeyHistory when child handles action', () => {
const { navigateTo, back, getState, getSubState } = getRouterTestHelper(
getExampleRouter({ backBehavior: 'history' })
);
expect(getState().routeKeyHistory).toEqual(['A']);
navigateTo('B');
expect(getState().index).toEqual(1);
expect(getState().routeKeyHistory).toEqual(['A', 'B']);
navigateTo('B2');
expect(getState().index).toEqual(1);
expect(getState().routeKeyHistory).toEqual(['A', 'B']);
expect(getSubState(2).routeName).toEqual('B2');
back();
expect(getState().index).toEqual(1);
// 'B' should not be popped when the child handles the back action
expect(getState().routeKeyHistory).toEqual(['A', 'B']);
expect(getSubState(2).routeName).toEqual('B1');
});
it('handles nested actions', () => {
const { navigateTo, getSubState } = getRouterTestHelper(getExampleRouter());