Clojurescript 组件can'中指定的Ratom;你不更新那个组件吗?
从试剂开始。我有一个按钮,它的Clojurescript 组件can'中指定的Ratom;你不更新那个组件吗?,clojurescript,reagent,Clojurescript,Reagent,从试剂开始。我有一个按钮,它的:单击值会导致CPU密集型功能运行;要花很长时间才能回来。我想更新按钮本身的文本以通知用户可能需要等待,因此我定义了一个ratom来指定按钮文本,然后我reset函数运行时的ratom 如果我在我的按钮组件功能外定义ratom,则此功能有效,但如果我通过let在组件功能内定义ratom,或如果我重置,则此功能无效组件功能中顶层的ratom。也就是说,如果我取消注释下面的第一行注释,或者取消注释let的两行注释,则按钮文本无法更改。我做错什么了吗?这是预期的行为吗?关
:单击值会导致CPU密集型功能运行;要花很长时间才能回来。我想更新按钮本身的文本以通知用户可能需要等待,因此我定义了一个ratom来指定按钮文本,然后我reset代码>函数运行时的ratom
如果我在我的按钮组件功能外定义ratom,则此功能有效,但如果我通过let
在组件功能内定义ratom,或如果我重置,则此功能无效代码>组件功能中顶层的ratom。也就是说,如果我取消注释下面的第一行注释,或者取消注释let
的两行注释,则按钮文本无法更改。我做错什么了吗?这是预期的行为吗?关于ratoms和DOM更新,这里适用的一般规则是什么
(def label (reagent.core/atom "Make chart"))
(defn chart-button
[normal-label running-label]
; (reset! label normal-label) ; reset globally-defined ratom
; (let [label (reagent.core/atom normal-label)] ; use local ratom
[:button {:on-click (fn []
(reset! label running-label)
(js/setTimeout (fn []
(cpu-intensive-function)
(reset! label normal-label))
10))
}
@label] ;)
)
...
[chart-button "make chart" "running..."]
...
(不相关,但需要澄清:我使用setTimeout
技巧使DOM更新,尽管长时间运行的函数会阻止浏览器在函数运行时更新DOM。)这里的问题是,每次需要(重新)渲染组件时,都会调用函数图表按钮。例如,在本地重置示例中,有人单击按钮,您的标签
将重置为运行标签
。试剂检测到这一变化并调用图表按钮
功能,查看新呈现的按钮应该是什么样子,此时您的第一次重置变化又回来了。let版本也有类似的问题
有两种方法可以处理试剂中的局部状态。最简单的方法是从组件返回函数,而不是向量,如本例所示
(defn timer-component []
(let [seconds-elapsed (r/atom 0)]
(js/setInterval #(swap! seconds-elapsed inc) 1000)
(fn []
[:div
"Seconds Elapsed: " @seconds-elapsed])))
基本上,在试剂中,组件可以是渲染函数,也可以是返回渲染函数的函数。在上述情况下,我们使用闭包来设置一些局部状态,然后返回使用该状态的渲染函数。每次经过的秒数
增加时,将再次调用内部函数并重新加载组件
另一种方法更为复杂,但可能会帮助您从中获得更多的意义。通过使用函数而不是将函数用作组件,您可以完全控制组件的生命周期。您的问题在于,每次需要(重新)呈现组件时,都会调用函数图表按钮。例如,在本地重置示例中,有人单击按钮,您的标签
将重置为运行标签
。试剂检测到这一变化并调用图表按钮
功能,查看新呈现的按钮应该是什么样子,此时您的第一次重置变化又回来了。let版本也有类似的问题
有两种方法可以处理试剂中的局部状态。最简单的方法是从组件返回函数,而不是向量,如本例所示
(defn timer-component []
(let [seconds-elapsed (r/atom 0)]
(js/setInterval #(swap! seconds-elapsed inc) 1000)
(fn []
[:div
"Seconds Elapsed: " @seconds-elapsed])))
基本上,在试剂中,组件可以是渲染函数,也可以是返回渲染函数的函数。在上述情况下,我们使用闭包来设置一些局部状态,然后返回使用该状态的渲染函数。每次经过的秒数
增加时,将再次调用内部函数并重新加载组件
另一种方法更为复杂,但可能会帮助您从中获得更多的意义。您可以通过使用而不是使用功能作为组件来完全控制组件生命周期。非常感谢--非常清楚的诊断和解释。现在一切都有意义了。(也许我早该知道。我读过,但没有理解。)非常感谢——非常清楚的诊断和解释。现在一切都有意义了。(也许我早该知道。我读过,但没有理解。)