我有一个组件:
(defn inner-input [cljs_element activeEl title]
(let [form (atom title)]
(fn [cljs_element activeEl title]
[:input {:type "text"
:onChange #(reset! form (.. % -target -value))
:on-blur #(change-title cljs_element (.. % -target -value))
:style {:display (if (:active (:node cljs_element)) "block" "none")
:width (* (+ 1 (count @form)) 8)
:max-width 730
:min-width 170}
:value @form}])))
它嵌套在其他组件中:
(defn card-input [cljs_element activeEl]
(fn [cljs_element activeEl]
(let [title (:title (:node cljs_element))]
[:div
[inner-input cljs_element activeEl title]])))
当我在内部输入组件中输入数据时,我需要更新本地状态表单。当外部组件卡输入更新时,我想将我的表单从参数重置为新的 title prop。我怎样才能做到这一点?
我尝试将(reset! form title)
放在内部输入组件中的let和fn之间,但它无济于事
答案 0 :(得分:1)
您可以使用reagent/track!
收听标题的更改,reagent/dispose
停止收听。您也可以使用add-watch和remove-watch,但track是一种更方便的语法。
(defn inner-input [title]
(reagent/with-let
[form (reagent/atom @title)
watch (reagent/track! (fn [] (reset! form @title)))]
[:label
"Inner input"
[:input {:on-change (fn [e]
(reset! form (.. e -target -value)))
:on-blur (fn [e]
(reset! title (.. e -target -value)))
:value @form}]]
(finally
(reagent/dispose! watch))))
(defn card-input []
(reagent/with-let
[title (reagent/atom "hello")]
[:div
[:label "Title"
[:input {:on-change (fn [e]
(reset! title (.. e -target -value)))
:value @title}]]
[inner-input title]]))
现在,如果您输入内部输入,它将仅在您退出输入框时更新外部,但更改外部标题将立即更改内部标题。那是你想要的吗?
但是如果您不想将标题作为ratom
传递并且必须将其作为值传递,那么您可以将其与之前的值进行比较以确定它是否已更改,并仅在以下情况下重置表单它改变了。
(when (not= @previous-title title)
(do (reset! previous-title title)
(reset! form title)))
此代码可以进行渲染,因为form
更改时可以安全地调用...不会发生任何事情。