使用 defmulti 和 defn 作为 om/build-all 的函数有什么区别?

What is the difference between using defmulti and defn as a function of om/build-all?

我最近开始学习om by using examples codes of om repository. Now, I am checking multi示例,我可以理解这个程序的行为。

点击“+”按钮后,

但是当我添加以下代码时
(只需将 even-odd-widget defmulti 代码更改为 defn 代码)

(defn test-widget
  [props owner]
  (reify
    om/IWillMount
    (will-mount [_]
      (println "Test widget mounting"))
    om/IWillUnmount
    (will-unmount [_]
      (println "Test widget unmounting"))
    om/IRender
    (render [_]
      (dom/div nil
        (dom/h2 nil (str "Test Widget: " (:my-number props)))
        (dom/p nil (:text props))
        (dom/button
          #js {:onClick #(om/transact! props :my-number inc)}
          "+")))))

并尝试使用此功能而不是 test-widget,结果没有打印消息...

那么defmulti和defn在这种情况下有什么区别呢? 这是错误还是正确的行为?

提前致谢。

协议方法 om/IWillMountom/IWillUnmount 仅在组件为 mounted/unmounted 时调用一次。它不会在每次渲染时调用,因此如果单击“+”按钮不会导致组件成为 mounted/unmounted,则不会生成日志消息。多重方法的使用对此行为没有影响。

您在使用多方法版本时看到重复的日志语句的原因是每次点击都会返回不同的组件,因此组件也是 mounted/unmounted 每次您点击“+”,而与每次单击“+”时安装并保持安装单个组件的普通功能。

对于纯函数和多方法版本,您生成的日志消息将出现在浏览器的开发人员控制台中,但仅当组件 mounts/umounts 时才会出现,而不是在每次渲染时出现。

点击'+'按钮将在普通函数场景中触发现有挂载组件的重新渲染。如果要登录组件的每个渲染,则需要执行以下操作:

(defn test-widget
  [props owner]
  (reify
    om/IWillMount
    (will-mount [_]
      (println "Test widget mounting"))
    om/IWillUnmount
    (will-unmount [_]
      (println "Test widget unmounting"))
    om/IRender
    (render [_]
      (.log js/console "Rendering test widget!")
      (dom/div nil
               (dom/h2 nil (str "Test Widget: " (:my-number props)))
               (dom/p nil (:text props))
               (dom/button
                #js {:onClick #(om/transact! props :my-number inc)}
                "+")))))

(defn app [props owner]
  (reify
    om/IRender
    (render [_]
      (apply dom/div nil
        (om/build-all test-widget (:widgets props))))))