【问题标题】:How to write a Decorator for a Reagent component如何为 Reagent 组件编写装饰器
【发布时间】:2023-03-28 16:29:01
【问题描述】:

我有一些类似的试剂成分,可以通过某些方式呈现给定的数字:

(defn plain-number [n]
  [:h1 n])

(defn pie-chart [n]
  (render-fancy-chart n))

还有一些(简化的)状态:

(def state (r/atom {:a 5 :b 10 :c 7}))

而且我知道如何编写一个组件,它可以访问该状态并使用其中一个组件来呈现该状态:

(def fetch-and-render-pie [k]
   (let [v (get @state k)]
     [pie-chart v]))

[fetch-and-render-pie :a] ; renders pie with 5

到目前为止,一切都很好。但这是耦合和重复的。

目标:

装饰器会很好,它可以获取一些状态并将其传递给孩子。用法如下所示:

[fetch :a
  [pie-chart]]

可能的解决方案:

(defn fetch [k wrapped]
  (let [v (get @state k)]
    (conj wrapped v)))

这行得通,但它与组件定义的向量相混淆,并且它假定了很多 wrapped 组件的参数。链式装饰器失败了。


必须有一个聪明而强大的解决方案。有什么想法吗?

【问题讨论】:

    标签: clojure decorator clojurescript reagent re-frame


    【解决方案1】:

    你不能仅仅因为你将一个参数传递给装饰组件就摆脱对装饰组件参数的假设,并且应该知道如何以与函数调用相同的方式进行操作。但是您无需将矢量传递给您的装饰器,只需一个组件本身就可以工作:

    (defn fetch [k component]
      (let [v (get @state k)]
        [component v]))
    
    [fetch :test pie-chart] ; ~ [pie-chart (get @state :test)]
    

    对于链接,您需要支持 component 的额外参数:

    (defn fetch [k component & args]
      (let [v (get @state k)]
        (into [component v] args)))
    
    (defn prepare [s component & args]
      (let [v (keyword s)]
        (into [component v] args)))
    
    [prepare "test" fetch pie-chart {:colourful true}]
    ; ~ [pie-chart (get @state (keyword "test")) {:colourful true}]
    

    这有点类似于 HOF 和线程宏。

    【讨论】:

    • 这看起来是一个非常有前途和优雅的解决方案。我会试试的。非常感谢。
    【解决方案2】:

    只有试剂,我们可以使用光标

    (defn com-a [state]
      (fn []
        [:h1 @state]))
    
    (defn fetch [db]
      (let [state (reagent/cursor db :k)] ; assume {:k "dd"}
        (fn []
          [com-a state])))
    

    重新构图

    (re-frame/reg-sub
      :chart-data
      (fn [db [_ query]]
        (get-in db query)))
    
    (defn com-a [state]
      (fn []
        [:h1 @state]))
    
    (defn fetch [db]
      (let [state (re-frame/subscribe [:chart-data [:k]])]
        (fn []
          [com-a state])))
    

    【讨论】:

      猜你喜欢
      • 2017-01-13
      • 2014-09-20
      • 1970-01-01
      • 2021-01-28
      • 2011-03-19
      • 1970-01-01
      • 2015-03-22
      • 1970-01-01
      • 2010-09-15
      相关资源
      最近更新 更多