Fork me on GitHub
Pepijn de Vos13:12:46

What happens if you dereference ratoms in the outer function of a form-2 component? Will it simply never update?

Pepijn de Vos13:12:32

Here is my scenario: I want to display some async result. So I have a component that sets up a callback based on its parameters, and then I guess keeps some local ratom that the callback can update. Problem is, that would rerender the component, which would also set up a new callback.


But do you need to set up a new callback when the external parameters change?

Pepijn de Vos14:12:54

What I have done now is have a ratom, which has a watch that does the callback which sets another atom


Can't say for sure without the code, but that doesn't sound too unreasonable.

Pepijn de Vos14:12:50

Yea it's fine. My initial plan was to have the second atom as local state but that gave complications


I think in React you would use the useEffect hook with two arguments. Can't really think of a Reagent alternative off the top of my head.


But you can use useEffect in Reagent just fine as well.

Pepijn de Vos14:12:38

I'll just stick to the global state solution, it's not that bad


I'm not sure why this code doesn't rerender:

(defn DocsBad []
  (let [state (r/atom {:versions nil})]
    (fn [article-id]
      (let [state* @state
            {:keys [versions]} @state
            version-entity-ids [1 2]]
        (when (not= versions version-entity-ids)
          (swap! state assoc :versions (vec version-entity-ids)))
        [:div (pr-str state* @state)]))))
The pr-str gives {:versions nil} {:versions [1 2]} if nothing external causes a rerender I checked everything on If I change the swap! to (js/setTimeout #(swap! state assoc :versions (vec version-entity-ids))), it rerenders perfectly (`{:versions [1 2]} {:versions [1 2]}`)


you set state to {:versions nil}, and then deref it to state*, so state* is now {:versions nil}, not <reagent.core/atom {:versions nil}>, and then you swap! the value in state, but that doesn’t change state* because why would it?


state* is just a persistent hashmap


Because I expect it to get rerendered after every change to state


so the first render should show nil, but it should rerender immediately with the new value


i wonder if it doesn’t trigger a rerender because that happens before the hiccup is returned


It's easy to work around, but it took me a long time to isolate it, so it should probably be an entry on that page