2017-08-03 71 views
0

當在Clojurescript I上試用this post時,我嘗試了不同的方法來實現timer-component組件。我第一次嘗試,但是,沒有工作:爲什麼組件在試劑中不能正確呈現?

(defn timer-component [] 
    (fn [] 
    (let [seconds-elapsed (r/atom 0)] 
     (js/setTimeout #(swap! seconds-elapsed inc) 1000) 
     [:p (str "Expired time: " @seconds-elapsed)]))) 

由於調試日誌聲明顯示計時器仍經常叫和seconds-elapsed變量仍正常更新。但是,顯示屏未更新,組件始終顯示「過期時間:0」。

與博客文章中的代碼示例相比,我的組件交換fnlet聲明,並且此修改似乎阻止正確顯示,但無法正確更新組件。我的期望是組件既可以更新也可以正確顯示,或者既不更新也不顯示。

我的問題是爲什麼會發生這種情況?這是否是Reagent中的錯誤或者是我濫用API?

回答

2

您總是看到相同的值,因爲每個(重新)渲染都會調用內部匿名函數。因此,seconds-elapsed被一次又一次綁定到一個新值爲0的原子。這不是一個錯誤,但Reagent應該如何工作。

你的組件是「Form-2」,並且應該在外部函數timer-component中聲明它的本地狀態,每個組件只調用一次。 Re-frame documentation explains different forms of Reagent components很好。

重新幀文檔添加註釋在試劑教程的例子中,這可能有助於澄清:

(defn timer-component [] 
    (let [seconds-elapsed (reagent/atom 0)]  ;; setup, and local state 
    (fn []  ;; inner, render function is returned 
     (js/setTimeout #(swap! seconds-elapsed inc) 1000) 
     [:div "Seconds Elapsed: " @seconds-elapsed])))