为什么不能在let中定义试剂组分的状态?

时间:2017-01-16 15:32:09

标签: clojurescript lexical-scope reagent

假设我们在hiccup语法中定义了文本文本区域。

(def written-text (reagent/atom ""))

(defn text-area []
    [:textarea
     {:value     @written-text
      :on-change #(reset! written-text (-> % .-target .-value))
      :on-click  #(println @written-text)}])

假设我们希望文档中有多个文本区域副本,每个副本都有不同的状态。然后,我们必须将当前可用的当前状态中的状态移动到词法范围的符号中。类似的东西:

(defn text-area []
  (let [written-text (reagent/atom "")]
    [:textarea
     {:value     @written-text
      :on-change #(reset! written-text (-> % .-target .-value))
      :on-click  #(println @written-text)}]))

但是现在这个代码不起作用。无论用户输入什么,文本字段总是空的。这是为什么?如何将我的状态包含在每个组件的词法范围内?

1 个答案:

答案 0 :(得分:0)

这个问题的答案可以在re-frame documentation中找到,它描述了试剂项目中通常可以找到的不同形式的组件。它声明为了为每个组件状态提供持久的词法范围,必须编写一个返回另一个渲染函数的函数;否则每次试剂重新渲染组件时都会重新定义state atom。所以对于给定的组件:

(defn text-area []
  (let [written-text (atom "")]
    (fn []                                       
      [:textarea
        {:value     @written-text
         :on-change #(reset! written-text (-> % .-target .-value))}])))

这样,试图在希望重绘组件时调用的函数是内部的匿名函数。定义词法范围的let不会重新运行。

这个答案的所有功劳都归功于用户mccraigmccraig对clojurians的懈怠。