Compare commits

...

5 Commits

Author SHA1 Message Date
Brent Vatne
8bd25cf372 Bump to 1.0.0 2018-02-06 17:51:55 -08:00
Brent Vatne
20af8c688e Prevent push from bubbling up (#3454) 2018-02-06 17:49:52 -08:00
Brent Vatne
b0dccd7e88 Prevent pop and popToTop from bubbling up to parent stack (#3453) 2018-02-06 17:35:32 -08:00
Brent Vatne
c69a22f10e Bump version 2018-02-06 15:59:44 -08:00
Eric Vicenti
43a1c5ddbd Fix issue with StackRouter popToTop (#3451)
Previously the state was getting squashed, in this case it would destroy the routeName of the state, which was a route for the parent navigator, who could no longer render properly.
2018-02-06 15:56:39 -08:00
4 changed files with 118 additions and 5 deletions

View File

@@ -24,17 +24,19 @@ class MyNavScreen extends React.Component<MyNavScreenProps> {
<SafeAreaView>
<SampleText>{banner}</SampleText>
<Button
onPress={() => navigation.navigate('Profile', { name: 'Jane' })}
title="Go to a profile screen"
onPress={() => navigation.push('Profile', { name: 'Jane' })}
title="Push a profile screen"
/>
<Button
onPress={() => navigation.navigate('Photos', { name: 'Jane' })}
title="Go to a photos screen"
title="Navigate to a photos screen"
/>
<Button
onPress={() => navigation.replace('Profile', { name: 'Lucy' })}
title="Replace with profile"
/>
<Button onPress={() => navigation.popToTop()} title="Pop to top" />
<Button onPress={() => navigation.pop()} title="Pop" />
<Button onPress={() => navigation.goBack(null)} title="Go back" />
<StatusBar barStyle="default" />
</SafeAreaView>

View File

@@ -1,6 +1,6 @@
{
"name": "react-navigation",
"version": "1.0.0-rc.2",
"version": "1.0.0",
"description": "Routing and navigation for your React Native apps",
"main": "src/react-navigation.js",
"repository": {

View File

@@ -173,8 +173,13 @@ 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,
index: 0,
routes: [state.routes[0]],
@@ -276,6 +281,13 @@ export default (routeConfigs, stackConfig = {}) => {
...StateUtils.push(state, route),
isTransitioning: action.immediate !== true,
};
} else if (
action.type === NavigationActions.PUSH &&
childRouters[action.routeName] === undefined
) {
return {
...state,
};
}
if (
@@ -390,6 +402,7 @@ export default (routeConfigs, stackConfig = {}) => {
const backRoute = state.routes.find(route => route.key === key);
backRouteIndex = state.routes.indexOf(backRoute);
}
if (backRouteIndex > 0) {
return {
...state,
@@ -397,6 +410,13 @@ export default (routeConfigs, stackConfig = {}) => {
index: backRouteIndex - 1,
isTransitioning: immediate !== true,
};
} else if (
backRouteIndex === 0 &&
action.type === NavigationActions.POP
) {
return {
...state,
};
}
}
return state;

View File

@@ -366,6 +366,97 @@ describe('StackRouter', () => {
expect(pushedState.routes[1].routes[1].routeName).toEqual('qux');
});
test('pop does not bubble up', () => {
const ChildNavigator = () => <div />;
ChildNavigator.router = StackRouter({
Baz: { screen: () => <div /> },
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('push does not bubble up', () => {
const ChildNavigator = () => <div />;
ChildNavigator.router = StackRouter({
Baz: { screen: () => <div /> },
Qux: { screen: () => <div /> },
});
const router = StackRouter({
Foo: { screen: () => <div /> },
Bar: { screen: ChildNavigator },
Bad: { screen: () => <div /> },
});
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.PUSH,
routeName: 'Bad',
},
state2
);
expect(state3 && state3.index).toEqual(1);
expect(state3 && state3.routes.length).toEqual(2);
});
test('popToTop does not bubble up', () => {
const ChildNavigator = () => <div />;
ChildNavigator.router = StackRouter({
Baz: { screen: () => <div /> },
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 /> },