Is there a write-up anywhere on the challenges of react using identity for comparison and clojurescript using equality? I’ve tried different libraties and wrappers over hooks the other day and I’m still confused if this is something that could be “fixed” on the clojurescript (macro) side of things. Right now good old reagent seems more accessible to me.
I have opinions
https://github.com/Lokeh/helix/blob/master/docs/pro-tips.md#dont-use-deep-equals
I'm gonna subscribe to your blog :p
lol
I was wondering the other day if I have an RSS feed setup or not
FWIW my blog is not always great, I am trying to get better at writing
@ordnungswidrig I think the answer is that in the majority of cases, you actually do want to use identity for comparison. If your team is struggling with this, it means that you might need to slightly rethink the way you are programming your app.
my blog is empty, because I'm terrible at writing :)
One problem with hooks is that deep equality becomes useful when you've got use-effect in play
in some specific way, or do you mean just that it would be nice to have deep equality for deps comparison?
most of the time, when I think I need deep equality it can actually be solved by lifting the data outside of a component's render fn, or by memoizing a calculation
the times that I haven't been able to solve this were worst case situations: deserializing data from some external source, e.g. a fetch payload
in that instance, deep equality is both necessary and also terrible. I wrote a custom hook that covered this and gave it a really long name use-stable-identity
I wonder why in ClojureScript "default equality" (`=`) should be worse than identity. Coming from reagent with a global atom and cursors etc. I'm just used that it short circuits on equality.
Maybe I'm simply doing it wrong :-)
(but I'm also a fan of hiccup 😛 )
=
can potentially do a traversal of the entire structure you're passing in to determine whether the two data structures are equal, which is why it can be slower
maybe I'm making a mountain out of a mole hill, but IME fixing this for 80% of the cases requires a slight restructuring of my code that ends up being faster. it is a change if you're coming from reagent, because now you do need to think about identity of your data structures
maybe that's fundamentally an antipattern? I haven't determined yet
helix does try to make this easier for you by providing easy syntax for optimizations
e.g.:
(defnc my-component [{:keys [value]}]
(let [data {:foo value}]
(hooks/use-effect
[data]
(js/alert "data changed!"))
,,,))
the above will alert every successful render because data
gets created every render.
with helix, you can easily annotate the data with a memo optimization which will fix this:
(defnc my-component [{:keys [value]}]
(let [data ^:memo {:foo value}]
,,,))
helix will emit a call to helix.hooks/use-memo
and use inference based on the local context to fill in value
as a dependency, so that it re-computes the value when value
changesmy goal is to turn on the easy syntax for optimizations by default in a release this week. I have the week off so gonna be doing some OSS stuff
@lilactown it was because of the serialization that I had the problem, yep.
I like that.
In some projects, most of your state is serialized.
@lilactown I like hx and I tried helix, I need to understand this better.
I read your concerns about hiccup but using ($ some-component {,,,})
instead of [some-component {,,,}]
feels like a step back, even compared to JSX.
The performance cost is significant though. In a UI you've got a really small performance budget.
If we are really just discussing syntax, try the hx factory mode. It gives you something equally short to the hiccup syntax.
What about #uix? It claims only a small performance penalty for hiccup like syntax.
It'd be interesting to try that on the react benchmarks helix is part of.
@dominicm is that a collection of react wrappers competing?
I saw today that @roman01la forked sablono and has made some improvements to the inference and performance
It’s interesting.
I’m just sort of sensitive to “good enough” solutions at the level we sit as wrapper authors, since React itself is a “good enough” solution wrt performance already
And app authors are the ones that suffer from whatever performance tax we impose within our wrapper libs
👋 Sablono fork was mostly done to solve existing issues with input fields in Rum and unblock Rum from waiting for Sablono to fix its issues. But in general I'll put some time into the library to try to align interpreter perf with uix.
which fork is this? I think the clojurescript react-wrapper and hiccup landscape is getting a little confusig 😛
it's now in Rum's repo under the name daiquiri
https://github.com/tonsky/rum/tree/gh-pages/src/daiquiri
On the other hand, when most of the Hiccup is compiled into react calls, there's not much left for interpretation, unlike in uix, where compilation is optional.
(didn't know this channel exists :) )
yeah, I am very interested in hiccup that can compile into forms w/ essentially zero cost compared to equivalent JSX
my efforts so far haven't yielded anything more ergonomic than explicitly calling a macro constructor or using factories, which is why I've eschewed recommending or adopting it as a default
I'm still hoping that someone else will get it there 😄