mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-10 09:13:43 +08:00
Prevent pop and popToTop from bubbling up to parent stack (#3453)
This commit is contained in:
@@ -28,6 +28,7 @@ class MyNavScreen extends React.Component<MyNavScreenProps> {
|
||||
title="Go to a profile screen"
|
||||
/>
|
||||
<Button onPress={() => navigation.popToTop()} title="Pop to top" />
|
||||
<Button onPress={() => navigation.pop()} title="Pop" />
|
||||
<Button
|
||||
onPress={() => navigation.navigate('Photos', { name: 'Jane' })}
|
||||
title="Go to a photos screen"
|
||||
|
||||
@@ -173,7 +173,11 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
|
||||
// Handle pop-to-top behavior. Make sure this happens after children have had a chance to handle the action, so that the inner stack pops to top first.
|
||||
if (action.type === NavigationActions.POP_TO_TOP) {
|
||||
if (state.index !== 0) {
|
||||
if (state.index === 0) {
|
||||
return {
|
||||
...state,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...state,
|
||||
isTransitioning: action.immediate !== true,
|
||||
@@ -391,6 +395,7 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
const backRoute = state.routes.find(route => route.key === key);
|
||||
backRouteIndex = state.routes.indexOf(backRoute);
|
||||
}
|
||||
|
||||
if (backRouteIndex > 0) {
|
||||
return {
|
||||
...state,
|
||||
@@ -398,6 +403,13 @@ export default (routeConfigs, stackConfig = {}) => {
|
||||
index: backRouteIndex - 1,
|
||||
isTransitioning: immediate !== true,
|
||||
};
|
||||
} else if (
|
||||
backRouteIndex === 0 &&
|
||||
action.type === NavigationActions.POP
|
||||
) {
|
||||
return {
|
||||
...state,
|
||||
};
|
||||
}
|
||||
}
|
||||
return state;
|
||||
|
||||
@@ -366,6 +366,76 @@ describe('StackRouter', () => {
|
||||
expect(pushedState.routes[1].routes[1].routeName).toEqual('qux');
|
||||
});
|
||||
|
||||
test('pop does not bubble up', () => {
|
||||
const ChildNavigator = () => <div />;
|
||||
const GrandChildNavigator = () => <div />;
|
||||
GrandChildNavigator.router = StackRouter({
|
||||
Quux: { screen: () => <div /> },
|
||||
Corge: { screen: () => <div /> },
|
||||
});
|
||||
ChildNavigator.router = TabRouter({
|
||||
Baz: { screen: GrandChildNavigator },
|
||||
Qux: { screen: () => <div /> },
|
||||
});
|
||||
const router = StackRouter({
|
||||
Foo: { screen: () => <div /> },
|
||||
Bar: { screen: ChildNavigator },
|
||||
});
|
||||
|
||||
const state = router.getStateForAction({ type: NavigationActions.INIT });
|
||||
const state2 = router.getStateForAction(
|
||||
{
|
||||
type: NavigationActions.NAVIGATE,
|
||||
routeName: 'Bar',
|
||||
key: 'StackRouterRoot',
|
||||
},
|
||||
state
|
||||
);
|
||||
const barKey = state2.routes[1].routes[0].key;
|
||||
const state3 = router.getStateForAction(
|
||||
{
|
||||
type: NavigationActions.POP,
|
||||
},
|
||||
state2
|
||||
);
|
||||
expect(state3 && state3.index).toEqual(1);
|
||||
expect(state3 && state3.routes[1].index).toEqual(0);
|
||||
});
|
||||
|
||||
test('popToTop does not bubble up', () => {
|
||||
const ChildNavigator = () => <div />;
|
||||
const GrandChildNavigator = () => <div />;
|
||||
GrandChildNavigator.router = StackRouter({
|
||||
Quux: { screen: () => <div /> },
|
||||
Corge: { screen: () => <div /> },
|
||||
});
|
||||
ChildNavigator.router = TabRouter({
|
||||
Baz: { screen: GrandChildNavigator },
|
||||
Qux: { screen: () => <div /> },
|
||||
});
|
||||
const router = StackRouter({
|
||||
Foo: { screen: () => <div /> },
|
||||
Bar: { screen: ChildNavigator },
|
||||
});
|
||||
const state = router.getStateForAction({ type: NavigationActions.INIT });
|
||||
const state2 = router.getStateForAction(
|
||||
{
|
||||
type: NavigationActions.NAVIGATE,
|
||||
routeName: 'Bar',
|
||||
},
|
||||
state
|
||||
);
|
||||
const barKey = state2.routes[1].routes[0].key;
|
||||
const state3 = router.getStateForAction(
|
||||
{
|
||||
type: NavigationActions.POP_TO_TOP,
|
||||
},
|
||||
state2
|
||||
);
|
||||
expect(state3 && state3.index).toEqual(1);
|
||||
expect(state3 && state3.routes[1].index).toEqual(0);
|
||||
});
|
||||
|
||||
test('popToTop works as expected', () => {
|
||||
const TestRouter = StackRouter({
|
||||
foo: { screen: () => <div /> },
|
||||
|
||||
Reference in New Issue
Block a user