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

ratom update within render function does not cause a re-render #552

Open
john-shaffer opened this issue Dec 15, 2021 · 2 comments
Open

ratom update within render function does not cause a re-render #552

john-shaffer opened this issue Dec 15, 2021 · 2 comments
Labels

Comments

@john-shaffer
Copy link

Reagent version: 1.1.0
Repro:

(defn DocsBad []
  (let [state (r/atom {:versions nil})]
    (fn []
      (let [state* @state
            {:keys [versions]} @state
            version-entity-ids [1]]
        (when (not= versions version-entity-ids)
          (swap! state assoc :versions (vec version-entity-ids)))
        [:div (pr-str state* @state)]))))

Expected: Component renders at least twice and results in [:div "{:versions 1} {:versions: 1}"].
Actual: Component renders once and results in in [:div "nil {:versions 1}"] (unless something else causes a render).

@Deraen Deraen added the blocked label Dec 19, 2021
@Deraen
Copy link
Member

Deraen commented Dec 19, 2021

I tried using this component in a project, and I'm seeing {:versions [1]} {:versions [1]} rendered. I also tried adding some console.logs on the fn body and inside when form, and I can see the update is called once and render is first called with {:versions nil} and then with the updated value.

@rmschindler
Copy link

If I run the code which @john-shaffer provided as is (reproduced here for clarity)...

(defn DocsBad []
  (let [state (r/atom {:versions nil})]
    (fn []
      (let [state* @state
            {:keys [versions]} @state
            version-entity-ids [1]]
        (when (not= versions version-entity-ids)
          (swap! state assoc :versions (vec version-entity-ids)))
        [:div (pr-str state* @state)]))))

...I get {:versions nil} {:versions [1]}. The view component is being rendered once.

It may help to share that if I run the following modified code...

(defn DocsBad []                                                                                    
  (let [state (r/atom {:versions nil})]                                                             
    (fn []                                                                                          
      (let [state* @state                                                                           
            {:keys [versions]} @state                                                               
            version-entity-ids [1]]                                                                 
        (when (not= versions version-entity-ids)                                                    
          (r/next-tick (partial swap! state assoc :versions (vec version-entity-ids))))             
        [:div (pr-str state* @state)]))))

...I get {:versions [1]} {:versions [1]}. The view component is being rendered twice.

Note that the difference merely involves using the next-tick Reagent function, so that the swap! is the tiniest bit deferred.

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

3 participants