为什么组件在Reagent中无法正确呈现?

时间:2017-08-03 06:27:51

标签: clojurescript reagent

当使用Clojurescript在Reagent上阅读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?

1 个答案:

答案 0 :(得分: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])))