Fork me on GitHub
#reagent
<
2021-12-14
>
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.

p-himik14:12:55

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

p-himik14:12:22

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

p-himik14:12:01

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.

p-himik14:12:16

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

john-shaffer18:12:59

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 https://cljdoc.org/d/reagent/reagent/1.1.0/doc/frequently-asked-questions/why-isn-t-my-component-re-rendering- 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]}`)

NoahTheDuke19:12:49

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?

NoahTheDuke19:12:16

state* is just a persistent hashmap

john-shaffer19:12:49

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

john-shaffer19:12:07

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

NoahTheDuke19:12:35

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

john-shaffer19:12:37

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