Fork me on GitHub
#cljsrn
<
2020-11-06
>
pez15:11:53

I’m having troubles getting a RN switch component to behave. When I switch it is briefly toggles back before toggling to the intended position again. I have a feeling it is because I am doing it the wrong way. This is the way I’m doing it (using re-frame):

(defn my-switch []
  (let [enabled? @(rf/subcribe [:enabled?])]
    [switch {:on-value-change #(rf/dispatch [:set-enabled (not enabled?)])
             :value           enabled?}]))

frankitox15:11:24

Seems like a common performance problem in using reagent + re-frame. You could try using dispatch-sync + flush combo:

(defn my-switch []
  (let [enabled? @(rf/subcribe [:enabled?])]
    [switch {:on-value-change #(do (rf/dispatch-sync [:set-enabled (not enabled?)])
                                 (reagent.core/flush))
             :value           enabled?}]))

❤️ 3
pez15:11:44

I’ll give that a shot!

pez15:11:52

And yes, reagent is in the mix too. The problem started to be noticeable when I moved the switch state down a notch in the app-db structure. So it is quite deeply nested.

frankitox15:11:20

I don't see why that could be a problem, but I don't know enough about re-frame's internals. I usually have to sprinkle the code with those declarations, last time it happened when using react-native-draggable-flatlist. Sometimes I leave it as it is because the production build works a bit faster and the issue disappears there.

joshmiller16:11:55

@pez You can also keep the enabled? state in a local ratom.

(let [enabled? (r/atom @(rf/subscribe [:enabled?])] ...

pez17:11:28

Thanks! The sync-then-fush works great. With the local ratom I get a strange behaviour with it resetting on the first tap, then it starts to work. And, I think I see a slight performance difference. I have some content behind a (when enabled? …) and that content is more delayed with the ratom solution. The delay seems to be about as long as the glitch I had without these mitigations, so maybe it is really more “honest”, rather.