This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-11-24
Channels
- # announcements (2)
- # beginners (130)
- # calva (72)
- # cider (4)
- # cljdoc (15)
- # cljs-dev (3)
- # cljsrn (2)
- # clojars (4)
- # clojure (55)
- # clojure-nl (1)
- # clojure-uk (19)
- # clojurescript (46)
- # cursive (95)
- # datomic (6)
- # figwheel (40)
- # fulcro (12)
- # hyperfiddle (3)
- # off-topic (11)
- # onyx (3)
- # parinfer (6)
- # pathom (15)
- # protorepl (38)
- # re-frame (67)
- # reitit (18)
- # shadow-cljs (45)
- # tools-deps (2)
Ah nice thanks easier than I thought đ
anyone heard of re-frame being used in a chrome extension before? the relevant challenge is that the app-db would have to live in what's called a "background script" that is communicated with asynchronously by short-lived clients that render the actual HTML (in my case "popup pages", which are created when you click on the extension's icon next to the browser bar and are destroyed when you click away)
i feel like this should definitely be possible because event handling is asynchronous in the first place (just adding some additional asynchronous "IPC" via these chrome APIs into the mix) but the question for me is whether it'd be worth it đ
Iâm not sure what youâre asking. Is it possible? Absolutely. Is it good? Maybe?
I imagine it would be, since coeffects + dispatch should be an easy way to model the message passing to and from your app
i think i will have to apply my forehead to the wall on this for a bit to come up with some better questions đ. thanks for looking.
This is a re-frame + reagent question. If you setup a component like so:
(defn c [x]
(let [foo (subscribe [:foo])
(fn [x]
(let [bar (subscribe [:bar @foo]
zoo (subscribe [:zoo]...
possible you should never set things up this way, and thats part of my confusion. But assume this is a valid setup, then its a bit unclear to me how and when things are evaluated.
1. when c
is called i would assume everything updates and we return a new render function.
2. when :foo
changes but c hasn't been called with a new x then i assume the render function returned from c doesn't change as it was never called. This is probably the confusing part to me, as a subscription is global, so the alternative seems plausible as well.
3. when c
is called then i assume we return a new render function. If then bar changes then we don't change the render functions output?AFAIK, in reagent you will need to create the dependent subscription (subscribe [:bar @foo])
in another component
I would expect that c
is only called once, to obtain a rendering function, and that the rendering function is the only thing called thereafter.
Once per component in the DOM, that is.
I mean, if there is another view that c is part of, then if the arguments to c, change, i would expect it to update right?
Ill put it this way, does a subscription inside a view, always mean that view is re-rendered if the subscription updates? like if :zoo
updates, it would take the value we closed over for @foo
the last time c's render function ran and pass that in?
thanks for the feedback btw
i. it depends on if you dereference the subscription
ii. with a form-2 component, the intial function body (let [foo ...]
is only run once per instantiation
I would not expect c
to be called a second time if the value of x
changes, unless x
is a subscription.
so (subscribe [:foo])
in this case will only ever be run once, unless you completely blow the UI tree away and re-instantiate the component
It would be easy enough to throw in some println's or console.log's and see if I'm right tho đ
your second point @drewverlee is correct, that when the view is re-rendered (the returned function is re-run) it keeps all closed over values e.g. foo
> I would not expect c
to be called a second time if the value of x
changes, unless x
is a subscription.
that makes sense to me.
> so (subscribe [:foo])
in this case will only ever be run once, unless you completely blow the UI tree away and re-instantiate the component
> even if you pass in new props x
thats if x isn't a subscription itself right?
ah, i see what your saying
if you dereference it, then it will re-run wherever you dereference it when that ratom emits a new value
(defn c [x]
(let [foo (subscribe [:foo])] ;; <-- ran only once per instantiation
(fn [x]
;; these will be ran on each re-render
;; e.g. a new `x` passed in or `foo` updates
(let [bar (subscribe [:bar @foo])
zoo (subscribe [:zoo]...
now letâs say you dereference both bar
and zoo
inside of the body of your render fn
your component will probably behave as you would kind of expect; it will re-render any time foo
bar
or zoo
change
the only kinda-bummer is that you are subscribing and disposing the old subscription on each render. but actually subscribe
might be memoized, I canât remember
hmm, ok. i might get it. I'll need a minute to try things out and let it sink in.
there are also some tricks to get c
to completely re-initialize when x
changes if you want to know đ
The latest version of re-frame does do subscription caching, so it's cool to subscribe and de-ref in the same line of code.
if i cause an effect from inside an event-handler, is that effect handled synchronously? in other words, if i dispatch
an event via dispatch-sync
in an :on-click
handler, is the complete process synchronous?
e.g.:
(reg-event-fx :foo
(fn [cofx _]
(async-fetch-data) ;; <-- asynchronous AJAX request, will not wait
(assoc cofx :db {:foo "fetching"}})))
the function will not wait for async-fetch-data
to complete before returningotherwise, re-frame will add the dispatched event to a queue and handle them in order
my problem is safari being weird about playing audio. i do click button -> create element, set src, play it basically
and if play isn't called in the event handler of the click (i.e. when the user interacts) safari thinks somebody is trying to annoy the user by autoplaying
https://github.com/heyarne/safari-sounds if you're interested
so it would seem there are two ways to approach getting data to your views, with reagent and re-frame. The view can have subscriptions that query the data and your view just subscribes to that, or the data can be passed into the view and from their be used in subscriptions or used directly. The methods would seem to be interchangeable, is that right?
youâre talking about the difference between:
(defn show-foo []
(let [foo (subscribe [:foo])]
(fn [] [:div @foo])))
and
(defn show-foo [foo]
[:div foo])
;; elsewhere
(defn app []
(let [foo (subscribe [:foo])]
(fn [] [show-foo @foo])))
theyâre not exactly the same, right? the first one has an explicit dependency on the :foo
subscription to get itâs data
say we had a ton of foo
âs to render in our app, we wouldnât want to subscribe to a single foo inside of the same component that defines how it should look and behave
thereâs also the matter of displaying the componentâs various UI states in devcards and testing it
> say we had a ton of foo
âs to render in our app, we wouldnât want to subscribe to a single foo inside of the same component that defines how it should look and behave
Sorry, what does this mean? why would you need to subscribe to foo more then once in a component?
you would subscribe to a todo-list then right?
right, you would subscribe to the list in a component that would then pass the data for each to-do
in as props