helix

https://github.com/Lokeh/helix
fabrao 2020-05-06T00:45:02.207700Z

hello all, I could use this https://github.com/nubank/workspaces lib with Helix. It´s easy

(ns myapp.workspaces.cards
  (:require
   [helix.core :as hx :refer [$]]
   [helix.dom :as d]
   [myapp.lib :refer [defnc]]
   [nubank.workspaces.core :as ws]
   [nubank.workspaces.model :as wsm]
   [nubank.workspaces.card-types.react :as ct.react]
   [nubank.workspaces.card-types.test :as ct.test]))

(defnc Painel []
       (d/div {:style {:color "blue"}} "This is a testing"))

(ws/defcard hello-card
            (ct.react/react-card
             ($ Painel)))

fabrao 2020-05-06T00:45:47.208200Z

easier than using devcards 🙂

Aron 2020-05-06T08:27:05.208400Z

worspaces == devcards?

Aron 2020-05-06T08:27:31.208900Z

also, is it worth trying helix without shadow-cljs? with the new clj tooling?

dominicm 2020-05-06T10:04:49.209Z

you have to use the figwheel branch to do that, but otherwise it works fine :)

danieroux 2020-05-06T11:27:53.210500Z

@ashnur we used vanilla Clojurescript with helix, and now using hx with the figwheel branch

Aron 2020-05-06T11:36:13.211300Z

I am confused now : ) but do I deduce it correctly that everything should work with everything ?

Aron 2020-05-06T15:27:43.212400Z

btw, we talk so much about performance but so far I've seen two attempts to actually measure this, one the benchmark a week ago, and one my attempts with sierpinski triangles and both failed to materialize the said improvements. : )

lilactown 2020-05-06T15:39:26.212800Z

helix gives you more tools than other react wrappers to optimize

lilactown 2020-05-06T15:39:59.213500Z

that’s all

Aron 2020-05-06T15:41:01.214900Z

could I ask help with my sierpinski attempt sometimes in the future? I don't want to sound entitled, I realize our goals might not match up 🙂

lilactown 2020-05-06T15:41:43.215300Z

sure! if you post a repository I can review it when I have time

lilactown 2020-05-06T15:44:24.216200Z

I’ve also tried to setup helix’s defaults to be relatively good for performance, but maybe I’ve done it wrong

Aron 2020-05-06T15:45:08.217100Z

I expect most of my personal struggles at the moment to come from simply inexperience with clojurescript, so that's also why I don't want to say anything more than just that I, personally, struggle a bit 🙂

Aron 2020-05-06T15:45:30.217500Z

the repo contains html code for the original demo from here https://claudiopro.github.io/react-fiber-vs-stack-demo/

Aron 2020-05-06T15:46:13.218100Z

the code that uses the old react fiber release works flawlessly, my first attempt fails very badly 😞

Aron 2020-05-06T15:47:31.219200Z

so much so that my first viceral reaction was to do it in js first using latest Fiber because I just can't believe I can fail this much, but that's silly of course, it's very easy to fail at it if you don't understand the language : )

lilactown 2020-05-06T15:50:29.219600Z

yeah definitely. there’s a lot to learn.

lilactown 2020-05-06T15:50:51.220100Z

that demo is using a very old version of React Fiber, too, so it’s not a 1:1 translation

Aron 2020-05-06T15:53:33.220400Z

possibly, but the code is very simple 🙂

Aron 2020-05-06T15:53:56.220900Z

What I had the most struggle with is the createRoot method, it kept losing the root

aiba 2020-05-06T21:12:40.223800Z

Discovered a strange behavior today. Using helix.experimental.refresh, I get different refresh behavior with a component depending on whether it calls a hook with clojure's # syntax, vs. (fn [x] ...) syntax. In other words, (let [f #(my-hook %)] (f foo)) has a different refresh behavior from (let [f (fn [x] (my-hook x))] (f foo)).

aiba 2020-05-06T21:15:52.225400Z

looking at the compiled output, it looks identical except the refresh signature function gets called with a string like "(my-hook p1__121991#)" instead of "(my-hook x)" . Could hte presence of a "#" in the signature string be doing something?

Aron 2020-05-06T21:27:22.226200Z

what is the latest version of helix I could try? should I clone the repository for this? I've been using 0.0.10 for a while and it seems everyone else uses something else 🙂

aiba 2020-05-06T21:28:06.226600Z

@ashnur i'm using 0.0.10

Aron 2020-05-06T21:32:37.227100Z

cool, good to know, i am reading the docs now, i left out everything that sounded scary at the first time

Aron 2020-05-06T21:32:47.227300Z

like experimental

Aron 2020-05-06T21:32:49.227600Z

: D

dominicm 2020-05-06T21:38:41.227700Z

At least you won't lose your job for using them...

Aron 2020-05-06T21:43:50.228400Z

yeah, I want to do the sierpinski thing now, that's not for work 🙂

lilactown 2020-05-06T21:56:02.228900Z

@aiba what’s the difference in behavior?

lilactown 2020-05-06T21:56:58.229900Z

my best guess is that the #() syntax might generate a new symbol name every refresh, which would cause a new signature to be created and invalidate your component’s state

lilactown 2020-05-06T21:57:24.230500Z

in other words, it’s not the # in the signature; the name before the # might be changing each render

lilactown 2020-05-06T21:58:04.231Z

but also, I would be very careful that you are following the rules of hooks: https://reactjs.org/docs/hooks-rules.html

lilactown 2020-05-06T21:58:45.232Z

calling a hook in an anonymous function makes my spider senses tingle that you might be doing something dynamic in a way that could easily break due to violating the rules

lilactown 2020-05-06T21:59:46.233Z

a good rule of thumb is to follow the naming convention set by React/helix: always start your custom hook name with use , e.g. use-my-app-state

aiba 2020-05-06T22:04:17.233900Z

difference in behavior: with the "#" symbol in the signature, the entire component gets re-rendered even when state should be unchanged.

aiba 2020-05-06T22:05:14.234700Z

that's a good theory (symbol name changing on refresh), i can test that by looking at the compiled code

aiba 2020-05-06T22:07:55.235300Z

@lilactown you are absolutely correct, the name of the symbol was changing upon refresh!

aiba 2020-05-06T22:09:55.236500Z

and yeah, admittedly it's a little sketchy to build functional indirection on the hook calls, but i think i'm OK in my case. there is a static vector of constants, and i'm mapping a hook over the vector, so the order/count of hooks should be preserved.

aiba 2020-05-06T22:12:04.237700Z

regarding naming custom hooks with use-, i did see that helix analyzer specifically checks for (string/starts-with? (name x) "use-") and i was wondering if that would miss direct calls to react/useState or calls to third-party js librarys that name their hooks useFoo

lilactown 2020-05-06T22:15:29.237900Z

it might yeah

lilactown 2020-05-06T22:19:14.238400Z

it should check for camelCase or kebab-case, I just haven’t gotten around to writing that regex 😛

lilactown 2020-05-06T22:20:01.238800Z

we don’t use react-refresh at work yet so it’s something that I only experiment with in my free time

aiba 2020-05-06T22:22:05.239100Z

gotchya, well i use it every day with helix and it kicks ass!

aiba 2020-05-06T22:22:15.239300Z

so thank you 🙂

❤️ 1
aiba 2020-05-06T22:22:59.239800Z

happy to write the expression and send a PR for camel case if you'd like

lilactown 2020-05-06T22:23:11.240100Z

I would appreciate that!

👍 1
aiba 2020-05-06T22:23:49.240700Z

it's 1 line if we take a dependency on https://clj-commons.org/camel-snake-kebab/

aiba 2020-05-06T22:23:54.241Z

otherwise a multiline check

lilactown 2020-05-06T22:24:05.241300Z

I would prefer not to take a dependency

aiba 2020-05-06T22:24:13.241600Z

ok, sounds good

lilactown 2020-05-06T22:24:27.242Z

if you have any ideas how to handle the anonymous function, let me know

aiba 2020-05-06T22:27:00.243900Z

we could canonicalize signature strings by renaming the variables in the expressions, but that could be a slippery slope of trying to compare two expressions and determining whether they are in some sense equivalent

aiba 2020-05-06T22:27:32.244500Z

im actually OK just remembering not to call hooks from within # anonymous functions

👍 1
aiba 2020-05-06T22:27:58.245300Z

hopefully it's valid to (mapv use-foo some-constant-vector)

aiba 2020-05-06T22:28:11.245700Z

because that i do all the time

aiba 2020-05-06T22:28:27.245900Z

and seems to be working so far

lilactown 2020-05-06T22:28:52.246300Z

well, if you turn on {:helix/features {:check-invalid-hooks-usage true}} it will definitely throw compiler warnings 😉

aiba 2020-05-06T22:29:35.246600Z

gotchya, i haven't done that yet

lilactown 2020-05-06T22:30:15.247500Z

what’s your use case for doing that?

aiba 2020-05-06T22:30:18.247600Z

there is some kind of hook checking built in to react native at least. sometimes it gives me warnings about hooks.

aiba 2020-05-06T22:31:41.248800Z

one example is there's a navigation screen with a bottom tab that has ~5 buttons, and the tabs are statically configured, and i want a hook for each tab.

lilactown 2020-05-06T22:35:26.249200Z

just make sure that you never want to conditionally render one of the buttons 🙂

lilactown 2020-05-06T22:36:05.249800Z

I would write out each usage of the hook personally. more typing, less potential bugs / have to remember it’s okay to call hooks in a loop just this once

lilactown 2020-05-06T22:38:05.251300Z

of course it’s up to you. the :check-invalid-hooks-usage linter will annoy you about it

lilactown 2020-05-06T22:38:15.251900Z

I guess I should add some way to disable it for certain exprs…

aiba 2020-05-06T22:38:18.252Z

yeah, it's a tradeoff. the downside with writing each hook separately is that it makes it easier to add a tab but forgot to hook it, which is a different kind of bug

aiba 2020-05-06T22:38:45.252200Z

this way, the code says all tabs are hooked