2

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

(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)))

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


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

4

2 回答 2

2

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

(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 和线程宏。

于 2017-06-13T17:20:44.480 回答
0

仅使用试剂,我们可以使用光标

(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-06-14T07:06:21.480 回答