From d9c0b507e0444f6fbf61d3daa4366c03d6823566 Mon Sep 17 00:00:00 2001 From: Brett Higgins Date: Tue, 4 Dec 2018 09:00:48 -0500 Subject: [PATCH] Update NavigationService example for v3 I am trying to follow these two doc pages in conjunction: - https://reactnavigation.org/docs/en/app-containers.html - https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html Though the "Navigating without the navigation prop" seems out of date since the introduction of explicit app containers in v3, the **App Containers** page indicates that I can get a ref on the _container_ that functions just like a navigator. After a couple of false starts, I stumbled upon what seems to be the correct setup, but it would have been helpful to start from a working example without having to infer the correct combination. My minimal working example: https://snack.expo.io/@brettdh/navigationservice-and-createappcontainer Possibly related: react-navigation/react-navigation#5252 --- docs/navigating-without-navigation-prop.md | 7 +- .../navigating-without-navigation-prop.md | 78 +++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 website/versioned_docs/version-3.x/navigating-without-navigation-prop.md diff --git a/docs/navigating-without-navigation-prop.md b/docs/navigating-without-navigation-prop.md index 7a6bc43e387..7fb78272879 100644 --- a/docs/navigating-without-navigation-prop.md +++ b/docs/navigating-without-navigation-prop.md @@ -11,16 +11,19 @@ You can get access to a navigator through a `ref` and pass it to the `Navigation ```javascript // App.js +import { createStackNavigator, createAppContainer } from 'react-navigation'; import NavigationService from './NavigationService'; const TopLevelNavigator = createStackNavigator({ /* ... */ }) -class App extends React.Component { +const AppContainer = createAppContainer(TopLevelNavigator); + +export default class App extends React.Component { // ... render() { return ( - { NavigationService.setTopLevelNavigator(navigatorRef); }} diff --git a/website/versioned_docs/version-3.x/navigating-without-navigation-prop.md b/website/versioned_docs/version-3.x/navigating-without-navigation-prop.md new file mode 100644 index 00000000000..22328baad9e --- /dev/null +++ b/website/versioned_docs/version-3.x/navigating-without-navigation-prop.md @@ -0,0 +1,78 @@ +--- +id: version-3.x-navigating-without-navigation-prop +title: Navigating without the navigation prop +sidebar_label: Navigating without the navigation prop +original_id: navigating-without-navigation-prop +--- + +Calling functions such as `navigate` or `popToTop` on the `navigation` prop is not the only way to navigate around your app. As an alternative, you can dispatch navigation actions on your top-level navigator, provided you aren't passing your own `navigation` prop as you would with a redux integration. The presented approach is useful in situations when you want to trigger a navigation action from places where you do not have access to the `navigation` prop, or if you're looking for an alternative to using the `navigation` prop. + +You can get access to a navigator through a `ref` and pass it to the `NavigationService` which we will later use to navigate. Use this only with the top-level (root) navigator of your app. + +```javascript +// App.js + +import { createStackNavigator, createAppContainer } from 'react-navigation'; +import NavigationService from './NavigationService'; + +const TopLevelNavigator = createStackNavigator({ /* ... */ }) + +const AppContainer = createAppContainer(TopLevelNavigator); + +export default class App extends React.Component { + // ... + + render() { + return ( + { + NavigationService.setTopLevelNavigator(navigatorRef); + }} + /> + ); + } +} +``` + +In the next step, we define `NavigationService` which is a simple module with functions that dispatch user-defined navigation actions. + +```javascript +// NavigationService.js + +import { NavigationActions } from 'react-navigation'; + +let _navigator; + +function setTopLevelNavigator(navigatorRef) { + _navigator = navigatorRef; +} + +function navigate(routeName, params) { + _navigator.dispatch( + NavigationActions.navigate({ + routeName, + params, + }) + ); +} + +// add other navigation functions that you need and export them + +export default { + navigate, + setTopLevelNavigator, +}; +``` + +Then, in any of your javascript modules, just import the `NavigationService` and call functions which you exported from it. You may use this approach outside of your React components and, in fact, it works just as well when used from within them. + +```javascript +// any js module +import NavigationService from 'path-to-NavigationService.js'; + +// ... + +NavigationService.navigate('ChatScreen', { userName: 'Lucy' }); +``` + +In `NavigationService`, you can create your own navigation actions, or compose multiple navigation actions into one, and then easily reuse them throughout your application. When writing tests, you may mock the navigation functions, and make assertions on whether the correct functions are called, with the correct parameters.