This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-08
Channels
- # architecture (20)
- # beginners (140)
- # cider (155)
- # cljsjs (1)
- # cljsrn (29)
- # clojure (53)
- # clojure-dev (9)
- # clojure-italy (40)
- # clojure-nl (13)
- # clojure-poland (4)
- # clojure-russia (8)
- # clojure-uk (51)
- # clojurescript (74)
- # cursive (36)
- # data-science (1)
- # datomic (3)
- # emacs (14)
- # fulcro (11)
- # graphql (2)
- # java (21)
- # javascript (2)
- # jobs (3)
- # nrepl (7)
- # off-topic (18)
- # om-next (1)
- # onyx (9)
- # portkey (8)
- # re-frame (72)
- # reagent (64)
- # reitit (4)
- # remote-jobs (1)
- # rum (1)
- # schema (1)
- # shadow-cljs (49)
- # slack-help (1)
- # spacemacs (8)
- # specter (7)
- # tools-deps (27)
- # vim (28)
I have a vague question about CLJS + Reagent. Specifically I'm curious about the origins of the monolithic 'app-state' design pattern, where you have a global object whose state cascades through various conditional rendering paths belonging to a bunch of (otherwise stateless) application components. Where does that pattern come from? Is it a Reagent idiom?
Oh quite possibly. I'm curious mainly if it has analogues in some sort of native Javascript framework? When I picked up Reagent a few years ago to build my first web app I was under the impression the 'app-state' atom was a React convention, but the React applications I've built/learned from have all been burdened with a troublesome amount of local state, this
pointers, locally-scoped objects, etc.
Which might have some practical utility, but it's strikingly different than the architecture of a Reagent app as I remember it.
That's an interesting historical question. Hmm: "because we always have the entire state of the UI in a single piece of data, we can trivially serialize all of the important app state" in http://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs might imply that JavaScript approaches weren't yet doing that. But I'm speculating.
Fascinating, it seems like Nolen is foreshadowing Redux a bit with the suggestion of pairing React/Om with a stateless data structure like mori
i’m not sure who was first, but there is this notion of the “flux” architecture, which is pretty widely used and is supposed to be medicine for poorly structured local state
redux is the most common example. there is also the mobx library that is a much closer analog to the reagent atom idea
One interesting historical twist is how Om helped popularize React in a non-trivial way.
Is there a direct relationship between the "atom" object in a Reagent (cljs?) application and the props
attribute of a React component? I ask mainly because they both seem to have the odd property that you can't directly traverse them, instead you have to be somewhat coy and use destructured local variables to inspect particular components of it
the direct answer is no. reagent atoms are just mutable pieces of data (you can put anything in them). reagent implements an observer pattern by watching derefs of atoms during render. are props
really different in react? I always thought it was just a normal property on an object
@lee.justin.m Thanks for suggesting mobx, this does indeed seem a lot closer to Reagent-y ideas about state management I sorely miss 🙂
be careful with it. because you can’t fully proxy arrays in javascript, you have to be very careful with it or it just won’t work. i also found it hard to debug when things went wrong.
You might be right, I'm still shaky about the scope/stucture of props
in React. It's not clear to me that they can be referenced outside the local scope unless bound to some public attribute though, and if I'm not mistaken it's an inherent property of React components?
Ah, props
is just idiomatic for a component's parameter arguments. Which, right, are intrinsically scoped to that object
oh right so reagent maps positional arguments to props
and props.children
in a slightly funny way. positional args are mapped to props.children
, unless the first argument is a map, in which case that map is props
.
Interesting, is the type alone what differentiates JS objects from HTML DOM elements? "If it's a map then it's data, otherwise render it?"
it works and you never have to think about it until you do a bunch of interop code and your brain goes 🤯
Heh, is there a pattern you've found that's more robust in the face of messy, real-world interop constraints?
i’ve written down all the ones i know about in the interop doc on the /docs folder in reagent
I've been attempting to use JS React to render some word vectors to an interactive webGL canvas, but I'm really struggling to make all the components work together. I didn't have this problem at all in Reagent, the state was so blissfully monolithic
So I'm considering maybe switching back to Reagent, but having been away from CLJS for a minute, I'm interested to hear what's new and fashionable these days in the world of MVC architectures
so redux is a pain because it is so verbose, but you can be productive quickly and it works and is easy to debug. i would say its closest analog is re-frame.
You anticipated exactly the reasons I've been apprehensive to use redux 🙂 It probably is quite close to what I'm looking for, though. Do React components still ordinarily have local state when paired with Redux, or is it more common to isolate the entire world state in the Redux Store object?
either. common advice is: does anything else need this state? then put it in the redux store. if it is truly local, then local setState is fine
Also do you have any recommendations for Redux tutorials? I think some of my previous missteps have been due to getting bogged down in ceremonious optimization details like, uh, const ACTION_NUMBER_259 = "ACTION_NUMBER_259"
just follow the egghead videos and docs on the website itself. and embrace the verbosity. you’ll drive yourself mad if you don’t. it’s really not that bad and there is payoff in having code that is dead simple.
Alright, you've convinced me to give it another shot. 🙂 It was an open question in my mind whether the verbosity of Redux is itself an argument for using Clojurescript since the ceremonial details specifically seem to be ways of staying sane in a world full of mutable objects
I mean yes, you should definitely use clojurescript 🙂 It’s way better. But if you just want to get productive in pure javascript, then react+redux is pretty straightforward and you’ll recognize lots of ideas from it.
The only thing I find holding me back from using cljs is I'm sending and receiving a lot of server-side data and it's not particularly clear to me after looking at a few examples how to render an HTTP response in clojurescript => data. On the other hand I wonder if I understood core.async a little better...
I’m writing an app that is basically a crud over a RESTish api to a node-js backend. I settled on using the promesa library with cljs-ajax. So far so good. People seem to love core.async but I found its handling of exceptions to be hard to deal with, and, generally, it seems like overkill for the kind of normal crud operations that I do. If you are familiar with promises, you might find that combination easier to deal with.
Though I’m not sure quite what you mean when you say “render an HTTP response in clojurescript => data”
So an example would be typeahead, where the input field is possessed of some onChange handler whose job is to send HTTP requests to a database API endpoint. It also has to have some corresponding method for receiving the response, rendering the response to the page, handling the event that the user selects an available option from the menu of suggestions, etc.
Of course there are ready-to-wear components/libraries implementing a far better typeahead component than I could cobble together myself, but there are other more niche operations I would need to figure out on my own, like how to pass an array of floats received from the server to a webGL renderer
right so there are a ton of engineering tradeoffs with something like that, but I think the answer is: you do in reagent whatever you’d do in javascript. the only difference is that instead of calling setState
or firing off a action in redux, you will just do a swap!
on an atom
or if you are using re-frame you’ll instigate the co-effect interceptor or whatever crazy thing you do there 🙂
ha! I've read the re-frame description of "nested state machines" which sounds similar to Reagent's architecture but I haven't had the chance to use it. What's the biggest difference vs. Reagent? There are interceptors?
Hi. You can check this faq about why to use re-frame: https://github.com/Day8/re-frame/blob/master/docs/FAQs/DoINeedReFrame.md. I like it because I wouldn't know how to nicely structure my app.
it adds a layer of state management on top of reagent. it is more explicit and there is more machinery. people who build large apps swear by it. i am poking fun of it a bit because there is so much terminology that it introduces. i think you can get by with reagent along for quite some time, but i haven’t built a big app with re-frame so maybe i’m missing out
what makes you think so? code executing in the browser by default is not instrumented to send the output back via the figwheel repl protocol
i say that because i see the outputs of prn's in my figwheel repl in CIDER and in the browser. I see the results of both prn and cljs.pprint/pprint
that's true when you eval code. but let's say you have some event handler in the browser that prints something. do you see that printed in the repl as well?
Are there any facilities to enable that behavior? For instance a lower-level browser api?
what does it mean by excluding def
with :refer-clojure
here in the cljs.spec code?
(ns cljs.spec.alpha
(:refer-clojure :exclude [+ * and or cat def keys merge])
https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/spec/alpha.cljs@cookyzed That's related to s/def
. I've looked at it before but never developed a full appreciation, given that def
is a special form.
You could build js and then publish it on npm
(https://docs.npmjs.com/getting-started/publishing-npm-packages). Don't forget to export required variables if you use advanced compilation (https://clojurescript.org/reference/advanced-compilation#access-from-javascript)
@U066TMAKS shadow-cljs is well-suited for creating NPM packages. Here's the relevant section in the user manual: https://shadow-cljs.github.io/docs/UsersGuide.html#target-npm-module
Any cursive + cljs users around? How do you run tests? I've just been using lein doo
but the output is very difficult to parse. And now that I'm getting spec errors, its very very unreadable
I've made pr into doo
to use humane-test-output
which should do better reporting: https://github.com/bensu/doo/pull/176.
Until that's merged, you can use [org.clojars.nenadalm/lein-doo "0.1.11-SNAPSHOT"]
(https://clojars.org/org.clojars.nenadalm/lein-doo).
I never tried to run test in any editor (using Emacs).
@U662GKS3F I added your lein-doo snapshot.. but my test output looks the same in the console
I have no idea what's the problem with newer cider (I use it just for src/
not test/
).
Hm, so i'll open that question up to any editors... how do ya'll view your test output?
@ramblurr have you looked at https://github.com/bhb/expound ?