I’m trying to get React Navigation to play with me. I get the navigation to work, but am a bit confused about how to stop shadow-cljs reload to not rerender the navigation stack. Right now if I navigate to the About screen and then rerender the root component (such as happens when I save the file) the Home screen gets rendered. The relevant code (I think):
(defn root []
[:> rnn/NavigationContainer
[:> Stack.Navigator
[:> Stack.Screen {:name "Home"
:component (fn [props] (r/as-element [home props]))
:options {:title "Home"}}]
[:> Stack.Screen {:name "About"
:component (fn [props] (r/as-element [about props]))
:options {:title "About"}}]]])
(defn start
{:dev/after-load true}
[]
(expo-root/render-root (r/as-element [root])))Turns out I can set the initial state of the navigation container. This branch of my example app now has navigation with smooth hot reload: https://github.com/PEZ/rn-rf-shadow/tree/pez/react-navigation Pasting the new root component code here, for easy reference:
(defn root []
;; The save and restore of the navigation root state is for development time bliss
(r/with-let [!root-state (rf/subscribe [:navigation/root-state])
save-root-state! (fn [^js state]
(rf/dispatch [:navigation/set-root-state state]))
add-listener! (fn [^js navigation-ref]
(when navigation-ref
(.addListener navigation-ref "state" save-root-state!)))]
[:> rnn/NavigationContainer {:ref add-listener!
:initialState (when @!root-state (-> @!root-state .-data .-state))}
[:> Stack.Navigator
[:> Stack.Screen {:name "Home"
:component (fn [props] (r/as-element [home props]))
:options {:title "Example App"}}]
[:> Stack.Screen {:name "About"
:component (fn [props] (r/as-element [about props]))
:options {:title "About"}}]]]))
(defn start
{:dev/after-load true}
[]
(expo-root/render-root (r/as-element [root])))