0

考虑以下假设的、简化的 clojurescript 片段:

(def cat (r/atom [{:id 0 :data {:text "ROOT" :test 17} :prev nil :par nil}
                 {:id 1 :data {:text "Objects" :test 27} :prev nil :par 0}
                 {:id 2 :data {:text "Version" :test 37} :prev nil :par 1}]))

(defn categorymanager [s]
  [:div
   [:> Reactable.Table
    {:data (clj->js
             s
             )}
    ]
   ]
  )

(defn content []
   (fn []
     [:div
     [:h1 "Test"]
     (categorymanager (select [ALL :data] (t/tree-visitor @cat)))
     [re-com/button :label "Do not click!"]
     ]
))

content 函数准备一个 Reagent 组件。代码片段按预期工作。(“选择”函数是 Spectre 库的一部分。)

我想添加最小的重新框架代码,以便当 cat atom 更改时,例如使用 REPL 中的函数,浏览器中的 React.js 组件会更改。我知道关于重新构建订阅和处理程序的理论,但只是在理论上,因为我无法让它在这样一个最小的例子中工作。它是如何完成的?如何使用 Re-frame 订阅和处理程序将更改推送到 Reagent 组件?

4

1 回答 1

1

您应该首先通过调度某种初始化程序来初始化 re-frame app-db。Re-frame 适用于它的内部单个 app-db。您可以在安装顶级 React 组件之前调度 with dispatch-sync,这样应用程序将在初始化后呈现。

对于您的具体示例,它将是这样的(根本没有经过测试):

; Initialize our db here. This one should be called with (re-frame/dispatch-sync [:initialize]) before rendering application.
(re-frame/register-handler
  :initialize
  (fn [_]
    {:cats [{:id 0 :data {:text "ROOT" :test 17} :prev nil :par nil}
            {:id 1 :data {:text "Objects" :test 27} :prev nil :par 0}
            {:id 2 :data {:text "Version" :test 37} :prev nil :par 1}]}))

; This one returns reaction with relevant cat list.
(re-frame/register-sub
  :cats
  (fn [db]
    (reaction
      (get @db :cats))))

(defn categorymanager [s]
  [:div
   [:> Reactable.Table
    {:data (clj->js
             s)}]])

(defn content []
  ; Here you subscribe to cat list. Once cat list is changed, component is rerendered.
  (let [cats (re-frame/subscribe [:cats])]
   (fn []
     [:div]
     [:h1 "Test"]
     (categorymanager (select [ALL :data] (t/tree-visitor @cats)))
     [re-com/button :label "Do not click!"])))
于 2016-05-04T12:12:57.110 回答