react

"mulling over state management stuff"
Aron 2020-05-15T05:56:40.102Z

I don't mind they steal the ideas

Aron 2020-05-15T05:56:46.102300Z

I mind that they don't make it well

Aron 2020-05-15T05:57:40.103200Z

clearly starts with the problems I've also been repeating non-stop, even here 1. components sharing state only through violation of encapsulation 2. no namespaces

Aron 2020-05-15T05:57:52.103500Z

and then implements a half-hearted solution

Aron 2020-05-15T05:57:56.103700Z

why?

Aron 2020-05-15T05:58:27.104200Z

if hooks were namespaced, you could use them anywhere, since the order wouldn't matter anymore

Aron 2020-05-15T05:59:13.104900Z

simply put, the fact that js can't talk about paths in a nested collection efficiently is its biggest weakness

Aron 2020-05-15T06:02:17.105Z

so they won't conflict? šŸ™‚ you need indexed access for performance

dominicm 2020-05-15T06:44:11.105500Z

https://news.ycombinator.com/item?id=23185451 this has my attention

dominicm 2020-05-15T07:01:12.107Z

The trick seems to be some kind of root context with a ref scoped from the name of the atom... That way it is scoped to the tree.

Aron 2020-05-15T07:50:52.107400Z

it explains a lot if it is for the server, thanks @dominicm

orestis 2020-05-15T08:07:34.108Z

Am I the only one who doesnā€™t care for the server render part?

Aron 2020-05-15T08:36:38.109800Z

I have had similar thoughts, but I wouldn't voice them quite like that : ). It's all about UX in the end, it is worth having fast first screen which means that it's good to be able to take your app and render it on the server and send it as html while the actual thing is loading in the background. If you don't care for those miliseconds then it's much easier to move all UI to the client and just be an api consumer.

dominicm 2020-05-15T08:50:19.109900Z

Some projects need it more than others. Particularly when building outside of only application.

Aron 2020-05-15T12:42:44.110300Z

"outside of only application"? I almost understand it šŸ™‚

orestis 2020-05-15T13:17:15.110800Z

I guess something that is a public thing?

aisamu 2020-05-15T13:19:23.112Z

IIRC, search engines also weren't very good at crawling SPAs until recently (even with proper sitemaps and routing)

dominicm 2020-05-15T17:38:34.112100Z

I was referring to the "A" in SPA. If you're doing pure SPA, then you don't care. If you have a mix of public facing content you're usually more inclined.

dominicm 2020-05-15T17:38:42.112200Z

Search engines still aren't very good, despite what they claim.

ā˜ļø 1
lilactown 2020-05-15T17:40:21.112700Z

yeah and in general downloading 3mb of compressed JS is still a horrible experience

lilactown 2020-05-15T17:40:45.113200Z

I really like the idea of selective hydration with mostly static content

lilactown 2020-05-15T17:41:02.113600Z

itā€™s what I built at my previous employer on top of CLJS, but it was all very manual

dominicm 2020-05-15T17:41:45.113900Z

Part of me wonders if I'm doing my current project wrong & we should go back to fully static w/ progressive react enhancement for tables, etc.

lilactown 2020-05-15T17:42:44.114600Z

a problem with CLJS specifically is that CLJS is awful for progressive enhancement since the core library is so many bytes

dominicm 2020-05-15T17:43:14.115200Z

Yes. But who'd want to write in something else?

lilactown 2020-05-15T17:43:16.115400Z

you get a lot of bang for you buck, but itā€™s still a lot of bucks

lilactown 2020-05-15T17:43:24.115700Z

haha thatā€™s why Iā€™m still around šŸ˜›

dominicm 2020-05-15T17:43:44.115800Z

Admittedly, my personal values are compromised by Cljs. That is, I think LibreJS is a great idea & cljs really compromises it.

dominicm 2020-05-15T17:43:53.115900Z

But this is my inner freedom hippy coming out :)

lilactown 2020-05-15T17:48:08.116700Z

I dream of a lisp-y, repl-y, immutable-first-y lang that doesnā€™t come with all the bytes. alas, I donā€™t know if itā€™s possible

lilactown 2020-05-15T17:48:21.117Z

but the costs of CLJS weigh on me every day

dominicm 2020-05-15T17:48:32.117100Z

You carry this heavy burden on your shoulders? šŸ˜

šŸ¤Ŗ 1
dominicm 2020-05-15T17:48:49.117200Z

Admittedly, I've never seen a bundle as big as ours & I'm pretty sure it's mostly from node_modules.

dominicm 2020-05-15T17:49:13.117400Z

I'm just changing our build to be :bundle, and I'm hoping to see some benefits from that.

dominicm 2020-05-15T17:49:25.117500Z

Maybe I can run some of our npm deps through closure for example.

dominicm 2020-05-15T17:49:38.117600Z

Or maybe just having webpack know about the whole build will solve my problems? Not sure.

Aron 2020-05-15T17:51:46.118300Z

i am not sure if people see what babel plugins look like size wise

lilactown 2020-05-15T17:51:57.118800Z

the biggest downside to :bundle AFAICT is that you canā€™t code split your node_modules with your CLJS code

Aron 2020-05-15T17:52:06.119100Z

async regenerator or core-js

lilactown 2020-05-15T17:52:06.119200Z

or at least, itā€™s a very manual process

Aron 2020-05-15T17:54:02.120900Z

it was always very manual, I heard a lot how closure was the state of the art in code splitting and then I looked it up and you had to manually write the config files. And even today webpack either wants you to use some completely custom built hack around dynamic import() modules which may or may not follow the standard in module resolution logic, or you have to write the splits manually

dominicm 2020-05-15T17:57:39.121500Z

@lilactown maybe with some webpack config, not sure. We aren't doing that yet, so future Dominic can worry about that.

dominicm 2020-05-15T17:57:49.121600Z

By then David might have fixed it :)

lilactown 2020-05-15T17:58:12.121800Z

hahaha

dominicm 2020-05-15T17:59:23.121900Z

Makes sense :) Now we have a jumping off point to go towards that!

orestis 2020-05-15T18:28:11.123300Z

shadow-CLJS with code splitting is pretty trivial. I pushed Vega to its own bundle which was 1mb...

lilactown 2020-05-15T18:29:50.123700Z

yeah, thatā€™s a big reason I donā€™t see myself migrating off of shadow-cljs anytime soon

orestis 2020-05-15T18:30:50.125600Z

Just skimmed a bit in recoilā€™s source. Itā€™s ... a lot.

lilactown 2020-05-15T18:30:57.125800Z

yeah

orestis 2020-05-15T18:32:36.127Z

I only did it on mobile so I wonā€™t pass judgement yet. But I just wonder if just building on top of IWatchable isnā€™t enough.

orestis 2020-05-15T18:33:31.128500Z

It seems recoil ā€œhangsā€ the state inside the component tree (you need a RecoilRoot component wrapper), so thatā€™s a major difference between that and module-level mutable state.

orestis 2020-05-15T18:34:53.129800Z

The ā€œselectorsā€ stuff is just derived data with dependency tracking, which also seems easy to do (esp. if atoms need to be keyed with globally unique identifiers).

dominicm 2020-05-15T18:36:07.132Z

Yep. It's the same story as redux :) clojurescript has a lot of this built-in

orestis 2020-05-15T18:36:09.132100Z

The main thing I want to see is how they deal with suspense. They have a ā€œLoadableā€ thing for suspending values, and they seem to be tracking nested loadables too, but the ā€œeasyā€ api seems to be always returning actual values, not Loadables.

orestis 2020-05-15T18:36:37.132700Z

Their various hooks seem to be doing a lot of stuff - 4-5 useEffect calls

orestis 2020-05-15T19:07:29.135100Z

Hm, watching now the recoil video. The application that the guy is building is (I think) at the far end of SPA. A ton of data, a ton of components, plugins that affect code splitting etc.

orestis 2020-05-15T19:08:44.137100Z

I still find it frustrating that to do something like recoil you need to reach into unstable/undocumented React features. (Batched updates, priorities etc).

orestis 2020-05-15T19:09:58.138500Z

But at the core idea is mutable shared state propagated via hooks so leaf components can rerender individually.

orestis 2020-05-15T19:10:25.139100Z

Which is what Iā€™m trying to do with reseda so Iā€™m happy

lilactown 2020-05-15T19:14:01.139700Z

yeah I think scoping the state to the component tree vs. truly global is the most interesting design decision

lilactown 2020-05-15T19:14:51.140700Z

Iā€™ve been working on something thatā€™s similar sort of reactive, incremental dataflow but my goals so far have been to help with state that lives outside the component tree

lilactown 2020-05-15T19:16:48.142Z

Iā€™m interested to see if thereā€™s a way to design something that could handle global state and state scoped to individual trees

orestis 2020-05-15T19:21:50.142900Z

Whatā€™s the point of scoping state ton component trees? Testing/DI?

dominicm 2020-05-15T19:22:28.143Z

Yep. Devcards, stuff like that.

dominicm 2020-05-15T19:22:35.143100Z

I quite like that idea - taking the name of the state and scoping it to the tree by registering the name behind a facade. You need a custom swap! then though, which is a shame.

lilactown 2020-05-15T19:26:21.143800Z

testing, DI, and SSR

lilactown 2020-05-15T19:26:44.144200Z

yeah the biggest design problem is you need some way of scoping mutations

lilactown 2020-05-15T19:26:53.144400Z

that isnā€™t gross to type šŸ˜›

lilactown 2020-05-15T19:27:16.144900Z

(send! scope ref inc) is a lot to type/remember

lilactown 2020-05-15T19:27:29.145300Z

(with-scope scope
  (send! ref inc))
might be better

lilactown 2020-05-15T19:30:14.146400Z

or, you could scope a ref at creation, so something like:

(def scope (create-scope))

(def ref (create-ref scope 0))

(send! ref inc)

orestis 2020-05-15T20:12:20.147200Z

Thatā€™s truly mutable scope though, right? Not even an event dispatch :)

orestis 2020-05-15T20:13:08.148Z

Iā€™m just happy that Clojure gives us enough primitives to build these things in the app.

āž• 1
lilactown 2020-05-15T20:22:19.148500Z

events are just a different kind of message to send šŸ˜‰

Aron 2020-05-15T21:21:56.148700Z

yeah, too low level