如何将新道具传递给 Reagent 中组件的状态?
How to pass new props to state of acomponent in Reagent?
我有一个组件:
(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]])))
当我在 inner-input 组件中输入数据时,我需要更新本地状态 form。当外部组件 card-input 更新时,我想将我的表单重置为参数中的新 title 道具。我怎样才能做到这一点?
我尝试在 inner-input 组件中将 (reset! form title)
放在 let 和 fn 之间,但这无济于事
您可以使用 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
更改时调用是安全的...不会发生任何事情。
我有一个组件:
(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]])))
当我在 inner-input 组件中输入数据时,我需要更新本地状态 form。当外部组件 card-input 更新时,我想将我的表单重置为参数中的新 title 道具。我怎样才能做到这一点?
我尝试在 inner-input 组件中将 (reset! form title)
放在 let 和 fn 之间,但这无济于事
您可以使用 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
更改时调用是安全的...不会发生任何事情。