我有一个适用于所有页面的试剂,同时点击返回&前进按钮。但是,当页面被刷新时会引发异常。
我的应用从Firebase和sets
原子获取数据。然后在呈现UI时。视图从原子获取数据并呈现UI。
但是当我刷新时,似乎在我的Atom由Firebase填充之前呈现页面,并且由于数据尚未可用而导致异常。
注意:当我仅刷新页面(println clicked-job uid)
而不是渲染标记时,println
运行两次,第一次返回nil
,第二次返回数据。
/* Atom */
(def current-view (atom {"jobs-list" {}}))
/* Helper Functions */
(defn set-list! [value]
(swap! app-state assoc-in ["jobs-list"] value))
(defn clicked-job [uid]
(get-in @app-state ["jobs-list" uid]))
/* View */
(defn job-view [uid]
(let [job clicked-job uid)]
[:div
[:div (job "name")] /***THROWS EXCEPTION HERE***/
[:a.routes {:href "#/"} "home page"])
/* Fetch data from Firebase and put it in Atom */
(let [fb (js/Firebase. "https://firebaseio.com/listings")]
(.on fb "value" #(set-list! (js->clj (.val %)))))
/* Set app-view to current-view */
(defn app-view []
[:div (@data/current-view)])
/* Render app-view */
(reagent/render-component [app-view] (.getElementById js/document "app"))
任何有助于正确刷新页面的帮助!
答案 0 :(得分:0)
我需要一个“网关”来确保如果我的状态尚未准备好,我的渲染代码就不会运行。
简单的方法是if语句。如果我的原子尚未由Firebase设置,则不执行任何操作。如果已设置,则渲染视图。由于Reagent在数据更改时自动呈现视图,因此您无需担心任何进一步的连接。
这是一个伪代码示例:
(if (empty? (data/get-list!))
(println "True. Atom is empty. Do not start rendering.")
(render-view)
)
答案 1 :(得分:0)
你可以做的另一件事是使用defonce而不是def为你的原子。这样可以防止在重新加载页面时重新定义原子形式。看一下the figwheel page,最后是一个关于编写可重载代码的有用部分。