再解释一下,当您执行(swap! (:toppings order) ...) 时,您正在从order 检索:toppings 键,如果它是一个映射,这将是有意义的,但它是一个原子,所以(:toppings order) 返回nil.
swap! 的第一个参数应该始终是一个原子(Reagent 原子的工作方式相同)。第二个参数应该是一个以原子内容作为第一个参数的函数。然后,您可以选择提供更多将传递给函数参数的参数。
您可以执行以下操作,而不是 minhtuannguyen 的回答:
(swap! order
(fn a [m]
(update m :toppings
(fn b [t]
(conj t "Pepperoni")))))
fn a 接收到 atom 内部的 map,将其绑定到 m,然后更新它并返回一个新的 map,它成为 atom 的新值。
如果您愿意,可以重新定义 fn a 以获取第二个参数:
(swap! order
(fn a [m the-key]
(update m the-key
(fn b [t]
(conj t "Pepperoni"))))
:toppings)
:toppings 现在作为第二个参数传递给fn a,然后在fn a 内部传递给update。我们可以对update 的第三个参数做同样的事情:
(swap! order
(fn a [m the-key the-fn]
(update m the-key the-fn))
:toppings
(fn b [t]
(conj t "Pepperoni")))
现在update 与fn a 具有相同的签名,所以我们根本不再需要fn a。我们可以直接提供update 代替fn a:
(swap! order update :toppings
(fn b [t]
(conj t "Pepperoni")))
但我们可以继续,因为update 还接受更多参数,然后传递给提供给它的函数。我们可以重写fn b 来获取另一个参数:
(swap! order update :toppings
(fn b [t the-topping]
(conj t the-topping))
"Pepperoni"))
再一次,conj 与fn b 具有相同的签名,所以fn b 是多余的,我们可以使用conj 代替它:
(swap! order update :toppings conj "Pepperoni")
因此,我们最终得到了 minhtuannguyen 的答案。