1

I have the following over-engineered code that displays 2 buttons on a page, but when I click on a button nothing happens.

I'm using reagent (r) and mui (m).

(defn settings [id]
  (let [active "active-content-button"
        inactive "content-button"
        classes (r/atom {1 inactive, 2 inactive})]

    (defn toggle-active [button-id]
      (swap! classes assoc 1 inactive)
      (swap! classes assoc 2 inactive)
      (swap! classes assoc button-id active))

    [:div {:style {:padding (* 2 SPACING)}}
     [:div {:class "tab-block"}
      [m/Button {:class (@classes 1) :on-click #(toggle-active 1)} "Filters"]
      [m/Button {:class (@classes 2) :on-click #(toggle-active 2)} "Settings"]]]))

I'm expecting the classes of the buttons to update themselves on click. What am I missing?

2 Answers 2

2

A few thinngs:

  • Don't nest defn and/or def. Instead, use let/letfn/fn or move that defn outside
  • Don't use multiple swap!/reset! operations on the same atom. Instead, combine them in a single one
  • You need to use a so-called form-2 component or r/with-let. Without any of those, your r/atom gets re-created on every render of the settings component

Some less important things:

  • Class names can be keywords in Reagent, if you prefer those
  • Mutually exclusive options are better handled with keywords rather than with numbers, i.e. I would remodel your data as active-button (r/atom :filters) and then would choose the class conditionally based on that
Sign up to request clarification or add additional context in comments.

Comments

0

The suggestions from the earlier answer would look something like this:

(defn class [active?]
  (if active? "active-content-button" "content-button"))

(defn settings [id]
  (let [active (r/atom :filters)]
    (fn []
      [:div {:style {:padding (* 2 SPACING)}}
       [:div.tab-block
        [m/Button {:class (class (= @active :filters))
                   :on-click #(reset! active :filters)}
         "Filters"]
        [m/Button {:class (class (= @active :settings))
                   :on-click #(reset! active :settings)}
         "Settings"]]])))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.