在 Om.Next 生命周期函数中关闭本地状态

Closing over local state in Om.Next lifecycle functions

我想做一些类似于 Reagent form-3 组件的事情,这使我能够定义一些共享(静态)变量以在生命周期函数中使用。

基本上我的问题是如何构建与下面 Reagent 代码片段中的 let 等价的东西?我似乎无法弄清楚如何使用 Om 的 defui 宏正确地执行此操作。

一个简单的例子是生成一个内部 ID,我可以通过 gdom/getElement.

在组件的特定实例的所有生命周期函数中访问它
(defn my-component
  [x y z]  
  (let [id (gensym "my-component-")]  ;; <-- how to do this in Om?
     (reagent/create-class                 
       {:component-did-mount (...)
        :component-will-mount (...)          
        :reagent-render
         (fn [x y z] (js/console.log id)))) ;; <-- id is available

您可以使用 om.next/set-state!om.next/update-state!om.next/get-state 写入、更改和读取组件本地状态。

然而,组件本地状态是应用状态的可怜表亲。要使用应用程序状态,请为您的 defui 组件提供一个 ident 并简单地构成一个作为组件查询一部分的关键字。然后设置 read 和 mutate 多方法,这些方法根据您发明的关键字进行分派。

附带说明 - 如果您使用的是 Fulcro 而不是 Om Next,则您将不需要 read 多功能方法。

经过一段时间的挖掘,我发现解决方案是结合使用 React 的 initLocalState 生命周期方法和 om.next/get-state,正如 Chris 的回答中所暗示的那样。

大纲变成如下:

(defui MyComponent
    Object
    (initLocalState [this] {:id (gensym "") ...}) ; <-- the key
    (render [this]
     (let [id (om/get-state this :id)] ...))
    (componentDidmount [this]
     (let [id (om/get-state this :id)] ...))
    ...

这种方法比 Reagent 中的方法更冗长,但我对此很满意,因为它提供了等效的功能。我一直在使用这个,所以我有点惊讶我在别处找不到任何关于这个的讨论。