Fork me on GitHub
#re-frame
<
2015-12-29
>
mbertheau16:12:06

@mikethompson: I'm using reagent 0.5.1 and re-frame 0.5.0 and I find the following statement in the re-frame readme to be wrong: "subscriptions can only be used in Form-2 components and the subscription must be in the outer setup function and not in the inner render function"

mbertheau16:12:59

I.e. I'm having a component (defn offered-for-display [id label-text open?] [w/textarea {:id id :label-text (str label-text (rand-int 10)) :value @(rf/subscribe [:current-offered-for-string]) :on-click #(reset! open? true)}]) and the rand-int value doesn't change when app-db changes.

mbertheau16:12:05

Is this a case of outdated docs?

darwin16:12:59

mbertheau: if I read your post correctly, I believe your code example does not use form-2 component, it uses basic form-1 component and subscription is made in the render function. In other words, your code cannot prove anything about that particular documentation snippet being outdated.

mbertheau16:12:31

@darwin: the docs go on to say "Well, this component [an example form-1 component with a subscription in the render function] would be re-rendered every time app-db changed, even if the value in name-ratom (the result of the query) stayed the same."

mbertheau16:12:49

That's the exact part of the docs that I'm referring to.

darwin17:12:08

mbertheau: ok, maybe you are right, the docs should say, that the call to subscribe returns a new reaction and component gets re-rendered every time the reaction signals a new change. And that depends on how that reaction was created. It also depends on reagent implementation I would guess (there were some changes between new reagent 0.5.1 and previous versions.

darwin17:12:36

can you share your call to (register-sub :current-offered-for-string …) ? how did you create the reaction? maybe new version of reagent is smarter about caching previous values and not announcing a change when app-db changes, but your particular value the reaction is watching does not

mbertheau17:12:33

(rf/register-sub
 :current-offered-for-string
 (fn [db]
   (reaction (let [choices (rf/subscribe [:get-in [:places-of-business]])
                   values (rf/subscribe [:get-in [:product :for-whom :places-of-business]])]
               (s/join ", " (map #(:name (@choices %)) @values))))))

darwin17:12:57

so you are using chained reactions, I think reagent won’t signal a change on reaction if reactions it depends on didn’t change in value, try to deref app-db somewhere inside the (reaction …) macro call, I would guess then it starts behaving as stated in the docs

darwin17:12:15

and by “change in value” is judged by identical? (which changed in recent version of reagent I guess, now it is configurable to use = as well)

darwin17:12:27

I’m not familiar with new reagent

mbertheau17:12:21

@darwin so the warning "Don't subscribe in form-1 components" is not justified anymore, do you agree?

darwin17:12:50

no, I think you are using subscribe inefficiently (maybe incorrectly in that code snippet), subscriptions should be created outside of that (fn …)

darwin17:12:08

it will probably work, just the subscriptions will be re-created on every change

mbertheau17:12:12

Hmm, then I still don't understand it simple_smile

darwin17:12:17

which is something you don’t want

darwin17:12:56

I’m not expert in this, reagent reaction system is quite complex and I wasn’t able to understand it fully even after trying to read the sources

darwin17:12:04

simple rule to avoid mistakes is to never create reactions in other reactions, always create them “outside” and just use them in reactions by dereferencing them

darwin17:12:18

your render functions are reactions (reagent creates them under the hood), that is why you want to do subscribe as form-2 components

darwin17:12:03

form-2 allows you to specify some “init” code and then actual reaction functionality as fn

darwin17:12:58

but the rule of not creating reactions in reaction functions is general, it applies to your own code creating reactions as well