reagent-project / reagent

A minimalistic ClojureScript interface to React.js
http://reagent-project.github.io/
MIT License
4.75k stars 414 forks source link

LightTable live coding? #27

Closed luposlip closed 10 years ago

luposlip commented 10 years ago

Hi there!

I'm considering Reagent vs. OM. I'm using LightTable.

So far I haven't been able to successfully use Reagent with LightTable live coding. With OM it works every time (following the first section in this tutorial: https://github.com/swannodette/om/wiki/Basic-Tutorial).

Any hints to getting it to work with Reagent? :-)

Thanks in advance - Reagent looks really promising by the way! :)

Best regards, Henrik

holmsand commented 10 years ago

Yes, the LightTable/Reagent combo is a little tricky. Right now you should be able to change data dynamically, and have it update immediately in the browser.

But code is another matter. The problem is this: child components don't re-render unless their data (either an atom or their arguments) change – that's what makes Reagent fast. Unfortunately this also makes it awkward to force an update, which is what I think you'd want to do in LightTable.

So, what Reagent needs (I think) to work better with LightTable is a way to globally disable the caching. I'm not sure about the right api, though. Perhaps simply (reagent.core/always-update false) or some-such?

Any thoughts?

Side note: In an ideal world, I'd like to be able to re-render everything automatically whenever you eval something in LightTable. But I don't think LightTable exposes the necessary hooks for that to be possible right now (but I haven't looked into this very deeply, so I might be completely wrong). It would be very cool, though.

luposlip commented 10 years ago

A config-var like the one you suggest - for development purposes - would work just fine for me.

Right now I'm just really hooked on the whole live coding gimmick, so the sooner I can start living out this dream with Reagent, the sooner I'll start using Reagent for serious stuff! :-)

Anything I can do to assist - let me know.

holmsand commented 10 years ago

Ok, I've been living the dream a little :)

I've added an experimental reagent.core/force-update-all, that re-mounts and re-renders all root components. That can be used either by eval-ing it directly in LightTable, or by adding something like

             "alt-r" [:eval-editor-form
                       (:eval.custom
                        "(if (exists? reagent.core/force-update-all)
                          (reagent.core/force-update-all)
                          \"Not available\")"
                        {:result-type :statusbar})]

to the :editor section in user.keymap.

Then, alt-r will eval the current form, just like cmd-return, and reload all components at once. It seems to work fairly well, in my very hasty testing.

There is one gotcha, though. If do, say, (reagent/render-component [foo] (.-body js/document)), and then later eval foo, it will not be updated directly (you'll have to do the render-component again). That is because the function foo is passed by value, so there's no way for Reagent to know that it has changed (that I can think of, at least).

foo's children will be re-rendered though, so a solution for now is simply to pass a another component to render-component, that returns [foo].

If you have an idea for a more elegant solution, let me know!

luposlip commented 10 years ago

Great news! :+1: Seems like I haven't too much luck in using your new code though.. Perhaps I need more insight in Leiningen. I have a project with dependency reagent "0.4.3-SNAPSHOT". I've build 0.4.3-SNAPSHOT using lein cljsbuild once. Then I install it in my local m2 repo with lein install.

When I look in the .m2 repo for the local reagent-0.4.3-SNAPSHOT.jar, it contains the new version of core.cljs with force-update-all.

But my local project can't seem to find any reagent classes at all, until I revert my dependency to 0.4.2.

Any hints? :-)

holmsand commented 10 years ago

I constantly feel I need more insight into Leiningen's mysteries as well :)

I can only say that it should work... When you do lein install, you should get a directory in ~/.m2/repository/reagent/reagent, containing reagent-0.4.3-SNAPSHOT.jar. Then you should be able to use [reagent "0.4.3-SNAPSHOT"] in :dependencies. At least that works for me :)

Btw, you can actually skip the "lein cljsbuild once" step.lein install ought to be enough (it basically just packs all the sources into a jar, without touching anything compiled).

luposlip commented 10 years ago

Alrighty ;) I managed to get something to work with the supplied demo app. And when I press the suggested alt+r LightTable returns the "Updated" status. But the UI doesn't update anyhow.

I'll try to figure out why my leiningen won't use the local reagent-0.4.3-SNAPSHOT.jar.

Would you mind to email me the sample app you have where it works (luposlip at gmail dot com)?

Thanks again! :)

holmsand commented 10 years ago

Ok, I think you're on your way :) If it says "Updated", that means that the new version has been picked up by LightTable at least.

I just pushed a commit where render-component optionally takes a function returning a component, instead of the component directly, which should make LightTable happier. So, instead of (reagent/render-component [foo] (.-body js/document)) you can do (reagent/render-component (fn [] [foo]) (.-body js/document))

To see it in use you can check out the "simple" example, in the examples directory. It should work out of the box, after the usual lein install dance. Hopefully. :)

Just git pull, cd into examples/simple, and run make. If you then open the "example/simple" directory as a workspace in LT, you ought to be able to just (a) open example.html, (b) hit cmd-return, and (c) change something and hit alt-r. Again, hopefully :)

luposlip commented 10 years ago

Holy Moly - it works! :-D

Great stuff Dan, thanks a bunch!! As of exactly right now, I'll start using Reagent for real stuff!

God aften i det Stockholmske!

luposlip commented 10 years ago

Hey again - when do you plan to have an official release (0.4.3) containing this lighttable "hack"?

Best, Henrik

holmsand commented 10 years ago

Well, I plan to do a release a couple of weeks ago :) That plan obviously didn't work out, unfortunately, as plans tend to do.

I want to do some more testing before I release. Hopefully I can get some time to do that next week.

Thanks for reminding my already quite bad conscience...

luposlip commented 10 years ago

Hi Dan,

Not to tickle your bad conscience any further, but I really need an official release with react 0.10.0 (and lighttable is a great add-on bonus). Any idea on when you'll get the time? :-)

Best regards, Henrik