Just starting out with Reagent. I have a button whose :on-click
value causes a CPU-intensive function to run; it takes a long time to return. I want to update the text of the button itself to notify the user that one might have to wait, so I define a ratom that will specify the button text, and then I reset!
the ratom while the function is running.
This works if I define the ratom outside my button component function, but fails to work if I define the ratom inside the component function via let
, or if I reset!
the ratom at the top level in the component function. That is, the button text fails to change if I uncomment the first commented line below, or uncomment the two lines for the let
. Am I doing something wrong? Is this expected behavior? What is the general rule about ratoms and DOM-updating that applies here?
(def label (reagent.core/atom "Make chart"))
(defn chart-button
[normal-label running-label]
; (reset! label normal-label) ; reset globally-defined ratom
; (let [label (reagent.core/atom normal-label)] ; use local ratom
[:button {:on-click (fn []
(reset! label running-label)
(js/setTimeout (fn []
(cpu-intensive-function)
(reset! label normal-label))
10))
}
@label] ;)
)
...
[chart-button "make chart" "running..."]
...
(Not relevant, but for clarification: I use the setTimeout
trick described here to cause the DOM to update despite the fact that the long-running function would otherwise prevent the browser from updating the DOM while the function is running.)