I see that the next react-navigation version to be released will have the useNavigation()
hook, but is there a way in react-navigation@4.x to effectively use this.props.navigation.dispatch()
without having to use this.props
?
I figured out a solution myself based on modifying a recommended approach from the official react-navigation 4.x docs. The approach involves making a navigation "app container" component out of the app's stack navigator and creating a reference to that container. This reference is then used by a mediating navigation services object (here I call it NavigationService
) that can be imported and used anywhere in my codebase.
// App.js
import { createStackNavigator, createAppContainer } from 'react-navigation';
import NavigationService from './NavigationService';
import HomeScreen from "./HomeScreen";
const TopLevelNavigator = createStackNavigator({
...
Home: {
screen: HomeScreen,
defaultNavigationOptions: { gesturesEnabled: isBackGestureEnabled }
}
...
});
const AppContainer = createAppContainer(TopLevelNavigator);
export default class App extends React.Component {
// ...
render() {
return (
<AppContainer
ref={navigatorRef => {
NavigationService.setTopLevelNavigator(navigatorRef);
}}
/>
);
}
}
The dispatching actions I want are defined as follows (here I have methods created for adding to my navigation stack and resetting the navigation stack). (This differs from the react-navigation docs' recommendation; I had to use _navigator.currentNavProp.dispatch()
rather than _navigator.dispatch()
, which didn't exist for me.)
// NavigationService.js
import { NavigationActions, StackActions } from "react-navigation";
var _navigator;
function setTopLevelNavigator(navigatorRef) {
_navigator = navigatorRef;
}
function navigate(routeName, params) {
_navigator.currentNavProp.dispatch(
NavigationActions.navigate({
routeName,
params
})
);
}
function navigationReset(routeName) {
const resetAction = StackActions.reset({
index: 0,
actions: [NavigationActions.navigate({ routeName })]
});
_navigator.currentNavProp.dispatch(resetAction);
}
export default { navigate, navigationReset, setTopLevelNavigator };
And now I can use this in any of my other JavaScript files, whether they are React components or not.
// anyOtherFile.js
import NavigationService from './NavigationService';
...
NavigationService.navigationReset("Home");
// or
NavigationService.navigate("Home");
...