Fork me on GitHub

@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"


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.


Is this a case of outdated docs?


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.


@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."


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


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.


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


 (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))))))


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


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)


I’m not familiar with new reagent


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


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


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


Hmm, then I still don't understand it simple_smile


which is something you don’t want


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


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


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


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


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