1👍
The usual pattern you follow in this case is to wrap the stateful/mutable object in a React component and use React’s lifecycle methods.
The approach is described in detail in re-frame
‘s Using-Stateful-JS-Component but this is how I tend to do it with D3:
(defn graph-render [graph-attrs graph-data]
;; return hiccup for the graph here
(let [width (:width graph-attrs)
height (:height graph-attrs)]
[:svg {:width width :height height}
[:g.graph]]))
(defn graph-component [graph-attrs graph-data]
(r/create-class
{:display-name "graph"
:reagent-render graph-render
:component-did-update (fn [this]
(let [[_ graph-attrs graph-data] (r/argv this)]
(update! graph-attrs graph-data)))
:component-did-mount (fn [this]
(let [[_ graph-attrs graph-data] (r/argv this)]
(init! graph-attrs graph-data)))}))
(defn container []
[:div {:id "graph-container"}
[graph-component
@graph-attrs-ratom
@graph-data-ratom]])
It is important to keep the outer/inner combination because React won’t populate its props correctly otherwise.
Another thing to be carefully of is the return of the reagent/argv
vector, which, as you can see, contains the props after the first item. I have seen (reagent/props comp)
in the wiki page above but I have never tried it myself.
Source:stackexchange.com