Fork me on GitHub
#helix
<
2021-05-24
>
Emi Gal13:05:49

This might be a silly question (apologies - I’m new to clojurescript, coming from a python background), but what are the benefits of using helix instead of just reagent?

Aron14:05:34

As someone who used helix for many months now but never tried reagent, my reasoning was that this way I can use react state management and any react developer can understand the code, if they squint a bit 🙂 Even though possibly the state management tooling provided by the core of clojurescript is one of the biggest value propositions, having to sell all of it at once to my bosses would've been more difficult. And I wasn't very experienced with cljs.

lilactown16:05:15

yep, like Aron said, helix is very close to React. Reagent adds a bunch of stuff on top

lilactown16:05:51

both are fine choices. reagent has a lot more discussion, blog posts, and usage in the ClojureScript world. if you're new to both ClojureScript and front end development, it might be easier to get help

lilactown16:05:12

however, if you're already familiar with front end development using React, helix should make it very easy for you to jump in, learn the syntax and start building UIs

Emi Gal19:05:58

awesome, thanks @ashnur and @lilactown. So if I understand this correctly, Helix is more like React, and Reagent is more idiomatic clojure. I kinda like the idea of having something that almost looks like React, but that interfaces well with Clojure. The only shortcoming I see for Helix right now is that it doesn’t have super straightforward interop with re-frame, which is arguably the most popular state management framework for clojurescript. I looked at the hooks on github but it’s a bit confusing (at least for a noob) on how those hooks exactly work, so I haven’t managed to make re-frame work with helix (yet).

Aron19:05:29

I am also a bit confused by the situation. In theory there is a use-subscription hook somewhere, but I think that's only experimental?

Aron19:05:45

Or uses pre-Fiber assumptions

raspasov19:05:45

I’ve been using React/ReactNative since 2014 or so. I’ve seen a number of libs/frameworks/state management approaches come and go, both in CLJS and JS world. I think sticking as close to React as possible makes sense (to the point where I don’t use any libraries at all, I just use direct JS interop with React and have my own basic state management on top). If I’m forced to pick a library today, Helix would be my choice.

Jimmy Miller19:05:19

One less than great thing about trying to combine reframe and helix is that you will end up with both helix and reagent in your application. For a production application that is probably less than desirable

👀 3
Emi Gal19:05:54

This is such a great point @jimmy - it’s exactly what’s been bothering me but I wasn’t able to articulate it as well as you just did 🙃

wilkerlucio19:05:51

one thing to consider here is that DCE is quite good in CLJS, this means you can use reframe, but use just the hooks helpers from Helix, this way you pay a very low price on it, in fact, only what you use

Jimmy Miller20:05:46

Yeah, I suspect in practice though you may run into more issues than just code size. Closure dead code elimination is definitely great. But you will also potentially have conflicts with dependencies. You could have confusion on a team about which way things ought to work. etc. Definitely not suggesting don't do it at all. Just that is probably worth thinking through and really testing out what it is like in practice before making the decision. Also, though, if people really like reframe and those people also want to use helix, making a reframe like library is a great opportunity for someone.

3
raspasov19:05:30

I think using React directly + using basic Clojure(Script) constructs is an underappreciated option. It does require very good expertise and understanding of both React and Clojure(Script), perhaps that’s why.

wilkerlucio19:05:13

the thing is, everyone would end up kind writing the same wrappers around, this is what I like about Helix, its very much just a lightweight wrapper to call React, in my case that's mostly important because of IDE auto-complete on Cursive, but also some of the helpers around hooks (so I don't have to write a fn to make an effect, neighter return the weird js/undefined to make the effect hook happy)

wilkerlucio19:05:52

I think if I were to use react directly, I would end up writing very similar helpers, so since @lilactown already took the work, I use it 🙂

👌 9
❤️ 3
raspasov19:05:25

That’s fair, but esp. around hooks, I think just using interop is super basic.

raspasov19:05:45

(def use-effect (.-useEffect React))

(use-effect 
 (fn []
  (fn cleanup []
   )))

raspasov19:05:58

What kind of wrapper do you really need here 🙂

wilkerlucio19:05:44

when you have a cleanup, I think looks good, but this botters me:

(def use-effect (.-useEffect React))

(use-effect 
 (fn []
    (do-something)
    js/undefined))

raspasov19:05:47

Not familiar with the js/undefined case. Which hook does that apply to?

wilkerlucio20:05:00

because if you don't return js/undefined, React complains that you can only return a fn from a effect

wilkerlucio20:05:36

this is because of JS vs CLJS different, in JS, if don't use return on a fn, you get undefined as the return, but in CLJS it will return the value of the last expression

wilkerlucio20:05:53

which, if it is anything other than a fn, or js/undefined, will throw an error from React

raspasov20:05:21

Hmm, I’ve always been returning a cleanup fn.

raspasov20:05:39

(for that past few months since I started using hooks and useEffect)

raspasov20:05:36

I guess that’s how I avoided running into that case, I always put an empty (fn cleanup []) even if it did nothing.

raspasov20:05:53

FWIW, my whole medium-sized project has only 4 (useEffect …) usages. I try to keep any side-effecting stuff out of the components as much as possible.

wilkerlucio20:05:27

I do use a lot of effects to integrate foreign libraries, like Cytoscape graph renders, D3 integration, CodeMirror integration, for those effects are super handy 🙂

raspasov20:05:10

Yes, I think those are good use cases. Mostly non-IO related stuff. If people start putting HTTP calls, etc in use-effect I think it’s not good.

wilkerlucio20:05:22

I used to think like that in the past, but nowadays I'm starting to think it can be good, and the Suspense + Async Rendering seem like something that will favor this kind of approach. my long time as a Fulcro usermade me aware of advantages and how we can reduce the number of requests. but at same time I feel the pain of *needing* to connect every component in the same query. so I'm excited with Fulcro Raw, which allows some effects to tap into the app state, and they may also trigger IO in the middle, I have coded a few projects playing with that, and I quite enjoy the results, I can develop really fast, and if I see the number of IO going off the rails, Ican always refactor, connect some queries and move the IO up.

wilkerlucio20:05:52

still feels experimental, but I have big hopes with this path of "ui tree processing"

raspasov00:05:09

Hmmm, ok. Fair. But I’ve gone that path where every component is its own “island” and does its own IO. It didn’t turn out very well in terms of the complexity it brings. For example, what happens when you need two requests to be processed in a specific order, but they belong in different components?

raspasov00:05:53

Perhaps if you design everything so that the order of requests does not matter, it can be good.

wilkerlucio19:05:28

I can also see oportunities to do dynamic batching, like Falcor does https://netflix.github.io/falcor/

wilkerlucio19:05:18

the basic idea is to debounce the API requests, so you can accumulate items and send a single request, would be interesting to see how much we can optimize/combine those with EQL

wilkerlucio19:05:13

the thing is, everyone would end up kind writing the same wrappers around, this is what I like about Helix, its very much just a lightweight wrapper to call React, in my case that's mostly important because of IDE auto-complete on Cursive, but also some of the helpers around hooks (so I don't have to write a fn to make an effect, neighter return the weird js/undefined to make the effect hook happy)

Emi Gal19:05:54

This is such a great point @jimmy - it’s exactly what’s been bothering me but I wasn’t able to articulate it as well as you just did 🙃