ClojureScript 点击时未应用类数值。

huangapple go评论53阅读模式
英文:

ClojuresScript not applying class values with click

问题

我有以下过度工程的代码,在页面上显示两个按钮,但当我点击按钮时什么都不发生。

我正在使用reagent (r) 和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 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?

答案1

得分: 2

一些要点:

  • 不要嵌套 defn 和/或 def。取而代之,使用 let/letfn/fn 或将 defn 移到外部。
  • 不要在相同的原子上使用多个 swap!/reset! 操作。取而代之,将它们合并为一个单独的操作。
  • 你需要使用所谓的 form-2 组件r/with-let。如果没有这些,你的 r/atom 会在每次渲染 settings 组件时重新创建。

一些次要的事项:

  • 在Reagent中,类名可以是关键字,如果你更喜欢的话。
  • 互斥的选项最好使用关键字而不是数字来处理,例如,我会将你的数据重新建模为 active-button (r/atom :filters),然后基于它有条件地选择类。
英文:

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

答案2

得分: 0

以下是翻译好的部分:

(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"]]]))
英文:

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"]]])))

huangapple
  • 本文由 发表于 2023年3月9日 21:24:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75685219.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定