reagent-project / reagent

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

Force-reset a component? #152

Closed GetContented closed 9 years ago

GetContented commented 9 years ago

I'm not too sure how to ask this, but how do I get a component that wraps a rendering function to re-mount on changing a particular parameter?

Here is a made up example (my actual case is too large to share):

(r/atom app-state {})

(defn some-component [id initial-state]
  (let [internal-state (r/cursor app-state [id]))]
    (reset! internal-state initial-state)
    (fn [id initial-state]
      [:div {:on-click (fn [e] (change-internal-state (-> e .-target .-value))} 
        @internal-state])))

The trouble is, I want internal-state to be re-set on id change. Is there some way I can re-mount a component?

mike-thompson-day8 commented 9 years ago

First item in here might help: https://github.com/Day8/re-frame/wiki/More-advanced-Reagent-techniques

GetContented commented 9 years ago

Thanks, @mike-thompson-day8 that's actually very similar to my use-case - using secretary URL transitions to re-trigger a "page" transition with an identical route - works with everything but the ID change. You're a bit of a legend! :) Seems like a prietty hacky solution, though. It'd be nice if there was a better way to trigger it somehow.

Come to think of it, I wrote the latest incarnation of my app without really understanding what the rendering function was for, so I should clean all of that up at some stage. Neverending!

I just tried, and that works perfectly. Thank you very much!

GetContented commented 9 years ago

By the way, while I've got your attention, @mike-thompson-day8 I actually think re-frame should be referred to from the main reagent repo. When building serious reagent/Om apps, it's the only really good pattern that works in complex apps with large rendering (esp recursive) trees, IMHO. When I first read your re-frame project intro, I laughed a fair bit (a little bit from sadness) because I'd just finished spending 3 months rebuilding my app first in Om then in Reagent and "arrived at" the re-frame pattern by myself. The data-flow and functionality reuse problem is the main thing, (and you can see the other frameworks have come around to this perspective and way of doing things, too) but also the fact that you only have one thread, so you have to switch to channels and chunk your processing if you have lots and don't want your app to dog.

mike-thompson-day8 commented 9 years ago

Very happy for re-frame to be referred to within a main reagent repo. But I have no control over that. I'm not a committer -- I just try to help in the triage of issues every now and again.

And I agree - anyone who isn't using re-frame is doomed to create their own version of it after trying and rejecting various approaches, including read/write Cursors. This assumes a sufficiently complex app, of course. If your app is simple, then it really doesn't matter what you do, it'll work.

All we need to do next is refine re-frame so it works with a reactive database like rethinkdb. Reactive subscriptions all the way back to the database.

GetContented commented 9 years ago

Yeah, it was mostly for the benefit of others, such as @holmsand and @yogthos , really. Just my two cents. It took me a while before I found re-frame. I actually think it'd be beneficial to roll the two into one, with re-frame being optional, but first-class somehow, but again, that's just my 2 cents.

GetContented commented 9 years ago

@mike-thompson-day8 I know this isn't the place, but perhaps eventual consistency database stuff would be useful... http://reiddraper.com/introducing-knockbox/

mike-thompson-day8 commented 9 years ago

I think Reagent is a quite magnificent base and I think re-frame is an interesting and useful layer above it. But that doesn't mean re-frame should be merged into Reagent. They are different layers.

And, at the re-frame level, there are other interesting alternatives like say zelkova. So let's leave them separate. Tomorrow, someone might well deliver a better re-frame layer (bless them).

Regarding knockbox and CRDTs: to me the main challenge in wiring re-frame into reactive databases (like rethinkdb) is how to handle "opportunistic updates" (aka latency compensation). Anyway, we're looking into it.