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

Inconsistent states when there are two events in one cycle #47

Open
dfrese opened this issue Oct 26, 2020 · 1 comment
Open

Inconsistent states when there are two events in one cycle #47

dfrese opened this issue Oct 26, 2020 · 1 comment
Assignees
Labels

Comments

@dfrese
Copy link
Member

dfrese commented Oct 26, 2020

When two events happen "at the same time" (on one event loop), then a state cannot be updated consistently. That can happen with onClick on both a parent and a child (event bubbling), as in this example where the final state is not 2, but 1, although both events fire and both messages are handled:

(deftest bubbling-events-test
  (let [c1 (reacl/class "c1" this state [& more]
                        render (apply dom/div
                                      {:onclick (fn [ev]
                                                  (reacl/send-message! this :foo))}
                                      more)

                        handle-message
                        (fn [msg]
                          (reacl/return :app-state (inc state))))

        c2 (reacl/class "c2" this state []
                        render (c1 (reacl/bind this :x)
                                   (c1 (reacl/bind this :x))))

        host (js/document.createElement "div")
        cc (reacl/render-component host c2 {:x 0})]
    
    (let [inner-div (.-firstChild (.-firstChild host))]
      (react-tu/Simulate.click inner-div (js/Event. "click" #js {:bubbles true :cancelable true})))

    (is (= 2 (:x (test-util/extract-app-state cc))))))
@dfrese
Copy link
Member Author

dfrese commented Oct 26, 2020

Note that I don't know how this is solvable in the current model, as the link between the app-states is established in the 'render' clause, which is not evaluated between the events (by React). But you wanted to take a look, @mikesperber .

Also note that the same issue exists when changing the state in component-did-mount in the c1 class, which might be more common:

(deftest two-mounts-state-test
  (let [c1 (reacl/class "c1" this state [& more]
                        render (apply dom/div
                                      more)

                        component-did-mount
                        (fn []
                          (reacl/return :app-state (inc state))))

        c2 (reacl/class "c2" this state []
                        render (c1 (reacl/bind this :x)
                                   (c1 (reacl/bind this :x))))

        host (js/document.createElement "div")
        cc (reacl/render-component host c2 {:x 0})]
    
    (is (= 2 (:x (test-util/extract-app-state cc))))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants