React Native lets us render views but doesn't solve the problem of transitioning between scenes.
Navigation concerns include:
- rendering common elements (headers)
- rendering navigation elements (back button)
- keeping track of global history stack
- navigating between scenes
- animations when moving between scenes
- hiding the keyboard when navigating
- debouncing
- opening / closing the drawere
We're using React Navigation v1.5 as it's intended to be used which means some tradeoffs.
- We won't be storing navigation state in the app-db
- We will navigate without the navigation prop to which requires a little trickery access to the top level navigator
- We hardcode our routes in the top level routing component to keep things simple
- We will hold off on seantempesta/cljs-react-navigation until we see if the basic interop is enough.
Unanswered / unresolved
- How subscriptions can include navigation state data. We could use state navigator.addListeners to act on focus/blur events.
- Including a drawer menu using DrawerNavigator.
- React Navigation v2 became stable yesterday(!) so needs a review of breaking changes and update as necessary.
- Sprinkling clj->js and js->clj on utils
Firstly we need to update our packages.json to include a new depencency
yarn add react-navigation
Updates to rn-api to give us access to the navigation api.
The re-frame integration will be based on some helper functions. These don't yet take care of interop so our code can work with standard clojure data structures.
Our event handlers will use effects to cause navigation changes.
To see the navigation state, event handlers can use a co-effect.
React Navigation works as a top level component configured with routing details. Each new route will need to be added here. We get a ref to the navigator when the top level navigation component is rendered. We use a SwitchNavigator for authentication flows and a StackNavigator for application routes.
And we replace the default re-natal app-root with our new one from navigation-component.
Note: we're keeping the future-app.ios.core/app-root var because the figwheel reloading mechanism uses it.
We prefer specific events handlers which involve navigation instead of generic use handlers which would tempt us to put behaviour directly in our views.
We do add an empty :app/navigation-ready event to allow initialisation work to be done after the navigator is ready.