如何在 Reagent 中定义默认组件

How to define default component in Reagent

我正在尝试使用 Reagent 创建 SPA 应用程序。如何定义默认 page/component?据我了解,我应该将当前页面保存在状态原子中。但是,如果我在主页中更改状态,则无法定义它。 例如,在此代码中 home 无法解析(第 1 行):

(defonce app-state (atom {:current-page (home)}))

(defn second-page []
  [:p 2])

(defn home []
  [:div
   [:p 1]
   [:input {:type "button" :value "Click!"
            :on-click #(swap! app-state second-page)}]])

(defn hello-world []
  [:div
   [:input {:type "button" :value "Home" :on-click #(swap! app-state home)}]
   (:current-page @app-state)
   [:h3 "footer"]])

(reagent/render-component [hello-world]
                          (. js/document (getElementById "app")))

只需使用 declarehomesecond-page 的占位符放在原子之前:

(declare home second-page)

(defonce app-state (atom {:current-page home}))

请确保始终打开浏览器选项卡 The Clojure CheatSheet. See also ,以了解有关 Clojure var 功能工作原理的更多详细信息。

有几种方法可以解决这个问题。一种方法是像这样创建一个名为页面的地图

(def pages {:home home
            :second second-page
            ....}

然后在状态原子中使用键名,即

(defonce app-state (atom {:current-page :home})

因为您只是存储关键字,所以不需要转发声明,因为关键字会自行计算。然后在您的代码中,您将使用 :current-page 的值从页面 map

中查找组件
defn hello-world []
  [:div
   [:input {:type "button" :value "Home" :on-click #(swap! app-state home)}]
   ((:current-page @app-state) pages)
   [:h3 "footer"]])

您可能还会发现 secretary 之类的东西可以作为推广此类想法的一种方法的示例。