This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-19
Channels
- # aleph (3)
- # beginners (90)
- # boot (1)
- # cider (1)
- # cljdoc (23)
- # clojars (1)
- # clojure (91)
- # clojure-dev (8)
- # clojure-greece (1)
- # clojure-italy (17)
- # clojure-japan (1)
- # clojure-nl (6)
- # clojure-spec (4)
- # clojure-uk (89)
- # clojurescript (48)
- # core-async (5)
- # cursive (79)
- # datascript (1)
- # datomic (40)
- # duct (1)
- # emacs (7)
- # figwheel-main (2)
- # graphql (7)
- # jobs (5)
- # nyc (5)
- # off-topic (61)
- # other-languages (2)
- # parinfer (6)
- # re-frame (63)
- # reagent (131)
- # ring-swagger (6)
- # shadow-cljs (158)
- # spacemacs (14)
- # tools-deps (15)
I think Redux/Flux-like architecture is a nice way of managing state because it's a very clear way of managing state. Have also been using MobX recently on a new project so we will see how that grows.
Though this is a Clojure forum so I won't talk about MobX too much. I have also tried to use Hoplon in Clojure(script) land, but the HLisp stuff kind of rubs me the wrong way honestly
I think as long as we are discussing state management MobX has to be in the mix. And we are discussing React rather prominently, which will not get converted to CLJS until v42 according to their roadmap. I made that up.
Redux/Flux is clear from 30k feet and next thing you know we are watching 24 free videos and still struggling to do what we want to do. Productivity tools are supposed to save developer energy, not consume it.
Hoplon is great, Matrix is great, binding.scala is great, but MobX is the dataflow mindshare leader. The CLJS community might want to choose carefully in this space.
have you ever built anything with MobX? very tricky to get right. it is very hard to monitor arrays in javascript and requires coding by convention. reagent’s atom system blows mobx out of the water.
also, where did this ‘dataflow’ terminology come from. in my world, this is called the ‘observer pattern’ from the GoF book
Have been using mobx-state-tree/mobx recently and not sure how I feel about it yet. The main positive aspect so far seems to be a lot less boiler plate/things getting in my way. My main concern with it is readability as the code base gets larger + being able to debug/test it (Redux is so easy to debug/test).
Reagent + ratom remains kind of a personal favourite, Re-frame isn't so bad but similar problems to Redux where I feel it gets in my way a lot
my memory of mobx is that you can’t observe a blank portion of the state. you can do that with ratoms. i.e. you can create a cursor to something that isn’t there and then you get a re-render when it loads. stuff like that just works better because mobx is kind of a filthy (but awesome) hack
I think that's the real heart of why ratoms are great, because they are really just a part of the language, they are very idiomatic
mobx is also synchronous, if i recall, which is kind of tricky to deal with if you’re not thinking carefully about whether a mutation might cause another mutation
This is true, and why mobx-state-tree/mobx in strict mode forces you to wrap state changes in actions
It's magic written in a language, that compiles to a language, that compiles to a language, that uses magic (react) and compiles to a language and...
Not to mention that the compilation happens on magic written on a language, that compiles to a language, that compiles to a language that...
the distinction for me is that I understand why reagent works: there’s a level of indirection that is built into cljs: specifically the fact that you can only manipulate atoms by deref
ing them. reagent inserts itself right there in that single place. mobx is doing screwball things to intercept direct object accesses and array manipulations.
sure, Reagent definitely doesn't feel like magic if you know Clojure, it just feels like a natural way of doing things/a slight extension of what you know
And I am surprised every time it works, especially in non-strict mode (which I think they have basically acknowledged was a bad idea, though it rules for prototyping)
to be clear: i’m a much stronger js programmer than cljs programmer still. my years of C++ are hard to shake 🙂
If we are surveying the field we are at 30k feet, so I would not exclude any library from discussion over details. If MobX is insufficiently granular, fine. Does it offer anything on transparency? Hoplon/Javen is limited by the “lifting” mechanism. Fine, but is it too great on transparency? Re-frame has a beautifully clear domino thing. Does that mean explicitly coding subscriptions and events? There is no superficial way to explore this space.
ah well that’s the issue. i’m not at 30k feet. I’m building product. everything looks good at 30k feet. 🙂
What are you using now?
And will you use that forever because to survey the choices means stopping typing? 🙂 I understand!
Reagent is great. Keep an eye out for the glitches if you ever see something that makes no sense.
i never said anything was excluded or that we shouldn’t talk about it. if i didn’t want to talk about it i wouldn’t be here. i’m interested to hear what milomord and anybody else who actually uses this stuff has to say
i’ve offered my thoughts as to why mobx is hard to use, which came from practical experience
I started with React on a hefty exercise and in two widgets realized why Abramov did Reflux. Re-doing those two widgets with Redux told me how brilliant are the CLJS React wrappers.
I am grateful for the input from a hardcore JSer on MobX. I just surfed the doc and took a deep dive into the internals to explore its solution to glitches, but a real user such as yourself offers great perspective.
I am too early on in my Mobx/Mobx State Tree exploration to offer advice on practical drawbacks/pitfalls unfortunately, but very curious to see how it goes for me
FWIW, I have not yet used it in anger but it feels like React context + suspense attacks the same generic problem as Redux and Reagent (with ratoms) but in a much simpler way
My experience of Reagent/ratoms has been 'joy to work with' pretty much, though it does give maybe too much freedom to me
@milomord be sure to read and understand https://mobx.js.org/best/react.html because you will be bitten by some of that unless you are careful to write code to avoid these pitfalls
esp. suspense I feel like is moving us towards shaking off the "only the V in MVC" lie that we've been using to sell people on React for awhile 😉
Thanks @lee.justin.m, I have already stumbled upon this after being bitten!
@milomord The True Lisper holds sacred the right to shoot off their own feet with too much freedom.
But I am generally not thrilled with React's own solutions to state management so far
I think they know this hence why they pushed people toward Flux/then Redux and obfuscated the context api somewhat
damn, missed suspense — googling
As I understand Suspense (not that well), it is more about waiting for network requests to complete
The very best thing in the world is the React doc on context
saying “no matter what you do, do not use context”.
AFAICT after 16.3 that's old advice. the new context API has been deemed production ready
the reason that they suggested not to use the old context API was because it was likely to change
honestly I never liked the idea of context within React but I forgave it because it makes some things slightly easier (eg, routers/outside stores)
There was a funny video where someone asked the Facebook team (at an open conference) about context and one of them turned to the others and said, “I told you they would find it.
most of the uses of state management libs have to do with 2 concerns: 1. plumbing state 2. reacting to side effects context addresses 1. suspense (begins to) address 2
And apparently one we need, in turn a refutation by example of the whole idea of isolation. It’s all connected, spaketh Buddha.
Thing is, I actually think I like React just being the view layer/a declarative view layer
Yeah, and now I see they have some insanely elaborate “forward ref” thingy that let’s us get at the dom.
And if FB are interested in turning it into a more fully fledged framework/standalone solution I will watch with interest but
View and model are one. (Prepare the tar and feathers.)
guilty
Actually, I lied. All my views have a value
slot. For the model object.
My guess? They spent three months trying to figure out state management, came up short, and decided to make the gaping whole a feature by bragging about how they were not telling us how to manage state. But we had to use Flux,
I think it's a feature that React has not implemented a lot of what has been filled in by other user-space libraries libs up until now
because you're right, they didn't know how to do it correctly. I don't know anyone who does
if they’d implemented a state management library you’d be complaining that their solution isn’t composable and isolated
Flux, Redux, MobX, etc. are great experiments that the React team and community has learned a ton from
and we're starting to see the fruit bear in the form of new React APIs that address those concerns, but at the framework-level
“I don’t know anyone who does.” raises-hand
They are only making things worse, doubling down on more and more framework in knee jerk solutions to every problem the user community brings to them.
if that had been the case then they would have integrated Flux, or Redux, into React
@lilactown I understand the skepticism! But I have been at this for 22 years so I am comfortable with the raised hand. See how far you get with this: https://codepen.io/kennytilton/pen/mXQNYR
@lilactown did you miss this? You asked me to produce it and said I was full of shit, so I think that means you have to read the whole thing and do the exercise on frame 6 and blog about what you learned. 🤞
react has been around for 5 years. they’ve cleared 10,000 bugs! definitely not “knee-jerk”
facebook has ~50,000 react components in their own internal codebase. these guys are not shooting from the hip
Redux was a failure. MobX — imperfections acknowledged! — has been eating its lunch with its transparency. Transparency being a buzzword for “we work out the dataflow, you just write the natural expression of your semantics”.
@hiskennyness I'm not questioning your experience. But I fundamentally think that anyone who claims they have the solution to designing and creating UI applications is full of shit
I’m not questioning your language skill, but I think you just questioned my experience. :rolling_on_the_floor_laughing:
For a second, @lee.justin.m, I thought you were describing CICS. 🙂
I've talked with Jordan Walke and other people who are involved in React / ReasonML and they are all incredibly intelligent, and humble enough to admit that they don't know a lot of answers. some of the questions we don't even know yet
I will take that as a compliment, @lilactown
Just look at the results. They are flailing. And yet they persist. Do you know what it looks like when smart engineers are not expereinced enough to realize they have done bad work?
See “StoneHenge”. Or Ivan Sutherland doing a CAD system in assembler in 1963 with nothing but a light pen that “read” the 1024x1024 CRT screen. The question is, what was the wasted effort using a deficient UI?
What if there is a “the solution”? Would that be a problem in that it violates our meta-certainty of what is possible? Long before Paris the editor of a beekeepers journal saw the Wright brothers flying around a field outside Daytona. He wrote to the Smithsonian to say OMG! The Smithsonian wrote back to say it was impossible, if anyone could fly like that it would have been in the papers. That only cost them a stamp.
Getting back to Suspense, here is a funny story about how dataflow handles Callback Hell without missing a beat (surprised even me): https://github.com/kennytilton/xhr/blob/master/cljs/xhr/XHR.md
Has anyone come across reagent not re-rendering when the sort order of a subscribed to sorted-map changes? I am guessing it is doing (= sort-map-asc sort-map-desc)
when checking props and that returns true whereas (identical? sort-map-asc sort-map-desc)
would return false causing a re-render but I am not 100% sure
Pardon a dumb question, but how does the sort order of a sorted-map change? Do you mean sorted-map-by
? But I think your guess is right about =
being true will get in the way of reagent detecting the change.
Yeah, an event will change the sort order of the map and the subscription will use sorted-map-by
to return the sorted map
Hmm, in a repl I just got
`(= (sorted-map-by < :a 2 :b 3) (sorted-map-by :b 3 :a 2)) => false
Oops, forgot the comparator…This is better:
`(= (sorted-map-by < :a 2 :b 3) (sorted-map-by > :b 3 :a 2)) => true
`@jamesthibaudeau i think your diagnosis is correct: because sorted maps with different comparators are =
, reagent will not re-render
Ooops: “For ratoms, identical? is used (on the value inside the ratom) to determine if a new value has changed with regard to an old value.”
https://github.com/reagent-project/reagent/blob/master/doc/WhenDoComponentsUpdate.md
“For props, = is used to determine if a new value have changed with regard to an old value.” (from the same link)
Make sure, of course, that you are dereferencing the ratom. The ratom remains identical?
Confirmed:
(def sorted-state (reagent/atom (sorted-map-by < [0 "zero" 1 "one"])))
(defn child-component
[s]
(js/console.log "child-component")
[:div (pr-str s)])
(defn test-component
[]
(js/console.log "test-component")
[child-component @sorted-state])
(js/setTimeout (fn []
(js/console.log "updating comparator")
(reset! sorted-state (sorted-map-by > [0 "zero" 1 "one"])))
1)
prints test-component
child-component
updating comparator
test-component
if you change the reset to (reset! sorted-state @sorted-state)
then the second test-component doesn’t print
sorted-map-by
wants its keyvals as &rest args, right?
[comparator & keyvals]
the only thing that matters is that sorted-map is =
with different comparators, and when passing props, reagent performs an =
check
what I think I will do is have my subscription return {:order :asc :data sorted-map-asc}
or the corresponding desc version
have reagent check the equality on that map instead of the sorted map itself
you can probably do something with protocols / types such that you have a version of sorted map that has different =
semantics but being explicit is probably better
yeah, could do it that way too, thanks for your help guys!
is there a different approach to scroll
event handler in reagent? all the other events seem to fire, except this one:
(r/create-class
{:component-will-mount
(fn []
(.addEventListener js/window "scroll" #(js/console.log "hello")))
...
})
@lilactown did you miss this? You asked me to produce it and said I was full of shit, so I think that means you have to read the whole thing and do the exercise on frame 6 and blog about what you learned. 🤞