From ef8e688b206605fe9848931a1fe601a9b5d11e24 Mon Sep 17 00:00:00 2001 From: Matthew Arbesfeld Date: Thu, 14 Apr 2016 18:23:47 -0700 Subject: [PATCH] Let inner nested stack reducers handle back actions first Summary:Fix for #6963 Closes https://github.com/facebook/react-native/pull/6982 Differential Revision: D3180164 Pulled By: ericvicenti fb-gh-sync-id: 234d3027097ae032ba0e24470adb3a5ebf07e351 fbshipit-source-id: 234d3027097ae032ba0e24470adb3a5ebf07e351 --- .../Reducer/NavigationStackReducer.js | 18 ++++--- .../__tests__/NavigationStackReducer-test.js | 54 ++++++++++++++++++- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/Libraries/NavigationExperimental/Reducer/NavigationStackReducer.js b/Libraries/NavigationExperimental/Reducer/NavigationStackReducer.js index 9a22d1482..f95198fa1 100644 --- a/Libraries/NavigationExperimental/Reducer/NavigationStackReducer.js +++ b/Libraries/NavigationExperimental/Reducer/NavigationStackReducer.js @@ -73,14 +73,6 @@ function NavigationStackReducer({initialState, getReducerForState, getPushedRedu if (!lastParentState) { return lastState; } - switch (action.type) { - case 'back': - case 'BackAction': - if (lastParentState.index === 0 || lastParentState.children.length === 1) { - return lastParentState; - } - return NavigationStateUtils.pop(lastParentState); - } const activeSubState = lastParentState.children[lastParentState.index]; const activeSubReducer = getReducerForStateWithDefault(activeSubState); @@ -101,6 +93,16 @@ function NavigationStackReducer({initialState, getReducerForState, getPushedRedu subReducerToPush(null, action) ); } + + switch (action.type) { + case 'back': + case 'BackAction': + if (lastParentState.index === 0 || lastParentState.children.length === 1) { + return lastParentState; + } + return NavigationStateUtils.pop(lastParentState); + } + return lastParentState; }; } diff --git a/Libraries/NavigationExperimental/Reducer/__tests__/NavigationStackReducer-test.js b/Libraries/NavigationExperimental/Reducer/__tests__/NavigationStackReducer-test.js index 42edc9d34..95e3c4316 100644 --- a/Libraries/NavigationExperimental/Reducer/__tests__/NavigationStackReducer-test.js +++ b/Libraries/NavigationExperimental/Reducer/__tests__/NavigationStackReducer-test.js @@ -103,4 +103,56 @@ describe('NavigationStackReducer', () => { expect(state3).toBe(state2); }); -}); \ No newline at end of file + it('allows inner reducers to handle back actions', () => { + const subReducer = NavigationStackReducer({ + getPushedReducerForAction: () => {}, + initialState: { + children: [ + {key: 'first'}, + {key: 'second'}, + ], + index: 1, + key: 'myInnerStack' + }, + }); + + const reducer = NavigationStackReducer({ + getPushedReducerForAction: (action) => { + if (action.type === 'TestPushAction') { + return subReducer; + } + + return null; + }, + getReducerForState: (state) => { + if (state.key === 'myInnerStack') { + return subReducer; + } + return () => state; + }, + initialState: { + children: [ + {key: 'a'}, + ], + index: 0, + key: 'myStack' + } + }); + + const state1 = reducer(null, {type: 'MyDefaultAction'}); + const state2 = reducer(state1, {type: 'TestPushAction'}); + expect(state2.children.length).toBe(2); + expect(state2.children[0].key).toBe('a'); + expect(state2.children[1].key).toBe('myInnerStack'); + expect(state2.children[1].children.length).toBe(2); + expect(state2.children[1].children[0].key).toBe('first'); + expect(state2.children[1].children[1].key).toBe('second'); + + const state3 = reducer(state2, NavigationRootContainer.getBackAction()); + expect(state3.children.length).toBe(2); + expect(state3.children[0].key).toBe('a'); + expect(state3.children[1].key).toBe('myInnerStack'); + expect(state3.children[1].children.length).toBe(1); + expect(state3.children[1].children[0].key).toBe('first'); + }); +});