Lazy vs Eager Seq of Reagent Components

时间:2016-10-30 22:53:53

标签: clojurescript reagent

我有以下代码:

MatrixXd compute(MatrixXd &C)
{
    // The matrix to return
    MatrixXd X(C.rows(), C.cols()); 

    // Thresholding C: if negative then set to 0
    MatrixXd P = (C.array() > 0).select(C, 0);

   // Compute the sum of each column of P (i.e. the 
   // sum of positive elements in C
   MatrixXd S = P.colwise().sum();

   // Now want to set all column X_j to P_j whenever S_j <= 1
   // I don't know how to vectorize this code
   // It's easy in Matlab: X(:, S <= 1) = P(:, S <= 1);
   for(int j = 0; j < S.cols(); j++){
    if(S(j) <= 1)
        X.col(j) = P.col(j);
   }
   return X;
}

它出现了意外行为:当我对C进行某些更新时,Reagent会调用组件的渲染器但不会更新UI,而其他更改会导致(ns my.app (:require [reagent.core :as r])) (def data (r/atom {})) (defn child-component [group-title group-data] some-hiccup) (defn parent-component [] [:div (for [[group-title group-data] @data] [child-component group-title group-data])]) (js/window.addEventListener "load" #(r/render [parent-component] (js/document.getElementById "some-id")) false) 重新安装而不是简单地更新,并且每个data都要从头开始呈现。在任何情况下,它都不会像React那样以最低限度更新现有组件。

我猜这个问题与parent-component有关,所以我玩了一些替代品。我尝试在child-component中包裹for,尝试将seq强制转换为向量,甚至尝试将for包裹在doall中并将for deref移动到let绑定向量,以防问题与我在@data绑定向量中解析let有关。这些变化都没有任何区别。

由于我事先知道r/atom中存储的地图的键,我能够尝试以下操作,并且它有效:

for

虽然这在这种情况下解决了我的问题,但作为一般解决方案并不令人满意,因为您并不总是知道将存储在data中的数据的形状。所以,最后我发现了适用于一般情况的解决方案:

(defn parent-component []
  [:div
    (let [data-map @data]
      (list
        [child-component :title-1 (:title-1 data-map)]
        [child-component :title-2 (:title-2 data-map)]))])

所以我的问题解决了,但我不明白为什么。如果问题只是我需要让原始的seq渴望,为什么r/atom没有做到这一点?要么我犯了一些非常愚蠢的错误,要么就是我不理解的Reagent内部工作原理。

注意:我也是以特殊的方式管理(defn parent-component [] (reduce (fn [prev [group-title group-data]] (conj prev [child-component group-title group-data])) [:div] @data)) ,这与我上面提到的关于Reagent如何根据如何我更新了doall。但是,我不确定这是否与我使用r/atom vs r/atom的一般问题相关。如果是的话,请告诉我,我会提供一些细节。

** **编辑

我明白了!问题是我对reduce的使用,我在上面忽略了这一点。原始doall看起来像这样:

:key

也许这是我不理解的React,但似乎你不应该使用parent-component来生成(defn parent-component [] [:div (for [[group-title group-data] @data] ^{:key (gensym)} [child-component group-title group-data])]) 。我改为以下,一切正常:

gensym

0 个答案:

没有答案