Fork me on GitHub
#re-frame
<
2021-06-25
>
vemv11:06:36

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

p-himik11:06:16

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.

👍 5
vemv11:06:08

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

p-himik11:06:23

It would work, sure. The whole re-com library is built that way.

👀 2
p-himik11:06:28

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.

👍 2
sansarip14:06:34

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.

👀 2
vemv14:06:34

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

sansarip15:06:41

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 defc and fnc. Unfortunately due to how the macro works, you’d need to inline your vanilla defn e.g.

(defc my-component (fn []))
This is because defc actually will dissect your vanilla-fn to get at the parameters it accepts and injects a bit of code into it. defc and fc are still around in the latest version, alongside the newer defnc and fnc macros

vemv15:06:00

Nice! Will check out

👍 2
colinkahn19:06:53

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.)

👍 2
🙂 2
indy11:06:51

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.

👀 2