【问题标题】:Why is db printing #object[Object [object Object]] in reframe?为什么 db 在 reframe 中打印 #object[Object [object Object]]?
【发布时间】:2020-03-03 18:30:55
【问题描述】:

在下面的代码中,我调度了两个点击事件:

;; event
(reg-event-db
 :some
 (fn [db [_ some-val]]
   (prn "The db is" db)
   (assoc db :some some-val)
   ))

;; another event
(reg-event-db
 :another
 (fn [db [_ another-val]]
   (prn "The db is" db)
   (assoc db :another another-val)
   ))

;; button
[:input {:type "button" :value "Button"
         :on-click #(do
                       (dispatch [:some :some-val])
                       (dispatch [:another :another-val]))}]

但不是打印数据库映射,而是打印"The db is" #object[Object [object Object]],然后

Error: No protocol method IAssociative.-assoc defined for type object: [object Object]

我做错了什么?我也尝试过#(dispatch [:some :some-val :another another-val],但这给出了同样的错误。一般来说,如何正确调度两个事件?

【问题讨论】:

    标签: clojurescript re-frame


    【解决方案1】:

    这是正确的:

    (do
      (dispatch [:first-event :some-value])
      (dispatch [:second-event :other-value]))
    

    这是不正确的:

    (dispatch [:some :some-val :another another-val])
    

    在本例中,您使用 3 个参数调度一个事件:

    • :some 是事件名称,
    • :some-val 是第一个参数,
    • :another 是第二个参数,
    • another-val 是第三个参数。

    您遇到的错误不是来自dispatch 事件的方式,而是来自您的db 状态。让我们一步一步地剖析它:

    如果(prn db) 输出#object[Object [object Object]] 这意味着db 是一个JavaScript 对象。

    如果(assoc db …) 失败并显示No protocol method IAssociative.-assoc defined for type object: [object Object],则意味着db 值不支持assoc 函数。 assoc 函数由协议(想想接口)定义,并且该协议在地图上实现。所以在这里,db 不是地图。

    为什么db 是 JavaScript 对象而不是 Clojure 映射?

    当您使用(reg-event-db :event-name handler-function) 时,handler-function 返回的值将替换db 状态。如果你错误地返回了一个 JS 对象,它将成为新的 db 值,并且这个新的不正确的 db 值将被传递给后续的事件处理程序。所以很有可能您的一个事件处理程序正在返回一个 JavaScript 对象。

    我将如何解决这种情况:

    • 使用(js/console.log db) 而不是(prn db)。您将能够看到这个 js 对象内部的内容。 prn 不知道如何正确打印js对象。
    • 确保cljs-devtools 已安装并正在运行。它允许您在控制台中探索复杂的对象。下次出现此问题时,您将立即看到有问题的值是什么,而不是不透明的字符串表示。
    • 使用reg-event-fx 而不是reg-event-db。虽然有点冗长,但它会让人眼更清楚你在db 中的价值。
    • 如果您想更进一步并确保不再发生这种情况,请查看Re-Frame Middlewares。在您的情况下,中间件将允许您对处理程序返回的值采取行动,如果它不符合您的期望,则可能会拒绝它。

    【讨论】:

      猜你喜欢
      • 2016-06-16
      • 2018-10-16
      • 1970-01-01
      • 2015-07-03
      • 2013-10-20
      • 2011-07-13
      • 2014-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多