Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Figwheel inferior to Hot Reloading? #58

Open
danielbraun opened this issue Jun 24, 2016 · 11 comments
Open

Figwheel inferior to Hot Reloading? #58

danielbraun opened this issue Jun 24, 2016 · 11 comments

Comments

@danielbraun
Copy link

I'm facing an annoying issue with WebViews.
When using figwheel, each time I save (and thus hot reload the app) all webviews in my app are "refreshed".
It's not the case when using JavaScript react native projects with Hot Reload enabled. The UI tree is updated, and WebViews are not reloading their pages.

re-natal + figwheel + save = web view is refreshing
vanilla react native + hot reload + save = web view is not refreshing

I played around with a google maps examples.
simulator screen shot 24 jun 2016 22 20 34

@pvinis
Copy link

pvinis commented Aug 22, 2016

why was this closed? did you figure it out?

@danielbraun
Copy link
Author

I haven't figured it out.
It's just been a while and no-one commented.
I can re-open it if you're facing it yourself as well.

@danielbraun danielbraun reopened this Aug 24, 2016
@pvinis
Copy link

pvinis commented Aug 24, 2016

I am not facing the same thing, but I am wandering what the differences are on a deeper level, so I thought I would get some extra insight from this issue. but like you said, noone commented.

@carocad
Copy link

carocad commented Mar 22, 2017

@danielbraun just adding myself to this conversation as I am interested as well.

I am facing a similar problem with mapbox's react-native wrapper. Whenever I save the file using Cursive + figwheel + re-natal my whole apps gets refreshed, not just the part that I just changed :(

I am not sure if this is a react-native problem, on my side or on the cljs stack since when I tried developing apps with figwheel in a browser everything worked as expected (no state lost on reload)

@seantempesta
Copy link

seantempesta commented Mar 22, 2017 via email

@carocad
Copy link

carocad commented Mar 29, 2017

@seantempesta I checked it on my phone and it does not look as if the Live Reload is enabled by default.

On the dev menu in my phone it says Enable Live Reload so I guess that means that it is not enabled.

@drapanjanas
Copy link
Owner

Maybe the problem is how figwheel reload callback is implemented in re-natal. There is a reloader component which wrapps the application root component. This component re-renders when cnt ratom changes, which is on each fighweel reload. The intention was to cause component tree startig from app root to re-render if some code reloaded by figwheel. But, it seems, the actual effect is that components are unmounted and mounted again, which causes loosing their internal state.

@carocad
Copy link

carocad commented May 3, 2017

@drapanjanas I think you are correct. After some experiments, I found out that if I keep a reference (through react's ref property) to the component, then I can keep the state even after a reload from figwheel.

I guess the problem is that unlike react, react-native is much more welcoming of internal state (maps components use that a lot) which obviously gets resetted after fighwheel unmounts and remounts the components :(

@carocad
Copy link

carocad commented May 15, 2017

for your interest: here is the blog post from facebook on React Native: https://facebook.github.io/react-native/blog/2016/03/24/introducing-hot-reloading.html

from the blog:

In a nutshell, his solution works by creating a proxy for every single React component on transform time. The proxies hold the component's state and delegate the lifecycle methods to the actual components, which are the ones we hot reload:

So they actually avoid reloading the real component and instead keep the inner state separated so that on reload it wont get lost. I guess for React Native hot reloading is in fact better than figwheel :/

@carocad
Copy link

carocad commented May 19, 2017

An update after some discussions in the cljsrn channel. Although hot reloading seems to work better for stateful components, it doesnt work well with stateless ones (a.k.a functional components). That would explain why maps work better with hot-reloading whereas things like text and views just never update (based on my own experience).

Furthermore the rn dev team doesnt seem too motivated to solve such issues in the near future. So it seems that figwheel is still ahead of the rn hot reload feature. I think that if we could avoid this full component reload on the root then we would be able to keep the state of those components.

@drapanjanas would you mind telling us why does figwheel needs to have this reload on the root element? I tried disabling it but then the app just never updated :(

References:

@drapanjanas
Copy link
Owner

drapanjanas commented May 20, 2017

Well, figwheel just recompiles and reloads changed files. It is a generic tool and is not aware of react or whatever other libs are used in the app. So it is not given that app is reloadable, but with react it is usualy the case. Writing Reloadable Code describes some tips. You can see what files were reloaded in console log - it is the changed namespace and all namespaces which imports it.
I think, for the webapp reload just works because in core namespace we usually have code which mounts the root component to the dom, so we get app reloaded becuase this namespace is reloaded every time any imported namespace have changed.
In RN I was not able to make it work in a similar way. So, it all ended up having a special namespace env.ios.main which wraps the app-root component which is re-rendered on every reload using :jsload-callback hook provided by figwheel. In reagent there is also a force-update-all but it seems not working in RN I think because we do not mount root component the "standard" way as in webapp.

So, when you remove the code of :jsload-callback, the reload just stops working. We could try thinking of something more clever to improve it, but I think it is important that we keep it all locked in special env.* namespaces and not let reload-specific code suck in to the real app namespaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants