Skip to content

Commit 787a080

Browse files
brentvatnesourcecode911
authored andcommitted
Add dismiss helper, made possible by also adding carefullyGetParent (react-navigation#3669)
* Add dismiss action, made possible by getParentState * Add dismiss to flow interface * Don't dispatch an action on dismiss helper if no parent state * carefullyGetParent instead of getParentState
1 parent 6909609 commit 787a080

File tree

5 files changed

+48
-2
lines changed

5 files changed

+48
-2
lines changed

examples/NavigationPlayground/js/SimpleStack.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class MyNavScreen extends React.Component<MyNavScreenProps> {
4949
/>
5050
<Button onPress={() => navigation.popToTop()} title="Pop to top" />
5151
<Button onPress={() => navigation.pop()} title="Pop" />
52-
<Button onPress={() => navigation.goBack(null)} title="Go back" />
52+
<Button onPress={() => navigation.goBack()} title="Go back" />
53+
<Button onPress={() => navigation.dismiss()} title="Dismiss" />
5354
<StatusBar barStyle="default" />
5455
</SafeAreaView>
5556
);

flow/react-navigation.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ declare module 'react-navigation' {
486486
+state: S,
487487
dispatch: NavigationDispatch,
488488
goBack: (routeKey?: ?string) => boolean,
489+
dismiss: () => boolean,
489490
navigate: (
490491
routeName: string,
491492
params?: NavigationParams,

src/__tests__/addNavigationHelpers-test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,32 @@ const dummyEventSubscriber = (name: string, handler: (*) => void) => ({
66
});
77

88
describe('addNavigationHelpers', () => {
9+
it('handles dismiss action', () => {
10+
const mockedDispatch = jest
11+
.fn(() => false)
12+
.mockImplementationOnce(() => true);
13+
const child = { key: 'A', routeName: 'Home' };
14+
expect(
15+
addNavigationHelpers({
16+
state: child,
17+
dispatch: mockedDispatch,
18+
addListener: dummyEventSubscriber,
19+
carefullyGetParent: () => ({
20+
state: {
21+
key: 'P',
22+
routeName: 'Parent',
23+
routes: [child],
24+
},
25+
}),
26+
}).dismiss()
27+
).toEqual(true);
28+
expect(mockedDispatch).toBeCalledWith({
29+
type: NavigationActions.BACK,
30+
key: 'P',
31+
});
32+
expect(mockedDispatch.mock.calls.length).toBe(1);
33+
});
34+
935
it('handles Back action', () => {
1036
const mockedDispatch = jest
1137
.fn(() => false)

src/addNavigationHelpers.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import NavigationActions from './NavigationActions';
44
import invariant from './utils/invariant';
5-
65
export default function(navigation) {
76
return {
87
...navigation,
8+
// Go back from the given key, default to active key
99
goBack: key => {
1010
let actualizedKey = key;
1111
if (key === undefined && navigation.state.key) {
@@ -19,6 +19,18 @@ export default function(navigation) {
1919
NavigationActions.back({ key: actualizedKey })
2020
);
2121
},
22+
// Go back from the parent key. If this is a nested stack, the entire
23+
// stack will be dismissed.
24+
dismiss: () => {
25+
let parent = navigation.carefullyGetParent();
26+
if (parent && parent.state) {
27+
return navigation.dispatch(
28+
NavigationActions.back({ key: parent.state.key })
29+
);
30+
} else {
31+
return false;
32+
}
33+
},
2234
navigate: (navigateTo, params, action) => {
2335
if (typeof navigateTo === 'string') {
2436
return navigation.dispatch(

src/navigators/createNavigator.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ function createNavigator(NavigatorView, router, navigationConfig) {
3232
return route === focusedRoute;
3333
};
3434

35+
_carefullyGetParent = () => {
36+
return this.props.navigation;
37+
};
38+
3539
render() {
3640
const { navigation, screenProps } = this.props;
3741
const { dispatch, state, addListener } = navigation;
@@ -52,9 +56,11 @@ function createNavigator(NavigatorView, router, navigationConfig) {
5256
const childNavigation = addNavigationHelpers({
5357
dispatch,
5458
state: route,
59+
carefullyGetParent: this._carefullyGetParent,
5560
addListener: this.childEventSubscribers[route.key].addListener,
5661
isFocused: () => this._isRouteFocused(route),
5762
});
63+
5864
const options = router.getScreenOptions(childNavigation, screenProps);
5965
descriptors[route.key] = {
6066
key: route.key,

0 commit comments

Comments
 (0)