mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-11 17:30:51 +08:00
StackRouter PopN Action (#3404)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
const BACK = 'Navigation/BACK';
|
||||
const INIT = 'Navigation/INIT';
|
||||
const NAVIGATE = 'Navigation/NAVIGATE';
|
||||
const POP = 'Navigation/POP';
|
||||
const RESET = 'Navigation/RESET';
|
||||
const SET_PARAMS = 'Navigation/SET_PARAMS';
|
||||
const URI = 'Navigation/URI';
|
||||
@@ -43,6 +44,12 @@ const navigate = createAction(NAVIGATE, payload => {
|
||||
return action;
|
||||
});
|
||||
|
||||
const pop = createAction(POP, payload => ({
|
||||
type: POP,
|
||||
n: payload && payload.n,
|
||||
immediate: payload && payload.immediate,
|
||||
}));
|
||||
|
||||
const reset = createAction(RESET, payload => ({
|
||||
type: RESET,
|
||||
index: payload.index,
|
||||
@@ -123,6 +130,7 @@ export default {
|
||||
BACK,
|
||||
INIT,
|
||||
NAVIGATE,
|
||||
POP,
|
||||
RESET,
|
||||
SET_PARAMS,
|
||||
URI,
|
||||
@@ -132,6 +140,7 @@ export default {
|
||||
back,
|
||||
init,
|
||||
navigate,
|
||||
pop,
|
||||
reset,
|
||||
setParams,
|
||||
uri,
|
||||
|
||||
@@ -39,6 +39,10 @@ export default function(navigation) {
|
||||
);
|
||||
return navigation.dispatch(NavigationActions.navigate(navigateTo));
|
||||
},
|
||||
pop: (n, params) =>
|
||||
navigation.dispatch(
|
||||
NavigationActions.pop({ n, immediate: params && params.immediate })
|
||||
),
|
||||
/**
|
||||
* For updating current route params. For example the nav bar title and
|
||||
* buttons are based on the route params.
|
||||
|
||||
@@ -97,6 +97,7 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
|
||||
"dispatch": [Function],
|
||||
"goBack": [Function],
|
||||
"navigate": [Function],
|
||||
"pop": [Function],
|
||||
"setParams": [Function],
|
||||
"state": Object {
|
||||
"index": 0,
|
||||
@@ -330,6 +331,7 @@ exports[`StackNavigator renders successfully 1`] = `
|
||||
"dispatch": [Function],
|
||||
"goBack": [Function],
|
||||
"navigate": [Function],
|
||||
"pop": [Function],
|
||||
"setParams": [Function],
|
||||
"state": Object {
|
||||
"index": 0,
|
||||
|
||||
@@ -326,10 +326,17 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === NavigationActions.BACK) {
|
||||
const key = action.key;
|
||||
if (
|
||||
action.type === NavigationActions.BACK ||
|
||||
action.type === NavigationActions.POP
|
||||
) {
|
||||
const { key, n, immediate } = action;
|
||||
let backRouteIndex = state.index;
|
||||
if (key) {
|
||||
if (action.type === NavigationActions.POP && n != null) {
|
||||
// determine the index to go back *from*. In this case, n=1 means to go
|
||||
// back from state.index, as if it were a normal "BACK" action
|
||||
backRouteIndex = Math.max(1, state.index - n + 1);
|
||||
} else if (key) {
|
||||
const backRoute = state.routes.find(route => route.key === key);
|
||||
backRouteIndex = state.routes.indexOf(backRoute);
|
||||
}
|
||||
@@ -338,7 +345,7 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
...state,
|
||||
routes: state.routes.slice(0, backRouteIndex),
|
||||
index: backRouteIndex - 1,
|
||||
isTransitioning: action.immediate !== true,
|
||||
isTransitioning: immediate !== true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,6 +713,47 @@ describe('TabRouter', () => {
|
||||
expect(state2).toEqual(state0);
|
||||
});
|
||||
|
||||
test('pop action works as expected', () => {
|
||||
const TestRouter = StackRouter({
|
||||
foo: { screen: () => <div /> },
|
||||
bar: { screen: () => <div /> },
|
||||
});
|
||||
|
||||
const state = {
|
||||
index: 3,
|
||||
isTransitioning: false,
|
||||
routes: [
|
||||
{ key: 'A', routeName: 'foo' },
|
||||
{ key: 'B', routeName: 'bar', params: { bazId: '321' } },
|
||||
{ key: 'C', routeName: 'foo' },
|
||||
{ key: 'D', routeName: 'bar' },
|
||||
],
|
||||
};
|
||||
const poppedState = TestRouter.getStateForAction(
|
||||
NavigationActions.pop(),
|
||||
state
|
||||
);
|
||||
expect(poppedState.routes.length).toBe(3);
|
||||
expect(poppedState.index).toBe(2);
|
||||
expect(poppedState.isTransitioning).toBe(true);
|
||||
|
||||
const poppedState2 = TestRouter.getStateForAction(
|
||||
NavigationActions.pop({ n: 2, immediate: true }),
|
||||
state
|
||||
);
|
||||
expect(poppedState2.routes.length).toBe(2);
|
||||
expect(poppedState2.index).toBe(1);
|
||||
expect(poppedState2.isTransitioning).toBe(false);
|
||||
|
||||
const poppedState3 = TestRouter.getStateForAction(
|
||||
NavigationActions.pop({ n: 5 }),
|
||||
state
|
||||
);
|
||||
expect(poppedState3.routes.length).toBe(1);
|
||||
expect(poppedState3.index).toBe(0);
|
||||
expect(poppedState3.isTransitioning).toBe(true);
|
||||
});
|
||||
|
||||
test('Inner actions are only unpacked if the current tab matches', () => {
|
||||
const PlainScreen = () => <div />;
|
||||
const ScreenA = () => <div />;
|
||||
|
||||
@@ -224,6 +224,7 @@ exports[`TabBarBottom renders successfully 1`] = `
|
||||
"dispatch": undefined,
|
||||
"goBack": [Function],
|
||||
"navigate": [Function],
|
||||
"pop": [Function],
|
||||
"setParams": [Function],
|
||||
"state": Object {
|
||||
"key": "s1",
|
||||
|
||||
Reference in New Issue
Block a user