mirror of
https://github.com/status-im/react-navigation.git
synced 2025-02-24 09:08:15 +00:00
Add dismiss helper, made possible by also adding carefullyGetParent (#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
This commit is contained in:
parent
052d22804c
commit
9a6e0bbd98
@ -49,7 +49,8 @@ class MyNavScreen extends React.Component<MyNavScreenProps> {
|
|||||||
/>
|
/>
|
||||||
<Button onPress={() => navigation.popToTop()} title="Pop to top" />
|
<Button onPress={() => navigation.popToTop()} title="Pop to top" />
|
||||||
<Button onPress={() => navigation.pop()} title="Pop" />
|
<Button onPress={() => navigation.pop()} title="Pop" />
|
||||||
<Button onPress={() => navigation.goBack(null)} title="Go back" />
|
<Button onPress={() => navigation.goBack()} title="Go back" />
|
||||||
|
<Button onPress={() => navigation.dismiss()} title="Dismiss" />
|
||||||
<StatusBar barStyle="default" />
|
<StatusBar barStyle="default" />
|
||||||
</SafeAreaView>
|
</SafeAreaView>
|
||||||
);
|
);
|
||||||
|
1
flow/react-navigation.js
vendored
1
flow/react-navigation.js
vendored
@ -486,6 +486,7 @@ declare module 'react-navigation' {
|
|||||||
+state: S,
|
+state: S,
|
||||||
dispatch: NavigationDispatch,
|
dispatch: NavigationDispatch,
|
||||||
goBack: (routeKey?: ?string) => boolean,
|
goBack: (routeKey?: ?string) => boolean,
|
||||||
|
dismiss: () => boolean,
|
||||||
navigate: (
|
navigate: (
|
||||||
routeName: string,
|
routeName: string,
|
||||||
params?: NavigationParams,
|
params?: NavigationParams,
|
||||||
|
@ -6,6 +6,32 @@ const dummyEventSubscriber = (name: string, handler: (*) => void) => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('addNavigationHelpers', () => {
|
describe('addNavigationHelpers', () => {
|
||||||
|
it('handles dismiss action', () => {
|
||||||
|
const mockedDispatch = jest
|
||||||
|
.fn(() => false)
|
||||||
|
.mockImplementationOnce(() => true);
|
||||||
|
const child = { key: 'A', routeName: 'Home' };
|
||||||
|
expect(
|
||||||
|
addNavigationHelpers({
|
||||||
|
state: child,
|
||||||
|
dispatch: mockedDispatch,
|
||||||
|
addListener: dummyEventSubscriber,
|
||||||
|
carefullyGetParent: () => ({
|
||||||
|
state: {
|
||||||
|
key: 'P',
|
||||||
|
routeName: 'Parent',
|
||||||
|
routes: [child],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}).dismiss()
|
||||||
|
).toEqual(true);
|
||||||
|
expect(mockedDispatch).toBeCalledWith({
|
||||||
|
type: NavigationActions.BACK,
|
||||||
|
key: 'P',
|
||||||
|
});
|
||||||
|
expect(mockedDispatch.mock.calls.length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
it('handles Back action', () => {
|
it('handles Back action', () => {
|
||||||
const mockedDispatch = jest
|
const mockedDispatch = jest
|
||||||
.fn(() => false)
|
.fn(() => false)
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
import NavigationActions from './NavigationActions';
|
import NavigationActions from './NavigationActions';
|
||||||
import invariant from './utils/invariant';
|
import invariant from './utils/invariant';
|
||||||
|
|
||||||
export default function(navigation) {
|
export default function(navigation) {
|
||||||
return {
|
return {
|
||||||
...navigation,
|
...navigation,
|
||||||
|
// Go back from the given key, default to active key
|
||||||
goBack: key => {
|
goBack: key => {
|
||||||
let actualizedKey = key;
|
let actualizedKey = key;
|
||||||
if (key === undefined && navigation.state.key) {
|
if (key === undefined && navigation.state.key) {
|
||||||
@ -19,6 +19,18 @@ export default function(navigation) {
|
|||||||
NavigationActions.back({ key: actualizedKey })
|
NavigationActions.back({ key: actualizedKey })
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
// Go back from the parent key. If this is a nested stack, the entire
|
||||||
|
// stack will be dismissed.
|
||||||
|
dismiss: () => {
|
||||||
|
let parent = navigation.carefullyGetParent();
|
||||||
|
if (parent && parent.state) {
|
||||||
|
return navigation.dispatch(
|
||||||
|
NavigationActions.back({ key: parent.state.key })
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
navigate: (navigateTo, params, action) => {
|
navigate: (navigateTo, params, action) => {
|
||||||
if (typeof navigateTo === 'string') {
|
if (typeof navigateTo === 'string') {
|
||||||
return navigation.dispatch(
|
return navigation.dispatch(
|
||||||
|
@ -32,6 +32,10 @@ function createNavigator(NavigatorView, router, navigationConfig) {
|
|||||||
return route === focusedRoute;
|
return route === focusedRoute;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_carefullyGetParent = () => {
|
||||||
|
return this.props.navigation;
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { navigation, screenProps } = this.props;
|
const { navigation, screenProps } = this.props;
|
||||||
const { dispatch, state, addListener } = navigation;
|
const { dispatch, state, addListener } = navigation;
|
||||||
@ -52,9 +56,11 @@ function createNavigator(NavigatorView, router, navigationConfig) {
|
|||||||
const childNavigation = addNavigationHelpers({
|
const childNavigation = addNavigationHelpers({
|
||||||
dispatch,
|
dispatch,
|
||||||
state: route,
|
state: route,
|
||||||
|
carefullyGetParent: this._carefullyGetParent,
|
||||||
addListener: this.childEventSubscribers[route.key].addListener,
|
addListener: this.childEventSubscribers[route.key].addListener,
|
||||||
isFocused: () => this._isRouteFocused(route),
|
isFocused: () => this._isRouteFocused(route),
|
||||||
});
|
});
|
||||||
|
|
||||||
const options = router.getScreenOptions(childNavigation, screenProps);
|
const options = router.getScreenOptions(childNavigation, screenProps);
|
||||||
descriptors[route.key] = {
|
descriptors[route.key] = {
|
||||||
key: route.key,
|
key: route.key,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user