mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-12 09:21:09 +08:00
New StackRouter Push Action (#3401)
This commit is contained in:
@@ -3,6 +3,7 @@ const INIT = 'Navigation/INIT';
|
||||
const NAVIGATE = 'Navigation/NAVIGATE';
|
||||
const POP = 'Navigation/POP';
|
||||
const POP_TO_TOP = 'Navigation/POP_TO_TOP';
|
||||
const PUSH = 'Navigation/PUSH';
|
||||
const RESET = 'Navigation/RESET';
|
||||
const SET_PARAMS = 'Navigation/SET_PARAMS';
|
||||
const URI = 'Navigation/URI';
|
||||
@@ -56,6 +57,20 @@ const popToTop = createAction(POP_TO_TOP, payload => ({
|
||||
immediate: payload && payload.immediate,
|
||||
}));
|
||||
|
||||
const push = createAction(PUSH, payload => {
|
||||
const action = {
|
||||
type: PUSH,
|
||||
routeName: payload.routeName,
|
||||
};
|
||||
if (payload.params) {
|
||||
action.params = payload.params;
|
||||
}
|
||||
if (payload.action) {
|
||||
action.action = payload.action;
|
||||
}
|
||||
return action;
|
||||
});
|
||||
|
||||
const reset = createAction(RESET, payload => ({
|
||||
type: RESET,
|
||||
index: payload.index,
|
||||
@@ -138,6 +153,7 @@ export default {
|
||||
NAVIGATE,
|
||||
POP,
|
||||
POP_TO_TOP,
|
||||
PUSH,
|
||||
RESET,
|
||||
SET_PARAMS,
|
||||
URI,
|
||||
@@ -149,6 +165,7 @@ export default {
|
||||
navigate,
|
||||
pop,
|
||||
popToTop,
|
||||
push,
|
||||
reset,
|
||||
setParams,
|
||||
uri,
|
||||
|
||||
@@ -60,5 +60,10 @@ export default function(navigation) {
|
||||
const key = navigation.state.key;
|
||||
return navigation.dispatch(NavigationActions.setParams({ params, key }));
|
||||
},
|
||||
|
||||
push: (routeName, params, action) =>
|
||||
navigation.dispatch(
|
||||
NavigationActions.push({ routeName, params, action })
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
|
||||
"navigate": [Function],
|
||||
"pop": [Function],
|
||||
"popToTop": [Function],
|
||||
"push": [Function],
|
||||
"setParams": [Function],
|
||||
"state": Object {
|
||||
"index": 0,
|
||||
@@ -334,6 +335,7 @@ exports[`StackNavigator renders successfully 1`] = `
|
||||
"navigate": [Function],
|
||||
"pop": [Function],
|
||||
"popToTop": [Function],
|
||||
"push": [Function],
|
||||
"setParams": [Function],
|
||||
"state": Object {
|
||||
"index": 0,
|
||||
|
||||
@@ -17,6 +17,13 @@ function isEmpty(obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function behavesLikePushAction(action) {
|
||||
return (
|
||||
action.type === NavigationActions.NAVIGATE ||
|
||||
action.type === NavigationActions.PUSH
|
||||
);
|
||||
}
|
||||
|
||||
export default (routeConfigs, stackConfig = {}) => {
|
||||
// Fail fast on invalid route definitions
|
||||
validateRouteConfigMap(routeConfigs);
|
||||
@@ -96,7 +103,7 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
if (!state) {
|
||||
let route = {};
|
||||
if (
|
||||
action.type === NavigationActions.NAVIGATE &&
|
||||
behavesLikePushAction(action) &&
|
||||
childRouters[action.routeName] !== undefined
|
||||
) {
|
||||
return {
|
||||
@@ -178,13 +185,17 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
|
||||
// Handle explicit push navigation action. Make sure this happens after children have had a chance to handle the action
|
||||
if (
|
||||
action.type === NavigationActions.NAVIGATE &&
|
||||
behavesLikePushAction(action) &&
|
||||
childRouters[action.routeName] !== undefined
|
||||
) {
|
||||
const childRouter = childRouters[action.routeName];
|
||||
let route;
|
||||
|
||||
// The key may be provided for pushing, or to navigate back to the key
|
||||
invariant(
|
||||
action.type !== NavigationActions.PUSH || action.key == null,
|
||||
'StackRouter does not support key on the push action'
|
||||
);
|
||||
// With the navigate action, the key may be provided for pushing, or to navigate back to the key
|
||||
if (action.key) {
|
||||
const lastRouteIndex = state.routes.findIndex(
|
||||
r => r.key === action.key
|
||||
@@ -252,7 +263,7 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
}
|
||||
|
||||
// Handle navigation to other child routers that are not yet pushed
|
||||
if (action.type === NavigationActions.NAVIGATE) {
|
||||
if (behavesLikePushAction(action)) {
|
||||
const childRouterNames = Object.keys(childRouters);
|
||||
for (let i = 0; i < childRouterNames.length; i++) {
|
||||
const childRouterName = childRouterNames[i];
|
||||
|
||||
@@ -441,6 +441,26 @@ describe('StackRouter', () => {
|
||||
expect(pushedTwiceState.routes[1].routeName).toEqual('bar');
|
||||
});
|
||||
|
||||
test('Push behaves like navigate, except for key', () => {
|
||||
const TestRouter = StackRouter({
|
||||
foo: { screen: () => <div /> },
|
||||
bar: { screen: () => <div /> },
|
||||
});
|
||||
const initState = TestRouter.getStateForAction(NavigationActions.init());
|
||||
const pushedState = TestRouter.getStateForAction(
|
||||
NavigationActions.push({ routeName: 'bar' }),
|
||||
initState
|
||||
);
|
||||
expect(pushedState.index).toEqual(1);
|
||||
expect(pushedState.routes[1].routeName).toEqual('bar');
|
||||
expect(() => {
|
||||
TestRouter.getStateForAction(
|
||||
{ type: NavigationActions.PUSH, routeName: 'bar', key: 'a' },
|
||||
pushedState
|
||||
);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
test('Handle basic stack logic for plain components', () => {
|
||||
const FooScreen = () => <div />;
|
||||
const BarScreen = () => <div />;
|
||||
|
||||
@@ -226,6 +226,7 @@ exports[`TabBarBottom renders successfully 1`] = `
|
||||
"navigate": [Function],
|
||||
"pop": [Function],
|
||||
"popToTop": [Function],
|
||||
"push": [Function],
|
||||
"setParams": [Function],
|
||||
"state": Object {
|
||||
"key": "s1",
|
||||
|
||||
Reference in New Issue
Block a user