re-frame

rolt 2024-03-07T13:57:23.797809Z

hello, I'm looking at the new lifecycles in re-frame alpha. I have a question about what it means for a subscription's dependencies. Let's say I have the following:

(reg :sub ::x
     (fn [db] (:x db)))

(reg :sub ::y
     :<- [::x]
     (fn [x _] x))
So ::y depends on ::x If I do:
(sub ^{::rf/lifecycle :forever} [::y])
I don't get any "Subscribe was called outside of a reactive context." warnings. Is ::x value also cached forever ? Or is it not cached at all ? I assume that it's simply not cached I do get the warning if I use the following:
(sub ^{::rf/lifecycle :reactive} [::y])
so I assume the warnings works properly for alpha subs too. Edit: I looked at the code, :safe is the default now so the answer is "it depends" :)

✅ 2
Kimo 2024-03-09T19:59:28.877239Z

Hey, thanks for trying it out. If you have any feedback, it would be great if you could add it to our https://github.com/day8/re-frame/issues/680 - ergonomics, underlying design pattern, or simply if you'd like more documentation, etc.

lwhorton 2024-03-07T18:04:41.484239Z

does anyone know about a re-frame (and/or reagent) reimplementation in pure js? long story short, my team is uncomfortable in lisp and doesn't see the benefits of working in a new stack via cljs. i still want to leverage the awesome ideas of re-frame (and the awesome idea of abstracting away react from reagent), if possible. reimplementing reframe's subscriptions, signal graph, registries, interceptors, and so on is a little daunting. it would be great if this already existed, and we could leverage it or help extend/finish the implementation.

p-himik 2024-03-07T18:06:36.974189Z

Haven't heard of a full thing, but I believe one of the guys from the React team has made a library for React that borrows atom and reaction concepts from Reagent.

👍 1
lwhorton 2024-03-07T18:08:26.073909Z

i think the thing most-scary about the implementation is that js doesnt have structural sharing. (= old-state new-state) in js will be a really expensive computation, and probably prohibitive for any reasonably large system. that makes the signal graph really expensive, and caching more complicated.

liebs 2024-03-07T18:13:39.557479Z

perhaps https://recoiljs.org/ ?

liebs 2024-03-07T18:13:51.930879Z

it's mentioned on the re-frame docs even

p-himik 2024-03-07T18:16:22.750109Z

> js doesnt have structural sharing Structural sharing by itself is irrelevant. What's relevant is how you compare the objects. You can avoid deep comparisons and do shallow ones as well. Ah, yes - Recoil is that library I mentioned above, forgot the name.

lwhorton 2024-03-07T18:21:23.043549Z

yes, that's correct - i'm not sure how to do fast equality checking in js, or if it can be done, without some lib like immutable which implements structural sharing. you might be able to get away with some fast-exit reducer, but in the worst-case you are going to end up comparing an entire app's state to itself a lot, i think?

lwhorton 2024-03-07T18:23:12.241349Z

also, writing js in an immutable fashion changes the surface area of your entire app. so for the purposes of getting constant-time equality checks, it's kind of a non-starter 😞 option.

p-himik 2024-03-07T18:23:22.553219Z

> i'm not sure how to do fast equality checking in js The question is, do you need to have fast equality checks? Are you sure you can't compare objects in a shallowly?

lwhorton 2024-03-07T18:28:21.410429Z

i suppose i'm not really sure. you can write a pretty quick shallowCompare between two objects (length test, key existence checks). but knowing when to rerender for a case like: { :open? true :child { :closed? false }} isn't it the case that only 2-level-deep objects (and beyond) necessitate a deepEqual comparison? im going to pour over recoiljs' implementation to see what's going on there. i think you might be able to do something that avoids a large deepEquals comparison by clever use of observables... but i should also just check the performance characteristics of a large amount of data with a brute-force deepEqual, too, huh?

p-himik 2024-03-07T18:33:30.439799Z

> isn't it the case that only 2-level-deep objects (and beyond) necessitate a deepEqual comparison? Why would anything necessitate a deep comparison? React itself doesn't care - shouldComponentUpdate returns true by default and exists for you to optimize the behavior on an as-needed basis. You can do the same. I would assume that Recoil does something similar, unless it uses some immutable data structures library.

lwhorton 2024-03-07T18:37:50.214069Z

oh, i did not think about the fact that shouldComponentUpdate defaults to true in baseline react. i haven't checked, but i assumed for years that reagent defaults to a simple = to determine the shouldComponentUpdate return. if that's the case i would think reagent is always more efficient at rerendering than react. awesome

p-himik 2024-03-07T18:39:27.975919Z

Maybe, maybe not. I haven't measured. Efficient enough for what I do - that is all I personally care about when it comes to efficiency.

💯 1
kennytilton 2024-03-08T23:59:53.941629Z

Does it have to sit on top of React? This is JS manipulating the DOM and CSS directly. https://tilton.medium.com/simplejx-aweb-un-framework-e9b59c12dcff