-
Notifications
You must be signed in to change notification settings - Fork 0
Introduction
This repository shows how to use Keechma with React Native (and re-natal) and shows off some of the more advanced functionality that Keechma enables.
This project is a work in progress, and it aims to be a kitchen-sink example of things that are possible with Keechma and React Native.
Here's the demo of the app in it's current state https://www.dropbox.com/s/4tzz5j2yamwi63j/keechma_react_native_routing_animations.mov?dl=0 . Currently it only shows how to transition between pages in React Native app.
Keechma is a route first / route driven app framework. This means that the route is the main source of the application state, or a minimal representation of the app state.
When we were introducing animated transitions to our app we were presented with a few problems:
- We are directly accessing the route from many places in our app
- We wanted to animate transitions between the pages, but we didn't want to change how we work (regarding the point #1)
Accessing route directly is not a problem when you don't have transitions, and it actually makes sense because route change is what powers the Keechma apps. The problem that we had was that changing the route would affect both pages that were in transition (current and next page). It would also cause changes to the contents of app-db
which means that the current page might start unmounting the components since the data wasn't in the app-db
anymore.
The solution was to somehow keep the old version of the app-db
around until the transition is over.
Before I proceed I want to do a quick recap of some parts of Keechma architecture that made the solution possible.
When writing Reagent components with Keechma, you will have two classes of components:
- Components that depend on
app-db
through subscriptions (stateful components) - Components that receive all their data through the arguments (pure components)
In Keechma, each stateful component MUST declare it's dependencies, both on the subscriptions and on the stateful child components. These dependencies are resolved on the application start, and a record that can resolve them is passed as a first argument (usually called ctx
) to a stateful component (through partial application)
(def render [ctx]
[:div "Foo"])
(def component
(keechma.ui-component/constructor {:renderer render
:subscription-deps [:some-subscription]})
This record (ctx
) contains all metadata that's needed for a component to render itself and to communicate with the rest of the app.
As I mentioned before, we wanted to animate transition between the pages, but we didn't want to change how we build the apps.
The solution ended up pretty simple, and I believe it's beautiful in it's execution. We've introduced the router
component that takes care of the transitions. Since it can access all of it's deps (and all of it's deps deps) through the ctx
argument, it will create the two extra versions of the world (including the app-db
) for each of it's child components. One version will be for Panel A
and another for Panel B
, all animations will be performed on these two panels, and it will use the route info to determine when to stop the update on the world copy of each of these panels.
This was possible only because Keechma doesn't allow you to depend on the global subscriptions and components from the UI
I recommend you to check https://github.com/keechma/example-keechma-react-native/blob/master/src/example_rn/components/router.cljs and https://github.com/keechma/example-keechma-react-native/blob/master/src/example_rn/controllers/route_transition.cljs to see how all of this works together.
There is code in there that isn't documented yet, but that is also in progress.