Closed luposlip closed 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.
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.
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!
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? :-)
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).
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! :)
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 :)
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!
Hey again - when do you plan to have an official release (0.4.3) containing this lighttable "hack"?
Best, Henrik
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...
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
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