{"_id":"@elie222/ex-navigation","_rev":"1-f5671976b3b45981a4177ab0c15f4a81","name":"@elie222/ex-navigation","dist-tags":{"latest":"5.0.0"},"versions":{"5.0.0":{"name":"@elie222/ex-navigation","version":"5.0.0","description":"Route-centric navigation library for React Native.","main":"./src/ExNavigation.js","public":true,"scripts":{"lint":"eslint ./src ./example","test":"echo \"Error: no test specified\" && exit 1"},"repository":{"type":"git","url":"git+https://github.com/elie222/ex-navigation.git"},"keywords":["react-native","navigation","expo","react"],"author":{"name":"Adam Miskiewicz","email":"adam@exponentjs.com"},"license":"MIT","peerDependencies":{},"dependencies":{"@expo/react-native-touchable-native-feedback-safe":"^1.1.0","clamp":"^1.0.1","core-decorators":"^0.12.2","fbemitter":"^2.0.2","fbjs":"^0.8.3","hoist-non-react-statics":"^1.0.5","invariant":"^2.2.1","lodash":"^4.6.1","mirror-creator":"^1.1.0","prop-types":"^15.5.10","react-addons-pure-render-mixin":"^15.5.2","react-addons-shallow-compare":"15.5.2","react-clone-referenced-element":"^1.0.1","react-mixin":"^3.0.5","react-native-drawer-layout-polyfill":"^1.1.0","react-native-tab-view":"^0.0.65","react-redux":"^5.0.6","react-static-container":"^1.0.0","react-timer-mixin":"^0.13.3","redux":"^3.5.2","redux-batched-actions":"^0.1.2","reselect":"^2.5.1","uuid-js":"^0.7.5","warning":"^2.1.0"},"devDependencies":{"babel-eslint":"^7.1.1","eslint":"^3.12.2","eslint-config-expo":"^5.1.3","eslint-plugin-babel":"^4.0.0","eslint-plugin-flowtype":"^2.30.0","eslint-plugin-import":"^2.2.0","eslint-plugin-react":"^6.8.0","flow-bin":"^0.30.0","react":"~15.4.2","react-native":"https://github.com/exponent/react-native/archive/sdk-15.0.0.tar.gz"},"gitHead":"5f5d2503053f61250ce6099de7e3d275bd597e5c","bugs":{"url":"https://github.com/elie222/ex-navigation/issues"},"homepage":"https://github.com/elie222/ex-navigation#readme","_id":"@elie222/ex-navigation@5.0.0","_nodeVersion":"10.1.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-TgySYjZfQklRxTEuZDzjb7lpiC39OtIpx/OvyWedZhPeipR3lw3Q+HIJZGKP0Mxz1BGHtGSN5seaGxH9AsJBYQ==","shasum":"a221c2afaa9c584f1ceff15dc7084576d60f9640","tarball":"https://registry.npmjs.org/@elie222/ex-navigation/-/ex-navigation-5.0.0.tgz","fileCount":71,"unpackedSize":298079,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdDKkBCRA9TVsSAnZWagAAlwMQAKQDFjMuAuyhLcyKeZX+\nMipG+Gm3oqNxL/ML5nECxuxnCH8OEkvlEkpwVP1XDfngLNx9xHUKB+vjHNJt\nZDzFV1y/oc0olKdUdHD0iGfgFYXMiqUSd5NxqiAXaCuqxIInAJhevV8cBrI7\nYfGVcnAn1smFGhF7lXl7EGg9NCzbUxvAQIW5LsxGgmoSDcs3e1zlYzOjVqk4\nagNV84Smjllv37hSnyUyaER3zOxR94Nb9fM/96Il6E6kigFpuiziewUF56Zt\nujeO/7gI7MxBKEfx3uCSkUqZTwKOEVAPhLFfcPp5s13YjMeL/9qA5PwKFaVh\nm1on6kSkVr+5FC3IvKI9A33ALDlwKhHUnXEGXb5zo24mYeD/51jdIuO76jML\nyZ1OSIIfq++L03Bh8hD3R4mbQHWLyO7b8HmWZPl6yaCAbOno5yzlL76IPujg\nvdNWvNk0Vsx4nbkjNDXsIKv7yz09G6IvcRyy5uZa55pHbvLZiH2mSSs5lN0A\n6ONPIJPe0/8mFhheUvFgKnh3hybdbwOdMV0O8SR3fwgGjTHhF+dw5R+gELuU\nFDwFi2B2yBsblYuAhhU23Fny0zBnlOlxtjgbvOFYLYOgE2pWEeKy57RphDYR\ntsMDTrgiPPR9OOuSmp1DCYq2URyEqe4Rh9ZhX/6yU1O9BHshq9DV9siYfqD8\nZEZL\r\n=oyXz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC8Z3PD6+1W2evHA8Mlk5g6ZmezaJzJfnyY8X2GI3heKwIhAMOr90R3PWRI+K2hDbI1z4dWI/o6t4DYo8LNSZ9O5pjU"}]},"maintainers":[{"name":"elie222","email":"hi@elie.tech"}],"_npmUser":{"name":"elie222","email":"hi@elie.tech"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ex-navigation_5.0.0_1561110784525_0.9984547731040199"},"_hasShrinkwrap":false}},"time":{"created":"2019-06-21T09:53:04.492Z","5.0.0":"2019-06-21T09:53:04.822Z","modified":"2022-04-05T07:11:42.941Z"},"maintainers":[{"name":"elie222","email":"hi@elie.tech"}],"description":"Route-centric navigation library for React Native.","homepage":"https://github.com/elie222/ex-navigation#readme","keywords":["react-native","navigation","expo","react"],"repository":{"type":"git","url":"git+https://github.com/elie222/ex-navigation.git"},"author":{"name":"Adam Miskiewicz","email":"adam@exponentjs.com"},"bugs":{"url":"https://github.com/elie222/ex-navigation/issues"},"license":"MIT","readme":"\n\n# 🚨This library is no longer maintained 🚨\n\nPlease use [\"react-navigation\"](https://github.com/react-navigation/react-navigation), or [other alternatives](https://reactnavigation.org/docs/en/alternatives.html) instead.\n\n----------------------------------------------------\n\n## ExNavigation\n\nA route-centric, batteries-included navigation library for Expo and\nReact Native that works seamlessly on Android and iOS.\n\n### A few of our favorite features\n\n- Android back button handling (it just works, no need to do anything)\n- Tab bar navigation\n- Drawer navigation\n- Sliding tab navigation\n- Optional blurred translucent backgrounds in navigation and tab bar on iOS\n- Alert bars\n- Declarative configuration co-located with your routes\n- Typed with Flow\n\n## Help / Support / Questions\n\nWe don't provide any realtime support for ExNavigation questions. If you\njoin the Expo Slack and ask a question there, we will direct you to\nthis section of the README. We suggest the following resources:\n\n- Search the README.\n- [Search the issues, then post an issue if nothing matches](https://github.com/expo/ex-navigation/issues).\n- Search the code if nothing else works.\n- Once you solve your problem, submit a pull request to add the solution to the README.\n\n## Installation\n\nAs of version 1.9.0, ExNavigation only supports React Native versions >=\n0.36.0 due to changes to the css-layout algorithm in React Native core.\n\n\n- `npm i @expo/ex-navigation babel-preset-react-native-stage-0 --save`\n- Change your `.babelrc` (if you have one, if not, then create one):\n\n```\n{\n  \"presets\": [\"react-native-stage-0/decorator-support\"]\n}\n```\n\n---\n\n*__Note:__ Comprehensive documentation is coming soon! For now, check out the example project in `example/`. This lib is very much a work in progress.*\n\n\n## How to run the example project\n\n- `cd example && npm install`\n- [Install the Expo client and XDE](https://docs.expo.io/versions/latest/introduction/installation.html)\n- Open the project in XDE and open it in the Exponent client\n\nor use this link in your mobile phone: https://expo.io/@community/ex-navigation-example\n\n## How is this different from what is built into React Native?\n\n`NavigationExperimental` ships with React Native, it is powerful and\nflexible, and that comes at the cost of exposing some internals to the\napp developer. ExNavigation is built on top of `NavigationExperimental`\nwith the aim of providing a more feature-rich out of the box experience.\n\n## A minimal navigation set up\n\nTo give you an idea of what the required pieces of are, the following\nincludes only the minimal code necessary to get ExNavigation working.\n\n```javascript\nimport React from 'react';\nimport {\n  AppRegistry,\n  Text,\n  View,\n} from 'react-native';\n\n/**\n * If you're using Expo, uncomment the line below to import Exponent\n * BEFORE importing `@expo/ex-navigation`. This sets the status bar\n * offsets properly.\n */\n// import Expo from 'expo';\n\nimport {\n  createRouter,\n  NavigationProvider,\n  StackNavigation,\n} from '@expo/ex-navigation';\n\n/**\n  * This is where we map route names to route components. Any React\n  * component can be a route, it only needs to have a static `route`\n  * property defined on it, as in HomeScreen below\n  */\nconst Router = createRouter(() => ({\n  home: () => HomeScreen,\n}));\n\nclass App extends React.Component {\n  render() {\n    /**\n      * NavigationProvider is only needed at the top level of the app,\n      * similar to react-redux's Provider component. It passes down\n      * navigation objects and functions through context to children.\n      *\n      * StackNavigation represents a single stack of screens, you can\n      * think of a stack like a stack of playing cards, and each time\n      * you add a screen it slides in on top. Stacks can contain\n      * other stacks, for example if you have a tab bar, each of the\n      * tabs has its own individual stack. This is where the playing\n      * card analogy falls apart, but it's still useful when thinking\n      * of individual stacks.\n      */\n    return (\n      <NavigationProvider router={Router}>\n        <StackNavigation initialRoute={Router.getRoute('home')} />\n      </NavigationProvider>\n    );\n  }\n}\n\nclass HomeScreen extends React.Component {\n  /**\n    * This is where we can define any route configuration for this\n    * screen. For example, in addition to the navigationBar title we\n    * could add backgroundColor.\n    */\n  static route = {\n    navigationBar: {\n      title: 'Home',\n    }\n  }\n\n  render() {\n    return (\n      <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>\n        <Text>HomeScreen!</Text>\n      </View>\n    )\n  }\n}\n\n\nAppRegistry.registerComponent('main', () => App);\n```\n\n## Push and popping routes\n\n```diff\n const Router = createRouter(() => ({\n   home: () => HomeScreen,\n+  about: () => AboutScreen,\n }));\n\n class HomeScreen extends React.Component {\n    render() {\n     return (\n       <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>\n         <Text>HomeScreen!</Text>\n+        <Text onPress={this._goToAbout}>\n+          Push about route\n+        </Text>\n       </View>\n     )\n   }\n+\n+  _goToAbout = () => {\n+    this.props.navigator.push(Router.getRoute('about'));\n+  }\n }\n\n+ class AboutScreen extends React.Component {\n+  static route = {\n+    navigationBar: {\n+      title: 'About',\n+    }\n+  }\n+\n+  render() {\n+    return (\n+      <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>\n+        <Text>AboutScreen!</Text>\n+        <Text onPress={this._goBackHome}>\n+          Go back home\n+        </Text>\n+      </View>\n+    )\n+  }\n+\n+  _goBackHome = () => {\n+    this.props.navigator.pop();\n+  }\n+}\n```\n\nIn the above example you will see that we `push` and `pop` routes to and\nfrom the stack by calling those functions on the `navigator` prop. This\nis a prop that is passed into all components that you registered with\nthe router. If you need to access the `navigator` on a component that\nis not a route, you can either pass it in manually from your route\ncomponent or use `withNavigation` as a decorator on the component:\n\n```javascript\nimport React from 'react';\nimport { Text } from 'react-native';\nimport { withNavigation } from '@expo/ex-navigation';\n\n@withNavigation\nclass BackButton extends React.Component {\n  render() {\n    return <Text onPress={this._goBack}>Go back</Text>\n  }\n\n  _goBack = () => {\n    if (this.props.navigator.getCurrentIndex() > 0) {\n      this.props.navigator.pop();\n    }\n  }\n}\n```\n\nAlternatively, rather than importing `Router` each time, you may pass the\nroute's name directly:\n\n```diff\n_goToAbout = () => {\n-  this.props.navigator.push(Router.getRoute('about'));\n+  this.props.navigator.push('about');\n}\n```\n\n… bearing in mind you will loose the ability to type check the route (if using\nFlow).\n\n## Passing params to a route\n\n```diff\n  class HomeScreen extends React.Component {\n\n   _goToAbout = () => {\n-    this.props.navigator.push(Router.getRoute('about'));\n+    this.props.navigator.push(Router.getRoute('about', {name: 'Brent'}));\n   }\n }\n\n class AboutScreen extends React.Component {\n   static route = {\n     navigationBar: {\n-      title: 'About',\n+      title(params) {\n+        return `Greeting for ${params.name}`;\n+      },\n     }\n   }\n\n   render() {\n     return (\n       <View style={{alignItems: 'center', justifyContent: 'center', flex: 1}}>\n-        <Text>AboutScreen!</Text>\n+        <Text>AboutScreen! Hello {this.props.route.params.name}</Text>\n         <Text onPress={this._goBackHome}>\n           Go back home\n         </Text>\n```\n\n## Updating route params\n\nSometimes you don't have all of the data that you need to set the\nnavigation bar title when you mount the route - for example, if you\nnavigate to a user profile screen by user id and need to fetch the\nprofile data before you know what the name is. In this case,\none solution is to use the `updateCurrentRouteParams` function available\non `StackNavigation` navigators.\n\n```diff\n class AboutScreen extends React.Component {\n   static route = {\n     navigationBar: {\n       title(params) {\n-        return `Greeting for ${params.name}`;\n+        if (typeof params.isCool === 'undefined') {\n+          return '';\n+        }\n+\n+        return params.isCool ? `Hey cool person!` : `zzz`;\n       },\n     }\n   }\n\n+  componentDidMount() {\n+    setTimeout(() => {\n+      this.props.navigator.updateCurrentRouteParams({\n+        isCool: this.props.route.params.name === 'Brent'\n+      })\n+    }, 1000);\n+  }\n+\n```\n\n### Make navigation bar buttons update based on route or app state\n\nSee the following example for details on how to connect your buttons to\nthe navigator or Redux to perform actions: https://github.com/brentvatne/ex-navigation-conditional-buttons-example\n\n## StackNavigation actions\n\nAs you saw above, you can `push` and `pop` routes. The following is a\nfull list of functions that can be called on StackNavigation navigators.\n\n- `push`: add a route to the top of the stack\n- `pop(n)`: remove n routes from the top of the stack, defaults to 1\n- `popToTop`: remove all but the first route from the stack\n- `replace`: replace the current route with a given route\n- `showLocalAlert`: show an alert bar with given text and styles\n- `hideLocalAlert`: hide an active alert bar\n- `immediatelyResetStack`: reset the current stack to the given stack\n- `updateCurrentRouteParams`: update route params as in the above example\n\n## Working with the navigation bar\n\nThe navigation bar configuration exposes a set of useful options that\nshould allow you to do most things that you will want to do with it.\n\nYou specify the configuration for the `navigationBar` on the route\ncomponent, or on a `StackNavigation` component.\n\n### On a route component\n\nWhen you configure the `navigationBar` on a route component, the\nconfiguration only applies to that specific component. This is\nusually useful for specifying the title or components to render\non the left or right of the title.\n\n```javascript\n\n class HomeScreen extends React.Component {\n   _goToAbout = () => {\n     this.props.navigator.push(Router.getRoute('about', {name: 'Brent'}));\n   }\n }\n\n class AboutScreen extends React.Component {\n   static route = {\n     navigationBar: {\n       title: 'Title goes here',\n       renderRight: (route, props) => <SignOutButton name={route.params.name} />\n     }\n   }\n\n   // ...\n }\n\n @connect()\n class SignOutButton extends React.Component {\n   render() {\n      return (\n        <TouchableOpacity onPress={this.props.dispatch(Actions.signOut())}>\n          <Text>Sign out {this.props.name}</Text>\n        </TouchableOpacity>\n      );\n   }\n }\n```\n\n### On StackNavigation\n\nYou can configure the `defaultRouteConfig` for all routes within a\n`StackNavigation` to save you needing to specify properties like\nthe `navigationBar` `backgroundColor` and `tintColor` (color to\nuse for the title and back button or drawer menu hamburger button).\n\n```javascript\nclass App extends React.Component {\n  render() {\n    return (\n      <NavigationProvider router={Router}>\n        <StackNavigation\n          defaultRouteConfig={{\n            navigationBar: {\n              backgroundColor: '#000',\n              tintColor: '#fff',\n            }\n          }}\n          initialRoute={Router.getRoute('home')}\n        />\n      </NavigationProvider>\n    );\n  }\n}\n```\n\n### navigationBar properties\n\n- `title` - a string or a function that returns a string. The function is provided with the route params as the first argument.\n- `titleStyle` - Text.propTypes.style object to use for the title.\n- `backgroundColor` - the background color to use for the\n`navigationBar`.\n- `tintColor` - the color to use for the title text and back button or\ndrawer button icons.\n- `visible` - boolean that indicates whether the `navigationBar` should\nbe visible for this route.\n- `translucent` - iOS and Expo only, use background blur on the\n`navigationBar`, like in the Apple Podcasts app, for example.\n- `borderBottomWidth` - the width of the bottom border\n- `borderBottomColor` - the color of the bottom border\n- `renderLeft` - a function that should return a React component that\nwill be rendered in the left position of the `navigationBar`.\n- `renderTitle` - a function that should return a React component that\nwill be rendered in the title position of the `navigationBar`.\n- `renderRight` - a function that should return a React component that\nwill be rendered in the right position of the `navigationBar`.\n- `renderBackground` - a function that should return a React component that\nwill be rendered in the background of the `navigationBar`.\n\n## TabNavigation\n\nA minimal example using tabs:\n\n```javascript\nimport {\n  StackNavigation,\n  TabNavigation,\n  TabNavigationItem as TabItem,\n} from '@expo/ex-navigation';\n\n\n// Treat the TabScreen route like any other route -- you may want to set\n// it as the initial route for a top-level StackNavigation\nclass TabScreen extends React.Component {\n  static route = {\n    navigationBar: {\n      visible: false,\n    }\n  }\n\n  render() {\n    return (\n      <TabNavigation\n        id=\"main\"\n        navigatorUID=\"main\"\n        initialTab=\"home\">\n        <TabItem\n          id=\"home\"\n          title=\"Home\"\n          selectedStyle={styles.selectedTab}\n          renderIcon={(isSelected) => <Image source={require('./assets/images/home.png')} /> }>\n          <StackNavigation\n            id=\"home\"\n            navigatorUID=\"home\"\n            initialRoute={Router.getRoute('home')}\n          />\n        </TabItem>\n\n        <TabItem\n          id=\"posts\"\n          title=\"Posts\"\n          selectedStyle={styles.selectedTab}\n          renderIcon={(isSelected) => <Image source={require('./assets/images/posts.png')} /> }>\n          <StackNavigation\n            id=\"posts\"\n            initialRoute={Router.getRoute('posts')}\n          />\n        </TabItem>\n\n        <TabItem\n          id=\"profile\"\n          title=\"Profile\"\n          selectedStyle={styles.selectedTab}\n          renderIcon={(isSelected) => <Image source={require('./assets/images/profile.png')} /> }>\n          <StackNavigation\n            id=\"profile\"\n            initialRoute={Router.getRoute('profile')}\n          />\n        </TabItem>\n      </TabNavigation>\n    );\n  }\n}\n```\n\nSee an example of TabNavigation in a real app\n[here](https://github.com/expo/rnplay/blob/f4d29c4578fb57347afd0d507a036dd232ec6fdb/navigation/TabNavigationLayout.js).\n\nIf you'd like to switch tabs programmatically (eg: a notification\narrives and you want to jump to a notifications tab, or you tap on a\nbutton to open your profile but within another tab) you can use\n`jumpToTab`. For the code below to work, we need the `navigatorUID` prop\nto be set on TabNavigator, as with the example above.\n\n```javascript\n<TouchableOpacity\n  onPress={() => {\n    this.props.navigation.performAction(({ tabs, stacks }) => {\n      tabs('main').jumpToTab('profile');\n      stacks('home').push(route);\n    });\n  }}\n/>\n```\n\n## DrawerNavigation\n\nA minimal example using the DrawerNavigation:\n\n```javascript\nimport {\n  StackNavigation,\n  DrawerNavigation,\n  DrawerNavigationItem,\n} from '@expo/ex-navigation';\n\n// Treat the DrawerNavigationLayout route like any other route -- you may want to set\n// it as the intiial route for a top-level StackNavigation\n\nclass DrawerNavigationLayout extends React.Component {\n  static route = {\n    navigationBar: {\n      visible: false,\n    }\n  };\n\n  render() {\n    return (\n      <DrawerNavigation\n        id='main'\n        initialItem='home'\n        drawerWidth={300}\n        renderHeader={this._renderHeader}\n      >\n        <DrawerNavigationItem\n          id='home'\n          selectedStyle={styles.selectedItemStyle}\n          renderTitle={isSelected => this._renderTitle('Home', isSelected)}\n        >\n          <StackNavigation\n            id='home'\n            initialRoute={Router.getRoute('home')}\n          />\n        </DrawerNavigationItem>\n\n        <DrawerNavigationItem\n          id='about'\n          selectedStyle={styles.selectedItemStyle}\n          renderTitle={isSelected => this._renderTitle('About', isSelected)}\n        >\n          <StackNavigation\n            id='about'\n            initialRoute={Router.getRoute('about')}\n          />\n        </DrawerNavigationItem>\n\n      </DrawerNavigation>\n    );\n  }\n\n  _renderHeader = () => {\n    return (\n      <View style={styles.header}>\n      </View>\n    );\n  };\n\n  _renderTitle(text: string, isSelected: boolean) {\n    return (\n      <Text style={[styles.titleText, isSelected ? styles.selectedTitleText : {}]}>\n        {text}\n      </Text>\n    );\n  };\n}\n\nconst styles = StyleSheet.create({\n  header: {\n    height: 20\n  },\n\n  selectedItemStyle: {\n    backgroundColor: 'blue'\n  },\n\n  titleText: {\n    fontWeight: 'bold'\n  },\n\n  selectedTitleText: {\n    color: 'white'\n  }\n});\n```\n\n\n### Integrate with your existing Redux store\n\nBehind the scenes ExNavigation manages your navigation state using\nRedux in its own store. If you'd like to store the navigation state\non your app's store, you can use the `createStoreWithNavigation`\nfunction when creating the store and then manually provide the\n`NavigationContext`, initialized with your app's store.\n\n```javascript\n/* Your store definition, let's say state/Store.js */\n\nimport { createNavigationEnabledStore, NavigationReducer } from '@expo/ex-navigation';\nimport { combineReducers, createStore } from 'redux';\n\nconst createStoreWithNavigation = createNavigationEnabledStore({\n  createStore,\n  navigationStateKey: 'navigation',\n});\n\nconst store = createStoreWithNavigation(\n  /* combineReducers and your normal create store things here! */\n  combineReducers({\n    navigation: NavigationReducer,\n    // other reducers\n  })\n);\n\nexport default store;\n```\n\n```javascript\n/* Your routes, Router.js */\n\nimport { createRouter } from '@expo/ex-navigation';\nimport HomeScreen from './HomeScreen';\n\nexport const Router = createRouter(() => ({\n  home: () => HomeScreen,\n}));\n```\n\n```diff\n /* The top level of your app, often in main.js or index.[ios/android].js */\n\n import {\n   NavigationContext,\n   NavigationProvider,\n   StackNavigation,\n } from '@expo/ex-navigation';\n\n import Store from './state/Store';\n import Router from './Router';\n\n+const navigationContext = new NavigationContext({\n+  router: Router,\n+  store: Store,\n+})\n\n return (\n   <Provider store={Store}>\n+    <NavigationProvider context={navigationContext}>\n       <StackNavigation yourUsualPropsHere />\n     </NavigationProvider>\n   </Provider>\n )\n```\n\n### Perform navigation actions from outside of a component\n\nYou might be using some Redux middleware like saga, thunk, promise, or\neffex (we recommend [effex](https://github.com/expo/redux-effex)\nbecause we love `async/await`). Whatever you're using, you no longer\nhave access to `this.props.navigator` and the like. What to do?\nWell as long as you include your navigation state inside of your Redux\nstore, you can dispatch a NavigationAction to it -- after all, this is\nwhat `this.props.navigator.push` etc. do behind the scenes.\n\nIn the following example we call `getState` and `dispatch` directly on\nyour store -- feel free to change this to whatever the equivalent is\nfor your context (eg: if this was effex, `dispatch` and `getState` would\nbe passed in to the `goHome` function).\n\n```javascript\nimport { NavigationActions } from '@expo/ex-navigation'\nimport Store from '../state/Store';\nimport Router from './Router'\n\nexport default function goHome() {\n  let navigatorUID = Store.getState().navigation.currentNavigatorUID;\n  Store.dispatch(NavigationActions.push(navigatorUID, Router.getRoute('home')))\n}\n```\n\n### Screen Tracking / Analytics\n\nYou might want to do some screen tracking in your apps. Since the entire navigation state is in redux, screen tracking is as simple as writing a redux middleware. Below is a simple middleware that uses `routeName` as the screen name for tracking screens.\n\n```javascript\nimport SegmentIO from 'react-native-segment-io-analytics';\n\nconst navigationStateKey = 'navigation';\n\n// gets the current screen from navigation state\nfunction getCurrentScreen(getStateFn) {\n  const navigationState = getStateFn()[navigationStateKey];\n  // navigationState can be null when exnav is initializing\n  if (!navigationState) return null;\n\n  const { currentNavigatorUID, navigators } = navigationState;\n  if (!currentNavigatorUID) return null;\n\n  const { index, routes } = navigators[currentNavigatorUID];\n  const { routeName } = routes[index];\n  return routeName;\n}\n\nconst screenTracking = ({ getState }) => next => action => {\n  if (!action.type.startsWith('EX_NAVIGATION')) return next(action);\n  const currentScreen = getCurrentScreen(getState);\n  const result = next(action);\n  const nextScreen = getCurrentScreen(getState);\n  if (nextScreen !== currentScreen) {\n    SegmentIO.screen(nextScreen);\n  }\n  return result;\n}\n\nexport default screenTracking;\n\n```\n\n### Android back button handling\n\nReact Native includes a global `BackHandler` module. Rather than using this module\ndirectly, include the `AndroidBackButtonBehavior` component in routes where you'd\nlike to control the back button. `AndroidBackButtonBehavior` accepts\n`isFocused` and `onBackButtonPress`. If `isFocused` is true, the `onBackButtonPress`\nwill fire when the user presses the back button. You need to make sure that `onBackButtonPress`\nreturns a promise that wraps the function you want to be called. Eg.\n\n```\n<AndroidBackButtonBehavior isFocused={someboolean}\n   onBackButtonPress={()=>Promise.resolve(fireMeWhenSomeBooleanIsTrue)}>\n   ...\n</AndroidBackButtonBehavior>\n```\n","readmeFilename":"README.md"}