Anyone has tried splitting view defns into pure and impure parts? (systematically, at scale)
For example in https://github.com/jacekschae/conduit/blob/732d56d5bd981bd47fab3cdd1b2d96ea27b1e7ff/src/conduit/views.cljs#L209-L216 , the
@(subscribe part makes the defn impure, which might preclude some techniques.
I figured the splitting could make sense: it would be akin to the controller<->view separation in MVC frameworks. The "C" part would handle state and the "V" part would be a pure fn of
app-data -> hiccup signature
This is how Redux’s connected components work, don’t they? The mapStateToProps and mapDispatchToProps (the impure bits) are injected into the HOC that “wraps” the “pure” React component.1👀
It's a balance. Having impure components does indeed preclude some techniques. But having all components consist of a pure fn + an impure one will make it harder to write and support. So if you need some of those techniques for all or for the majority of the views - sure, it makes sense. But if you need them only for some - I would split only those few view functions.2👍
Basically I'm interested in whether it would work at all (beyond a basic example), perhaps some experience report Supporting it might be less painful than it sounds - if one settles in using a MVC-like project structure, then splitting concerns would come quite naturally and mechanically i.e. many devs appreciate a proliferation of defns, files etc even when they know they could inline everything over one defn
It would work, sure. The whole re-com library is built that way.1👀
To be clear - it has only one layer, the pure functions. It doesn't depend on re-frame at all - that part is up to the user.1👍
There’s also this small library I wrote that provides another flexible way of creating form-1 components: https://github.com/sansarip/peanuts you can play around with it in the https://sansarip.github.io/peanuts/#!/peanuts.cards.main.1👀
That looks neat. It's useful that you point out performance - I suspected there was that possible drawback.
Btw have you tried an API in this style?
(defn vanilla-defn) +
(defc my-component vanilla-defn)
So one sticks to vanilla clojure.core defns, increasing the confidence in whether magic is in fact reduced. Also would mean automatic support for :pre/:post and the other things you point out
If I understand you correctly, that’s actually supported 🙂 That was the original implementation. If you look at an https://github.com/sansarip/peanuts/tree/5499859a2a00d37454256312b1d784c80ddb6587, you’ll see info on
Unfortunately due to how the macro works, you’d need to inline your vanilla
This is because
(defc my-component (fn ))
defcactually will dissect your
vanilla-fnto get at the parameters it accepts and injects a bit of code into it.
fcare still around in the latest version, alongside the newer
Nice! Will check out1👍
I’m familiar with this idea under the name “container components”. I use the pattern a lot, and it enables testing your views without any wiring in things like storybook (or dev cards etc.)1👍1🙂