试剂:使用观察者保持本地组件状态与全局状态同步?

时间:2016-08-26 10:38:33

标签: clojurescript reagent

考虑一下全局app-state(试剂)-atom:

(defonce state (reagent/atom ["Here" "are" "some" "words"]))

从整个网络应用程序的不同位置操纵/交换此原子。

现在有一个容器,需要从state呈现单词。容器本身需要在其本地状态下跟踪一些额外的数据,让我们说它需要单词的长度。
所以在本地状态中应该有一个与全局状态同步的原子,具有如下结构:

[{:word "Here" :length 4}
 {:word "are" :length 3}
 {:word "some" :length 4}
 {:word "words" :length 5}]

将呈现的内容,例如像这样:

(defn compo []
   (let [local-state ...]
      (fn []
         [:div
            (for [{:keys [word length] @local-state]
               [:div (str word " - " length)])])))

怎么做?这会是一个观察者(installed via add-watch在let语句开头的情况吗?

2 个答案:

答案 0 :(得分:1)

我不确定为什么你需要保持一个单独的局部原子,如果它应该始终与全局状态同步。只需使用全局状态,并将let表达式放在渲染函数中。

(defn compo []
  (let [local-data ...]
    [:div
      (for [{:keys [word length] @local-data]
        [:div (str word " - " length)])]))

现在,每次调用渲染函数时,整个渲染函数都会被执行。因此,您可以使用local-data将全局状态映射到此组件所需的内容。

希望这有帮助。

此外,还有另一个名为re-frame的clojurescript框架。它建立在试剂之上,它实现了用户,这正是您可能正在寻找的。您可以阅读有关他们的更多信息here

答案 1 :(得分:0)

如果您有一些可以从其他状态导出的局部反应状态 - 您可以使用试剂 reaction

(defonce state (reagent/atom ["Here" "are" "some" "words"]))

(defn count-words-length ...)

(defn compo []
  (let [words-length (reagent.ratom/reaction (count-words-length @state))]
    [:div
      (for [{:keys [word length] @words-length]
        [:div (str word " - " length)])]))

在这种情况下,每次 count-words-length 原子发生变化时,state 都会响应式地重新运行。