0

我有一个 ClojureScript 组件:

(defn main-panel []

  (def nodes (-> @(re-frame/subscribe [::subs/nodes])))

  (defn list-nodes [node]
    (prn (node :name)))

  (reagent/create-class
   {:component-did-mount
    (fn []
      (api-service/get-file-tree))

    :reagent-render
    (fn []
      (doseq [node nodes]
        (if (= (node :depth) 0)
          (list-nodes node))))}))

它将字符串打印到控制台。

但是当我将第一个函数更改为:

  (defn list-nodes [node]
    [:<>
     [:h1 (node :name)]])

我没有得到任何呈现的 HTML - 没有错误并且浏览器窗口保持空白。

如何更改它以呈现 html?

更新

针对以下答案,我已更改doseqfor. 现在的问题是我得到了错误Uncaught Invariant Violation: Objects are not valid as a React child,如果你正在使用 React,这很好,因为你可以调试,但使用试剂,不是那么多。考虑以下。这个功能:

(defn node [nodes]
  (prn (nodes :name)))

当被这个函数调用时:

    :reagent-render
    (fn []
      (for [nodes all-nodes]
        (if (= (nodes :depth) 0)
          (do
            (nodeComponent/node nodes)
            ))))

打印 5 个字符串。但是将调用的函数更改为:

(defn node [nodes]
  [:h1 (nodes :name)])

导致此错误:Uncaught Invariant Violation: Objects are not valid as a React child

这个问题是否与我遇到的另一个问题有关?

4

1 回答 1

2

一方面,def创建defn全局绑定。为了创建本地绑定,使用letor letfn

(defn main-panel []
  (let [nodes (-> @(re-frame/subscribe [::subs/nodes]))
    (letfn [(list-nodes [node]
              (prn (node :name)))]
      (reagent/create-class
       {:component-did-mount
        (fn []
          (api-service/get-file-tree))
        :reagent-render
        (fn []
          (doseq [node nodes]
            (if (= (node :depth) 0)
              (list-nodes node))))}))

您的问题是渲染函数应该返回打嗝形式,但doseq返回nil. 里面的函数开始运行(这就是你看到控制台输出的原因prn),但它的返回值被丢弃了(这就是你看不到 HTML 的原因)。一个直接的解决方法可能是替换doseqfor,但是

你也许可以这样做(第一种试剂形式):

(defn main-panel []
  [:ul (for [node @(re-frame/subscribe [::subs/nodes])
             :when (zero? (:depth node))]
         ^{:key (:id node)} ; whatever identifies nodes, for performance
         [:li {:class "node"} (:name node)]])

我不会在此处触发数据获取,而是在您启动应用程序的任何地方触发数据获取(或多或少与初始应用程序渲染步骤平行)。

于 2019-09-12T09:52:57.840 回答