我以这种方式使用(if)条件作为form-2 render-function:
(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)函数会有问题吗?如果声明为假,会发生什么?render函数返回nil?
发布于 2019-07-02 11:58:09
不,这不会像你期望的那样工作。要了解其中的区别,请考虑以下两个组件:
(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则不然。为什么会这样呢?当一个试剂组件可以返回两个东西中的一个时(我忽略了"type-3“组件,因为它与react知识挂钩)。它可以返回
如果它返回一个向量,函数本身就变成了呈现函数,在我们的例子中是test-component-if。当它返回一个函数时,返回的函数是呈现函数,而不是原始函数。在这种情况下,我将其命名为test-inner
当Reagent调用render函数时,它会跟踪函数访问的原子,并且每当原子发生变化时,它都会调用render函数。那么当我们使用test-component-if时会发生什么呢?
incremented
test-component-if
a绑定到1。
test-component-if
a)
不同的原子
因此,a始终为1。您可以通过查看控制台来验证这一点,每次单击该按钮时都会打印消息。
现在我们来看看test-component-fn
单击代理程序调用test-component-fn
a绑定到1.
test-component-fn返回并单击test-inner
test-inner
a is incremented
test-inner a的更改,并根据需要多次调用a。您可以验证let是否仅在控制台上再次执行一次。根据需要多次单击该按钮,消息将仅在第一次呈现时打印。
就不带else子句的if而言,这确实会返回nil。在这种情况下使用when而不是if是惯例,这清楚地表明缺少else是有意的。它还具有包含隐式do的优点。至于当它遇到nil,in most cases it will silently remove it and display nothing时,试剂会做什么。
发布于 2019-07-02 10:18:03
如果我使用( if )语句而不是(fn)函数,
会有问题吗?
我想您的意思是在fn函数中使用if,但无论哪种方式,这都不是问题。
以及当语句变为false时会发生什么?render函数返回nil?
试剂很好地处理这些,nil将被跳过(不会创建相应的子对象)。如果你在官方文档中看到TODOs app example,你会看到源代码如下:
(when (pos? done)
[:button#clear-completed {:on-click clear-done}
"Clear completed " done])]))在本例中,如果done不是正数,则该表达式的返回值为nil,并且用于清除已完成任务的按钮不会添加到DOM中。
https://stackoverflow.com/questions/56842634
复制相似问题