helix

https://github.com/Lokeh/helix
alidlorenzo 2020-03-05T00:31:46.122700Z

are children not merged into props by default? or are we meant to do {:children value} trying to do something like this:

(defnc txt [{:keys [children]] children)

(txt "Hello")

lilactown 2020-03-05T00:33:25.123Z

you’re calling txt like a function

alidlorenzo 2020-03-05T00:34:16.123400Z

ah you’re right :face_palm: have to get used to not doing that

lilactown 2020-03-05T00:37:53.124100Z

FWIW… it’s currently behind an experimental feature flag that I haven’t documented, but you can have defnc create a factory function instead of a component if you want

❤️ 1
lilactown 2020-03-05T00:38:29.124900Z

(defnc txt
  [{:keys [children]}]
  {:helix/features {:define-factory true}}
  children)

(txt "Hello")

lilactown 2020-03-05T00:38:40.125200Z

(should work, haven’t tested that case specifically)

alidlorenzo 2020-03-05T00:38:56.125800Z

will try it out, thanks

alidlorenzo 2020-03-05T00:39:15.126500Z

before you mentioned that you couldn’t get that working with macros, did anything change?

lilactown 2020-03-05T00:39:59.127100Z

I decided that if you want to explicitly enable it, you probably understand the differences between a factory function and a macro

lilactown 2020-03-05T00:41:03.128300Z

the two biggest differences are that • performance wise, the factory function will construct a hash map you pass in as props, not a JS object • you can’t/don’t use & for spread props

alidlorenzo 2020-03-05T00:44:25.129500Z

by props, you mean a cljs map of props, right? so does that mean we should still construct our primitive components with :define-factory false but others ones we can just use factories

lilactown 2020-03-05T00:48:08.132700Z

I’m not sure. what I mean is that:

(txt {:foo "bar"} "baz")
will not compile {:foo "bar"} to a JS obj, but instead will actually do what it says: create a new CLJS map and pass it to the component. the way that helix extracts passes these props and extracts them is smart. it will pass {:foo "bar"} as a single React prop
(react/createElement #js {"helix/props" {:foo "bar"}} "baz")
and then when you read props in defnc, it will check for that before defaulting to wrapping the whole props object in a bean: https://github.com/Lokeh/helix/blob/master/src/helix/core.cljs#L125

🆗 1
lilactown 2020-03-05T00:48:44.133100Z

I’m not completely sure how this impacts performance

lilactown 2020-03-05T00:49:08.133600Z

on the one hand, creating CLJS maps is more expensive than creating a JS obj. but by how much? ¯\(ツ)

lilactown 2020-03-05T00:50:25.135Z

some people who are sensitive to code size might see more keywords created as well

lilactown 2020-03-05T00:50:45.135500Z

anyway, I guess the only confusing thing people will really care about is that you can’t use &

alidlorenzo 2020-03-05T00:53:31.136400Z

hm, would it be possible for a component to know how it’s being called, so it could toggle :define-factory appropriately?

alidlorenzo 2020-03-05T00:55:24.136600Z

i haven’t used macros much yet so no idea if that’s possible but i could see it being useful to decide that when you’re calling the component rather than upfront

alidlorenzo 2020-03-05T00:56:07.136800Z

^ by that I mean whether it’s being called by $ or as a regular function

lilactown 2020-03-05T00:58:29.137100Z

I haven’t looked into it deeply, but it might be difficult

alidlorenzo 2020-03-05T00:59:59.137300Z

yea I imagine. might be best to just keep using $ 😅

alidlorenzo 2020-03-05T01:05:47.137500Z

can confirm this works

lilactown 2020-03-05T01:06:09.137700Z

👏

Luis C. Arbildo 2020-03-05T17:14:17.139600Z

Good Day @lilactown, How are you? I ask me, What resources did you use to get to know Clojure as you know it now?, maybe you could give me any recommendation

lilactown 2020-03-05T17:49:39.140300Z

hey Luis. I’ve been working with Clojure and ClojureScript for a couple years now, so time and experience is a lot of it!

lilactown 2020-03-05T17:50:05.140500Z

I also have enjoyed watching the talks Rich Hickey and David Nolen have given over the years

lilactown 2020-03-05T17:50:23.140700Z

mostly just keep experimenting, building software, and asking questions 🙂

Luis C. Arbildo 2020-03-05T17:52:34.140900Z

Neat! Thank you!

alidlorenzo 2020-03-05T21:59:43.142900Z

if the second argument of helix’s use-effect hook is the body of a function, how is cleanup handled? I’m trying to get something like this working:

(h/use-effect
   :always
   (fn []
     (js/console.log "starting...")
     (fn []
       (js/console.log "cleanup...."))))

lilactown 2020-03-05T22:01:11.143300Z

ah, helix’s use-effect doesn’t require you to wrap it in a 0-arity function

lilactown 2020-03-05T22:01:47.144100Z

(h/use-effect
 :always
 (js/console.log "starting...")
 (fn []
   (js/console.log "cleanup..."))

alidlorenzo 2020-03-05T22:07:21.144800Z

oh ok, so last function returned is one that gets called for cleaning up. cool thanks