为什么需要在 Reagent 组件中返回一个函数?

问题描述

来自 Reagent introduction一个简单的计时器组件:

(defn timer-component []
  (let [seconds-elapsed (r/atom 0)]
    (fn []
      (js/setTimeout #(swap! seconds-elapsed inc) 1000)
      [:div
       "Seconds Elapsed: " @seconds-elapsed])))

下面写着

前面的例子还用到了 Reagent 的另一个特性:一个组件 function 可以返回另一个函数,用于执行实际操作 渲染。这个函数调用参数与 第一个

这允许您对新创建的组件执行一些设置 无需求助于 React 的生命周期事件。

有人能提醒我这里的基本原则吗?为什么我们需要这个匿名函数?为什么不只是

(defn timer-component []
  (let [seconds-elapsed (r/atom 0)]
    (js/setTimeout #(swap! seconds-elapsed inc) 1000)
    [:div
     "Seconds Elapsed: " @seconds-elapsed])))

解决方法

据我所知,Reagent 每次想要渲染时都会调用 timer-component - 可能会一遍又一遍地设置相同的状态 (seconds-elapsed)。

通过返回那个匿名函数,它告诉 Reagent “用它来渲染 timer-component”。通过这种方式,您的状态设置与渲染分离,就像您的 doco 引用所说,这是一种无需使用 Reacts 生命周期事件即可执行状态设置的方法。

希望有意义

,

Tl;dr:返回的匿名函数是 render 方法,每个组件都必须具有该方法。如果在 Reagent 中使用 with-let macro,则可以省略匿名函数。

React 组件不可或缺的部分是 render function,它接受​​单个对象参数并返回一个 React 元素。 render 之间的区别 和组件构造函数是,虽然这两个方法在构造时都被调用,render is called on each update。 (例如,如果有人调用组件的 setState 方法)。

在上面的例子中,内部匿名函数和外部timer-component函数之间的区别与render和构造函数之间的区别是相同的。请注意匿名函数 closes over 绑定在 let 子句中的变量,这允许它是有状态的。如果 timer-component 本身就是 render 函数,那么它会在每次更新时被调用,并且 seconds-elapsed 会被无限地重置为零。

请参阅名为“Creating Reagent Components”的 Reagent 存储库上的文档。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...