Fork me on GitHub
#helix
<
2020-05-06
>
fabrao00:05:02

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

fabrao00:05:47

easier than using devcards 🙂

Aron08:05:05

worspaces == devcards?

Aron08:05:31

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

dominicm10:05:49

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

danieroux11:05:53

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

Aron11:05:13

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

Aron15:05:43

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

lilactown15:05:26

helix gives you more tools than other react wrappers to optimize

lilactown15:05:59

that’s all

Aron15:05:01

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 🙂

lilactown15:05:43

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

lilactown15:05:24

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

Aron15:05:08

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 🙂

Aron15:05:30

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

Aron15:05:13

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

Aron15:05:31

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

lilactown15:05:29

yeah definitely. there’s a lot to learn.

lilactown15:05:51

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

Aron15:05:33

possibly, but the code is very simple 🙂

Aron15:05:56

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

aiba21:05:40

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

aiba21:05:52

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?

Aron21:05:22

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 🙂

aiba21:05:06

@ashnur i'm using 0.0.10

Aron21:05:37

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

Aron21:05:47

like experimental

dominicm21:05:41

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

Aron21:05:50

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

lilactown21:05:02

@aiba what’s the difference in behavior?

lilactown21:05:58

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

lilactown21:05:24

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

lilactown21:05:04

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

lilactown21:05:45

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

lilactown21:05:46

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

aiba22:05:17

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

aiba22:05:14

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

aiba22:05:55

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

aiba22:05:55

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.

aiba22:05:04

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

lilactown22:05:29

it might yeah

lilactown22:05:14

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

lilactown22:05:01

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

aiba22:05:05

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

aiba22:05:15

so thank you 🙂

❤️ 4
aiba22:05:59

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

lilactown22:05:11

I would appreciate that!

👍 4
aiba22:05:49

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

aiba22:05:54

otherwise a multiline check

lilactown22:05:05

I would prefer not to take a dependency

aiba22:05:13

ok, sounds good

lilactown22:05:27

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

aiba22:05:00

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

aiba22:05:32

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

👍 4
aiba22:05:58

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

aiba22:05:11

because that i do all the time

aiba22:05:27

and seems to be working so far

lilactown22:05:52

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

aiba22:05:35

gotchya, i haven't done that yet

lilactown22:05:15

what’s your use case for doing that?

aiba22:05:18

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

aiba22:05:41

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.

lilactown22:05:26

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

lilactown22:05:05

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

lilactown22:05:05

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

lilactown22:05:15

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

aiba22:05:18

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

aiba22:05:45

this way, the code says all tabs are hooked