Description
View functions with a subscription are not pure. They are using a data input from a non-argument source.
(defn greet
[]
[:div "Hello " @(subscribe [:name])]) ;; in comes some data
From a practical point view, I haven't been motivated to solve this problem previously - given the way re-frame structures your app, non-local reasoning is not a problem in this case, and neither is testing because subscribe is trivial to stub out, so it feels like you are dealing with a pure function - however from a purist's point of view, this is certainly a "pebble in the shoe". In due course, I'd like it fixed, but I'm relaxed about when.
Here's a quick sketch of approximately how (not all issues resolved):
-
create a new
reg-view
function thru which all views are associated with anid
. Make this
registration much likereg-sub
in the way that you can nominate N signal inputs via a signals function. -
change Reagent so that the first element of vector can be an
id
previously registered by
reg-view
. So, instead of[:div ...]
, you could use[:something/panelX ...]
Would be used like this (notice how similar this is to reg-sub):
(re-frame.core/reg-view ;; <--- new
:a-view-id ;; an id for this view
;; input signals function
;; what it returns will become the first param passed to the computation function
(fn [item-id another] ;; will be given props
(subscribe [:item item-id]))
;; computation function which returns hiccup
(fn [item item-id another] ;; given props BUT with values from subscription prepended
[:div (:name item)]))
The computation fn
becomes pure. The "subscribed to" values are put in the first argument
(same pattern as is currently used with reg-sub
).
Later, when you wanted to use this view:
[:a-view-id 12 "hello"]
Reagent would look up the view id a-view-id
and use the associated render function.
Significant Open Questions:
- how to do Form-2 views or Form-3? This could be a stumbling block
- Reagent treats the first prop as special. If it is a map it can contain keys etc.
- Will Reagent accept this proposal?