在 re-frame 应用中使用 rc-animate 动画 antizer 表格

3
我正在尝试在re-frame应用程序中添加动画到表格,以重新创建http://react-component.github.io/table/examples/animation.html中的示例。该表格是使用antizer渲染的,后者是一个用于Ant Design react组件的ClojureScript库。为了实现动画效果,我正在尝试使用rc-animate(如示例中所示),它是一个JavaScript库。 为了集成rc-animate,我遵循了官方Webpack指南并创建了一个src/js/index.js文件:
import Animate from 'rc-animate';
window.Animate = Animate;

我的 project.clj 文件是:
(defproject ant-table-animation "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.10.238"]
                 [reagent "0.8.1"]
                 [re-frame "0.10.5" :exclusions [reagent]]
                 [antizer "0.3.1"]]

  :plugins [[lein-cljsbuild "1.1.7"]]

  :min-lein-version "2.5.3"

  :source-paths ["src/clj" "src/cljs"]

  :clean-targets ^{:protect false} ["resources/public/js/compiled" "target"]

  :figwheel {:css-dirs ["resources/public/css"]}

  :profiles
  {:dev
   {:dependencies [[binaryage/devtools "0.9.10"]
                   [cider/piggieback "0.3.9"]
                   [figwheel-sidecar "0.5.16"]
                   [day8.re-frame/re-frame-10x "0.3.3"]]

    :plugins      [[lein-figwheel "0.5.16"]]}
   :prod { }
   }

  :cljsbuild
  {:builds
   [{:id           "dev"
     :source-paths ["src/cljs"]
     :figwheel     {:on-jsload "ant-table-animation.core/mount-root"}
     :compiler     {:closure-defines {re-frame.trace.trace_enabled_QMARK_ true}
                    :main                 ant-table-animation.core
                    :output-to            "resources/public/js/compiled/app.js"
                    :output-dir           "resources/public/js/compiled/out"
                    :asset-path           "js/compiled/out"
                    :source-map-timestamp true
                    :preloads             [devtools.preload, day8.re-frame-10x.preload]
                    :external-config      {:devtools/config {:features-to-install :all}}
                    :infer-externs true
                    :npm-deps false
                    :foreign-libs [{:file "dist/index_bundle.js"
                                    :provides ["rc-animate" "rc-animate-child"]
                                    :global-exports {rc-animate Animate
                                                 rc-animate-child AnimateChild}}]
                    }}

    {:id           "min"
     :source-paths ["src/cljs"]
     :compiler     {:main            ant-table-animation.core
                    :output-to       "resources/public/js/compiled/app.js"
                    :optimizations   :advanced
                    :closure-defines {goog.DEBUG false}
                    :pretty-print    false}}


    ]}
  )

在我的 views.cljs 文件中,我尝试像这样渲染表格:
(ns ant-table-animation.views
  (:require
   [re-frame.core :as re-frame]
   [ant-table-animation.subs :as subs]
   [ant-table-animation.events :as events]
   [antizer.reagent :as ant]
   [reagent.core :as reagent]
   [rc-animate]
   ))

(.log js/console rc-animate)

(defn AnimateBody
  [props]
  (.createElement
    js/React
    rc-animate
    (.assign js/Object #js {:transitionName "move", :component "tbody"} props)))

(.log js/console AnimateBody)

(defn orders
  []
  (let [orders @(re-frame/subscribe [::subs/orders])
        width 80]
    [ant/table
     {:columns
      [{:title "Product Name" :dataIndex :product :width width}
       {:title "Quantity" :dataIndex :quantity :width width}
       {:title "Unit Price" :dataIndex :price :width width}
       {:title "Actions" :dataIndex "actions" :width width
        :render
        #(reagent/as-element
          [ant/button
           {:icon "delete" :type "danger"
            :on-click
            (fn []
              (re-frame/dispatch [::events/order-deleted (.-product %2)]))}])}]
      :dataSource orders
      :size "small"
      :components {:body {:wrapper AnimateBody}}
      :pagination {:page-size 20}
      :scroll {:y 300}}]))

(defn main-panel []
  (let [name (re-frame/subscribe [::subs/name])]
    [:div
     [:h1 "Hello from " @name]
     [orders]
     ]))

我完全不确定关于这个。
(defn AnimateBody
  [props]
  (.createElement
    js/React
    rc-animate
    (.assign js/Object #js {:transitionName "move", :component "tbody"} props)))

等同于示例中的那条线。
const AnimateBody = props => <Animate transitionName="move" component="tbody" {...props} />;

这句话的意思是:表格显示正确,但当我尝试删除一行时,它会出现以下错误跟踪:
react-dom.development.js:55 Uncaught Error: Unable to find node on an unmounted component.
at invariant (react-dom.development.js:55)
at findCurrentFiberUsingSlowPath (react-dom.development.js:4256)
at findCurrentHostFiber (react-dom.development.js:4266)
at findHostInstance (react-dom.development.js:17676)
at Object.findDOMNode (react-dom.development.js:18145)
at AnimateChild.transition (AnimateChild.js:83)
at AnimateChild.componentWillLeave (AnimateChild.js:70)
at performLeave (Animate.js:339)
at Array.forEach (<anonymous>)
at Animate.componentDidUpdate (Animate.js:188)
at commitLifeCycles (react-dom.inc.js:15386)
at commitAllLifeCycles (react-dom.inc.js:16646)
at HTMLUnknownElement.callCallback (react-dom.inc.js:143)
at Object.invokeGuardedCallbackDev (react-dom.inc.js:193)
at invokeGuardedCallback (react-dom.inc.js:250)
at commitRoot (react-dom.inc.js:16800)
at completeRoot (react-dom.inc.js:18192)
at performWorkOnRoot (react-dom.inc.js:18120)
at performWork (react-dom.inc.js:18024)
at performSyncWork (react-dom.inc.js:17996)
at requestWork (react-dom.inc.js:17884)
at scheduleWork (react-dom.inc.js:17689)
at Object.enqueueForceUpdate (react-dom.inc.js:11855)
at Object.Component.forceUpdate (react.inc.js:479)
at reagent$impl$batching$run_queue (batching.cljs?rel=1541330682770:39)
at Object.flush_queues (batching.cljs?rel=1541330682770:86)
at Object.run_queues (batching.cljs?rel=1541330682770:76)
at batching.cljs?rel=1541330682770:63
at re_frame_10x.cljs?rel=1541164419576:125

这也表明:
The above error occurred in the <Animate> component:
in Animate (created by ant_table_animation.views.animateBody)
in ant_table_animation.views.animateBody (created by BaseTable)
in table (created by BaseTable)
in BaseTable (created by Connect(BaseTable))
in Connect(BaseTable) (created by BodyTable)
in div (created by BodyTable)
in BodyTable (created by ExpandableTable)
in div (created by ExpandableTable)
in div (created by ExpandableTable)
in div (created by ExpandableTable)
in ExpandableTable (created by Connect(ExpandableTable))
in Connect(ExpandableTable) (created by Table)
in Provider (created by Table)
in Table (created by LocaleReceiver)
in LocaleReceiver (created by Table)
in div (created by Spin)
in AnimateChild (created by Animate)
in div (created by Animate)
in Animate (created by Spin)
in Spin (created by Table)
in div (created by Table)
in Table (created by ant_table_animation.views.orders)
in ant_table_animation.views.orders (created by    ant_table_animation.views.main_panel)
in div (created by ant_table_animation.views.main_panel)
in ant_table_animation.views.main_panel

我是Clojure的初学者,对React更是一知半解;在尝试了一个星期之后,我最终来到了这里,但现在感觉进退两难。我已经将我的项目上传至Github,供任何想尝试的人使用。

Webpack 正在混淆 rc-animate 对象,因此我使用 mode:development 重新打包它 - 我已更新错误消息。 - idyphall
1个回答

0

无法在未安装的组件上找到节点错误是由于React版本问题而发生的。我通过明确使用rc-animate库中使用的React版本 - 16.5.2,在我的project.clj中处理了它:

...             
[reagent "0.8.1" :exclusions [cljsjs/react cljsjs/react-dom [cljsjs/react-dom-server]]]
[cljsjs/react "16.5.2-0"]
[cljsjs/react-dom "16.5.2-0"]
[cljsjs/react-dom-server "16.5.2-0"]
    ...
[antizer "0.3.1" :exclusions [cljsjs/react cljsjs/react-dom [cljsjs/react-dom-server]]]]
    ...

为了正确定义AnimateBody组件,我不得不使用reagent/adapt-react-classreagent/as-elementreagent/reactify-component的组合。 具体来说,在我的views.cljs文件中,我将该组件定义为:
(def animate (reagent/adapt-react-class rc-animate))
(def animateBody
  (fn [props]
    (reagent/as-element [animate (assoc props :transition-name "move" :component "tbody")])))

然后使用以下代码将其传递给ant/table组件:

...
:components {:body {:wrapper (reagent/reactify-component animateBody)}}
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接