3
votes

I have this form:

(defn input-question
  []
 (let [new-question (reagent/atom "")]
  (fn []
  [:div
   [:input {:type      "text"
            :value     @new-question
            :on-change #(reset! new-question (-> % .-target .-value))}]
   [:input {:type     "button"
            :value    "Save new question"
            :on-click #(re-frame.core/dispatch [:create-question @new-question])} ] ])))

How can I reset @new-question to "" (empty string) after the dispatch?

3

3 Answers

4
votes

You can use reset! on the ratom after dispatching:

#(do (re-frame.core/dispatch [:create-question @new-question])
     (reset! new-question ""))

to reset it after dispatching the value.

2
votes

You probably want to review the re-frame effects docs:

Note that you can also use dispatch-n:

and you might want to use the fn syntax instead of the #(...) shorthand function syntax:

:input {:type     "button"
        :value    "Save new question"
        :on-click (fn []
                     (re-frame.core/dispatch [:create-question @new-question])
                     (reset! new-question "")) } ]
1
votes

You can also use both events and subs to keep as much logic out of your view code as possible. This means you will end up with many any events and subs, however this is by design and idiomatic to re-frame. This makes your re-frame code easier to understand, decoupled and more testable. Here is an example:

(rf/reg-fx
  :save-question
  (fn [question]))
    ;; Handle creating a question

(rf/reg-sub
  :new-question-value
  (fn [db _]
    (get-in db [:new-question :value])))

(rf/reg-event-db
  :on-new-question-change
  (fn [db [_ value]]
    (assoc-in db [:new-question :value] value)))

(rf/reg-event-fx
  :on-save-question-click
  (fn [{:keys [db]} _]
    {:db              (assoc-in db [:new-question :value] "")
     :save-question   (get-in db [:new-question :value])}))


(defn input-question
  []
  (let [new-question-value       (rf/subscribe [:new-question-value])
        on-save-question-click   #(rf/dispatch [:on-save-question-click])
        on-new-question-change   #(rf/dispatch [:on-new-question-change (.. % -target -value)])]
    (fn []
      [:div
       [:input {:type      "text"
                :value     @new-question-value
                :on-change on-new-question-change}]
       [:input {:type     "button"
                :value    "Save new question"
                :on-click on-save-question-click}]])))

Some extra notes about this code:

  • You should namespace your events and subs keys to prevent naming clashes

  • You should define a function and pass that into reg-fx, reg-event-db, reg-event-fx & reg-sub. Doing this can make the code more testable by allowing test code to call the function handler directly. However you can still test using Day8/re-frame-test but it's a little harder.