Fork me on GitHub

Hello I'm having trouble getting a form 3 CodeMirror component to re-render when I want it to. I have the component model-input, which is instantiated with a 'selected-measure' atom received from a subscription. I extract the code for the selected measure, and wrap in local-state atom code. I then instantiate the codemirror component with the code, and the component unwraps it and displays it. The model-input also has a dropdown which selects the measure and dispatches something that should trigger the model-input to re-render, and I would assume the codemirror also. I can see the local state in model-input is changing when the dropdown is changed, but the codemirror is not, and I don't get why. I'm guessing I'm either missing something in the form 3 component, or not understanding the re-render logic. Any thoughts? Thanks in advance


Here's an abbreviated version of the code if that's simpler

(defn app []
     [ "Model"]
     [model-input (rf/subscribe [:selected-measure])]]]

(defn model-input [selected-measure-atom]
  (fn [selected-measure-atom]
    (let [{:keys [name code]} @selected-measure-atom
          code (r/atom code)]
       [codemirror code {:name name}]

(defn codemirror [value-atom options update]
  (let [options (merge {:mode "clojure"} options)]
     {:reagent-render (fn [] [:div])
      (fn [component]
        (let [editor (create-codemirror
                      (rd/dom-node component)
                      (assoc options
                             :value @value-atom))]
          (.on editor "change"
               #(reset! value-atom (.getValue editor)))))})))

(defn create-codemirror [elem options]
   (clj->js options)))


I tried adding a component-did-update key to codemirror but it started doing some weird things, so I thought that was probably the wrong approach.


value-atom is never updated. You should get it from the new properties in the :component-did-update function.


Would value-atom (which is actually code) not be updated when the :selected-measure subscription fires in app?


codemirror is a form-3 component. Its [value-atom options update] arguments are used only when it's mounted. All the subsequent updates are passed to :component-did-update. Similar to form-2 components - the outer function receives its arguments when the component is mounted. All the subsequent updates change only the arguments of the inner function. Unless there's a :key metadata, but that's a whole other story.


Thanks! Not sure I've got my head around it TBH, but after adding the :component-did-update it is working now.

👍 1

Reagent and re-frame documentation is a great read that answers many similar questions.