Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swap! on a <-state atom behaves differently from useState #24

Closed
danielneal opened this issue Feb 25, 2019 · 3 comments
Closed

swap! on a <-state atom behaves differently from useState #24

danielneal opened this issue Feb 25, 2019 · 3 comments
Labels
bug Something isn't working

Comments

@danielneal
Copy link
Contributor

I wasn't sure exactly how to explain this - it was an issue that came up as I was trying to implement drag and drop and had quite a lot of event handlers all over the place.

I've done my best to make a minimal reproduction, hope it's not too vague!

The component below sets up a timer which increments a counter.
The raw react version increments the number on every tick, it calls the version of setNum that takes a function. The hx version only increments once, but doesn't continue to increment, I think because it is holding a reference to the initial state.

(defnc Counter
  [opts]
  (let [num-hx (<-state 1)
        [num setNum] (react/useState 1)]
    (react/useEffect (fn []
                       (let [id (js/setInterval #(swap! num-hx inc) 1000)]
                         (fn []
                           (js/clearInterval id)))) #js [])
    (react/useEffect (fn []
                       (let [id (js/setInterval #(setNum inc) 1000)]
                         (fn []
                           (js/clearInterval id)))) #js [])
    [:div
     [:span @num-hx]
     [:span "/"]
     [:span num]]))
@lilactown
Copy link
Collaborator

lilactown commented Feb 25, 2019

I had encountered this before and thought I was using it wrong. Your example was helpful in that it illustrates the difference between useState and <-state.

I believe the problem is that the implementation of ISwap has an implicit dependency on the current value in the Atomified instance. When your initial closure is created with useEffect, it captures that initial value in the atom instance and never gets the updated value.

@lilactown
Copy link
Collaborator

93c43b8 removes the reference of the initial value in the ISwap implementation, fixing this defect.

I'll cut a release later tonight with this change.

@danielneal
Copy link
Contributor Author

Nice! Thanks - I'll try it out in my full example but this fix looks good :)

@lilactown lilactown added the bug Something isn't working label Feb 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants