I'm currently tinkering with an approach where my code does not dispatch
re-frame events at all, but rather uses my own emit function to emit
signals[1]. I then, separately, have a signal->event map, so the (single
global) signal handler then maps signals to events and dispatches these
events to re-frame.

What this gives me is that the components don't have to know what the (DOM)
event callbacks actually do. Eg, instead of clicking the "add to list"
button dispatching an [:add-to-list ...] event, it triggers an
:add-to-list/clicked event and its up to the application to map this to the
[:add-to-list ...] event. This way this component can be reused elsewhere
by mapping the signal to whatever it makes sense for it to be mapped to.

This indirection also means you can map one signal to trigger multiple
re-frame events, although I haven't played with this enough yet to know if
that is desirable or not.

I like to think of re-frame events and handlers as the applications actions
or capabilities - that is, the things that you can do. That way it makes
sense that there is a 1:1 relationship between events and event handlers
(eg only one handler can handle [:add-to-list ...]). That way, components
emit "this thing just happened" signals which are mapped to "this outcome
should be performed" actions/capabilities.

Obviously reusable components can't always be made in isolation of the
actions that they trigger, especially if they need to maintain
transient/intermediary state. For this I like to define the component
specific handlers as namespaced keywords, eg :my-list-editor/add-to-list

I'm still undecided if such events should be dispatched directly or go
through the signal indirection.

Some final thing to note about the approach I'm investigating:
1. My signal->event mapper  can take an optional (pure) function to convert
signal parameters to whatever data the handler expects.
2. I like to keep my handler functions pure too and do any side-effects (eg
server comm or dispatching new events/emitting signals) in middleware.

Hope that gives you some ideas.

[1] I haven't got the terminology down yet :) I'm calling them signals for
now because they're kinda like Qt's signals & slots, but I dunno if they
really fit into the definition of signals from the FRP world.

On Fri, 27 Mar 2015 at 13:58 Khalid Jebbari <khalid.jebb...@gmail.com>
wrote:

> On Friday, March 27, 2015 at 2:39:37 PM UTC+1, Jamie Orchard-Hays wrote:
> > Does it make sense to pass the reusable component's context as an
> argument to it? ie,
> >
> > (defn ReusableComponent [some-context] .... )
> >
> > Jamie
> >
> > On Mar 27, 2015, at 8:54 AM, Colin Yates <colin.ya...@gmail.com> wrote:
> >
> > > In re-frame event dispatching is handled by (dispatch [:discriminator
> detail]). A corresponding (register-handler :discriminator (fn [db [_
> detail]]) then reacts to that dispatched event.
> > >
> > > My question is how are people managing this with re-usable components?
> For example, I have a tree and when selecting a node in that tree something
> should happen. But this is where it gets all polymorphic as _what_ happens
> depends on the client who instantiated the tree. I can see the following
> ways forward:
> > >
> > > - tree is configured with a 'context' key which is combined with the
> discriminator so rather than the tree emitting :node-selected it emits
> :consumer-a-node-selected. Consumer a can then handle
> consumer-a-node-selected and consumer b can handle (go on, guess)
> consumer-b-node-selected
> > > - a variation on the above involving writing your own dispatching
> logic...
> > > - tree doesn't use dispatch as the event bus, rather it takes in an
> instance of a Protocol:
> > >  IRespondToTree
> > >  (on-node-select [this node])
> > > - tree is parameterised with a map of fns {:node-selected-fn ...} etc.
> > >
> > > How would you all handle it? (I am leaning towards the first one).
> > >
> > > --
> > > Note that posts from new members are moderated - please be patient
> with your first post.
> > > ---
> > > You received this message because you are subscribed to the Google
> Groups "ClojureScript" group.
> > > To unsubscribe from this group and stop receiving emails from it, send
> an email to clojurescript+unsubscr...@googlegroups.com.
> > > To post to this group, send email to clojurescript@googlegroups.com.
> > > Visit this group at http://groups.google.com/group/clojurescript.
>
> Not sure I'm going to answer the question directly, since I've never used
> re-frame, Reagent or Om. I'm just an experienced React.js developer VERY
> interested with Clojure(Script).
>
> If you want reusable components, whatever wrapper you use around React,
> here's the plan.
>
> You should create 2 types of components : dumb and smart. Dumb components
> do 2 simple things : display stuff and handle input/events. The way they
> handle should be agnostic to any kind of library and should use only
> language-level feature. Functions. So the dumb component use function it's
> been passed and call it with the input/event. The smart components wrap
> dumb components and connect to the outside world with whatever your stack
> uses (channels, events, ratoms, what not).
>
> This way your dumb components are always reusable, whatever stack/project
> they're incorporated in. They can also be displayed in a simple page for
> your graphics or HTML/CSS team to check their look. The smart components
> handle whatever logic you want to put in them. So from a stack/page/project
> to another, only the smart components change, no the dumb ones. This keep
> UI consistent and separate concerns.
>
> Hope it's clear and helpful.
>
> --
> Note that posts from new members are moderated - please be patient with
> your first post.
> ---
> You received this message because you are subscribed to the Google Groups
> "ClojureScript" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojurescript+unsubscr...@googlegroups.com.
> To post to this group, send email to clojurescript@googlegroups.com.
> Visit this group at http://groups.google.com/group/clojurescript.
>

-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojurescript+unsubscr...@googlegroups.com.
To post to this group, send email to clojurescript@googlegroups.com.
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to