Skip to content

Commit

Permalink
Reset specific StackRouter with key (#789)
Browse files Browse the repository at this point in the history
* First test

* Allow a key to be passed for which scene should handle the action

* Adding key to NavigationResetAction

* Added test

* Add reset test with key

* Only apply this change if it is a RESET action

* Fix logic error, only check if the action is null if it is a RESET
  • Loading branch information
scbrady authored and ericvicenti committed Apr 5, 2017
1 parent e8726c1 commit e402eba
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/TypeDefinition.js
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ export type NavigationInitAction = {
export type NavigationResetAction = {
type: 'Navigation/RESET',
index: number,
key?: ?string,
actions: Array<NavigationNavigateAction>,
};

Expand Down
19 changes: 12 additions & 7 deletions src/routers/StackRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,18 @@ export default (
};
}

// Check if the current scene wants to handle the action
const currentRoute = state.routes[state.index];
const childRouter = childRouters[currentRoute.routeName];
if (childRouter) {
const route = childRouter.getStateForAction(action, currentRoute);
if (route && route !== currentRoute) {
return StateUtils.replaceAt(state, currentRoute.key, route);
// Check if a child scene wants to handle the action as long as it is not a reset to the root stack
if(action.type !== NavigationActions.RESET || action.key !== null) {
const keyIndex = action.key ? StateUtils.indexOf(state, action.key) : -1
const childIndex = keyIndex >= 0 ? keyIndex : state.index;
const childRoute = state.routes[childIndex];
const childRouter = childRouters[childRoute.routeName];
if (childRouter) {
delete action.key;
const route = childRouter.getStateForAction(action, childRoute);
if (route && route !== childRoute) {
return StateUtils.replaceAt(state, childRoute.key, route);
}
}
}

Expand Down
27 changes: 27 additions & 0 deletions src/routers/__tests__/StackRouter-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,33 @@ describe('StackRouter', () => {
expect(state2 && state2.routes[0].routes[0].routeName).toEqual('baz');
});

test('Handles the reset action with a key', () => {
const ChildRouter = StackRouter({
baz: {
screen: () => <div />,
},
});

const ChildNavigator = () => <div />;
ChildNavigator.router = ChildRouter;

const router = StackRouter({
Foo: {
screen: ChildNavigator,
},
Bar: {
screen: () => <div />,
},
});
const state = router.getStateForAction({ type: NavigationActions.INIT });
const state2 = router.getStateForAction({ type: NavigationActions.NAVIGATE, routeName: 'Foo', action: { type: NavigationActions.NAVIGATE, routeName: 'baz' }}, state);
const state3 = router.getStateForAction({ type: NavigationActions.RESET, key: 'Init', actions: [{ type: NavigationActions.NAVIGATE, routeName: 'Foo' }], index: 0 }, state2);
const state4 = router.getStateForAction({ type: NavigationActions.RESET, key: null, actions: [{ type: NavigationActions.NAVIGATE, routeName: 'Bar' }], index: 0 }, state3);

expect(state4 && state4.index).toEqual(0);
expect(state4 && state4.routes[0].routeName).toEqual('Bar');
});

test('Handles the navigate action with params and nested StackRouter', () => {
const ChildNavigator = () => <div />;
ChildNavigator.router = StackRouter({ Baz: { screen: () => <div /> } });
Expand Down

0 comments on commit e402eba

Please sign in to comment.