Trying to understand what's going on behind the scenes so I can maybe make my workflow a little better.
I'm working with RN and shadow-cljs in a CIDER repl.
I make a change to my code, the change causes my app to blow up during render so that I must hit r,r
to reload and get it working again. After reloading, my REPL loses connection to the JS environment and any command I type in to the REPL gives me a REPL command timed out.
message.
I have found two ways to get the REPL re-connected. I can either type :cljs/quit
-> (in-ns 'shadow.user)
-> (shadow/repl-runtime-clear)
-> (shadow/repl :app)
and then I'm back in business. That was annoying.
Or, I can close the application from the emulator and then re-open it from the list of apps.
Why would closing and re-opening the app work to get the REPL re-connected but doing a r,r
reload doesn't work? Is this the typical workflow that everyone uses for working with RN/CLJS? It seems tedious.
@ericihli its a bug in react-native in that it doesn't disconnect websockets when reloading the app
so shadow-cljs thinks the "old" app is still running and tries talking to it (but it never replies)
I opened an issue on the RN repo but it was closed due do inactivity for a year or so. nobody cared I guess.
I don't do RN development myself so I didn't follow up on it
The RN issues list is a wild and lawless place
I think I may have just found a solution. Seems to solve my problem in a way I'm happy with. Anyone see any gotchas?
(defn make-reloader
[component]
(let [component-ref (r/atom component)
wrapper (r/create-class
{:render (fn []
(let [component @component-ref]
(if (fn? component)
(component)
component)))
:component-did-mount
(fn []
(.addEventListener
rn/AppState
"change"
(fn [state]
(cond
(= state "background")
(.close @shadow-rn/socket-ref)
(and (= state "active")
(nil? @shadow-rn/socket-ref))
(shadow-rn/ws-connect)))))})]
(rn/AppRegistry.registerComponent "Ezmonic" (fn [] wrapper))
(fn [comp]
(reset! component-ref comp))))
http://facebook.github.io/react-native/docs/appstate.htmlWhen do you use this @ericihli , when the app “times out” when developing Android? Thanks
It's my root component. If you put prints in component-did-mount you'll see the state changes happen on reload.
(defonce reload (make-reloader views/app-container))
(defn ^:dev/after-load start []
(reload views/app-container))
(defn ^:export init []
(start))
Nice