我可以将(if)用作Form-2试剂渲染功能

时间:2019-07-01 21:22:33

标签: clojurescript reagent reagent-forms

我以这种方式将(if)条件用作form-2渲染函数:

(defn bro [dex]
      (let [yo (inc dex)]
           (if true
               [:div (str yo)])))

代替这种方式:

(defn bro [dex]
      (let [yo (inc dex)]
           (fn [dex]
               (if true
                   [:div (str yo)]))))

如果我使用(if)语句而不是(fn)函数是否有问题? 语句变为错误时会发生什么?渲染函数返回nil吗?

2 个答案:

答案 0 :(得分:0)

  

如果我使用(if)语句而不是(fn)函数是否有问题?

我认为您打算在if函数内使用fn ,但是无论哪种方式都没问题。

  

当语句为假时会发生什么?渲染函数返回nil吗?

试剂可以很好地处理这些问题,nil将被跳过(不会创建相应的子对象)。如果您在官方文档中看到TODOs app example,则会看到源代码具有以下代码:

(when (pos? done)
       [:button#clear-completed {:on-click clear-done}
        "Clear completed " done])]))

在这种情况下,如果done不是正数,则此表达式的返回值为nil,并且用于清除已完成任务的按钮根本不会添加到DOM。

答案 1 :(得分:0)

不,这将无法正常工作。要了解差异,请考虑以下两个组件:

(defn test-component-if []
  (let [a (atom 1)
        _ (.log js/console "let in -if")]
    (if (odd? @a)
      [:div
       [:p "odd"]
       [:button {:on-click #(swap! a inc)}
        "inc"]]
      [:div
       [:p "even"]
       [:button {:on-click #(swap! a inc)}
        "inc"]])))

(defn test-component-fn []
  (let [a (atom 1)
        _ (.log js/console "let in -fn")]
     ;; I dub thee test-inner
    (fn []
      (if (odd? @a)
        [:div
         [:p "odd"]
         [:button {:on-click #(swap! a inc)}
          "inc"]]
        [:div
         [:p "even"]
         [:button {:on-click #(swap! a inc)}
          "inc"]]))))

test-component-fn可以正常工作,而test-component-if则不能正常工作。这是为什么?好了,当一个试剂组件可以返回两件事之一时(我忽略了“类型3”组件,因为它会涉及到反应知识)。它可以返回

  1. 向量
  2. 另一个功能

如果返回向量,则函数本身将成为渲染函数,在本例中为test-component-if。当它返回一个函数时,返回的函数(而不是原始函数)是render函数。在这种情况下,我称之为test-inner

当Reagent调用渲染函数时,它会跟踪该函数访问的原子,并且每当该原子发生更改时,它就会调用渲染函数。那么,当我们使用test-component-if时会发生什么?

  1. 试剂呼叫test-component-if
  2. 我们的let子句将一个新原子a绑定到1。
  3. 返回向量
  4. 我们点击按钮
  5. 原子a递增
  6. 试剂看到对a的更改并致电test-component-if
  7. 我们的let子句将一个新原子a绑定到1。(与我们之前的a不同的原子)
  8. 糟糕!

因此a始终为1。您可以通过查看控制台并在每次单击按钮时看到消息均已打印来进行验证。

现在test-component-fn怎么样?

  1. 试剂呼叫test-component-fn
  2. 我们的let子句将一个新原子a绑定到1。
  3. test-component-fn返回test-inner which closes over a
  4. 试剂呼叫test-inner
  5. 我们点击按钮
  6. a递增
  7. 试剂看到对a的更改并致电test-inner
  8. 根据需要重复多次。

您可以验证let仅在控制台上再次执行。根据需要多次单击按钮,仅在首次呈现该消息时才打印该消息。

对于没有if子句的else,这确实返回nil。在这种情况下,通常使用when代替if,这清楚地表明缺乏else的意图。它还具有包括隐式do的优点。至于当遇到nilin most cases it will silently remove it and display nothing时,Reagent会做什么。