clojurescript+;试剂问题
我正在使用clojurescript和试剂开发一个简单的web应用程序。我想创建一个简单的“tab”组件,它(对于初学者)将包含一个文本输入组件 该应用程序有两个选项卡,用户可以选择一个选项卡,我想“保留”这两个选项卡中的每个选项卡中的值 代码如下:clojurescript+;试剂问题,clojure,clojurescript,reagent,Clojure,Clojurescript,Reagent,我正在使用clojurescript和试剂开发一个简单的web应用程序。我想创建一个简单的“tab”组件,它(对于初学者)将包含一个文本输入组件 该应用程序有两个选项卡,用户可以选择一个选项卡,我想“保留”这两个选项卡中的每个选项卡中的值 代码如下: (defn atom-input [value] [:input {:type "text" :value @value :on-change #(reset! value (-> % .-ta
(defn atom-input [value]
[:input {:type "text"
:value @value
:on-change #(reset! value (-> % .-target .-value))}])
(defn simple-tab [index]
(let [pg-index (atom 1)
a (atom 0)]
(fn []
[:div
[:h4 (str "index: " @index)]
[atom-input a]])))
(defn main-page []
(let [index (atom 0)]
[:div.container
[:div.row
[:button {:on-click (fn [] (reset! index 0))} "select tab 1"]
[:button {:on-click (fn [] (reset! index 1))} "select tab 2"]]
[:div.row
[simple-tab index]]]))
(defn ^:export run []
(reagent/render-component
(fn [] [main-page])
(.-body js/document)))
问题是,当我切换选项卡时,组件共享输入字段的值-我在这里做错了什么
非常感谢你的帮助 问题是您正在将
a(atom 0)
传递给atom输入
控件:[atom输入a]
。
这导致相同的atom值在选项卡之间共享
如果不想共享该值,则需要将a
更改为映射:a(atom{})
,并将映射和索引传递给atom input
,例如:
(定义原子输入[值索引]
[:输入{:键入“文本”
:value(或(获取@value索引)
:更改时#(交换!值关联索引(->%.-target.-value))})
(定义简单选项卡[索引]
(let[pg指数(原子1)
a(原子{})]
(fn[]
[:div
[:h4(str“index:@index)]
[atom输入a@index]]))
IMHO是一种更好的方法,它使用游标,这样您就不需要将索引和整个映射传递给atom input
,例如:
(定义原子输入[值]
[:输入{:键入“文本”
:value(或@value“”)
:更改时#(重置!值(->%.-target.-value))})
(定义简单选项卡[索引]
(let[pg指数(原子1)
a(原子{})]
(fn[]
[:div
[:h4(str“index:@index)]
[原子输入(试剂/光标[@index]a)]))
我认为这里有几个问题,因为您混淆了应用程序数据(状态)和显示逻辑数据(即DOM)。如果您将这两件事区分开来,即在一个原子中维护应用程序状态,在另一个原子中维护与组件显示相关的数据,那么事情可能会更干净一些
您的简单选项卡组件不需要知道关于选项卡状态的任何信息。它只需要知道应用程序状态,即通过atom输入输入/存储的值。因此,与其传递索引,不如传递希望它使用的原子。这将需要一些更高级别的逻辑来确定调用。例如,如果您有多个选项卡,则可能有如下内容
(condp = @index
0 [simple-tab tab0-atom]
1 [simple-tab tab1-atom]
...
n [simple-tab tabn-atom])
或者您可以修改简单选项卡,以便传入的值(即索引值)用作进入应用程序状态的键-我认为光标最简单,即
(def app-state (r/atom {:tabs {0 nil 1 nil}}})
(defn simple-tab [index]
(let [val-cur (r/cursor app-state [:tabs index])]
[atom-input val-cur]))
您使用的是form-2组件,即返回函数的组件 详情如下: 执行此操作时,只调用返回的函数,以便您的atom输入共享同一个atom 此外,您应该在内部函数中使用相同的参数
(defn simple-tab [index]
(let [pg-index (atom 1)
a (atom {})]
(fn [index]
[:div
[:h4 (str "index: " @index)]
[atom-input a @index]])))
在你的例子中,你正在传递一个原子,所以这并不重要,但是如果你忘记了这一点,你将来可能会出错
关于更广泛的体系结构,我建议您使用单个全局原子。尝试在这个原子中拥有尽可能多的状态,避免组件的局部状态,这样更容易推理
您还可以将选项卡命名为:product:users,并使用multimethod根据所选选项卡呈现正确的选项卡。这更容易阅读,也更容易在将来添加新选项卡