0

这一定是每个人在学习新框架时都会发现的那些愚蠢/复杂的事情之一。所以我有这个功能:

(defn display-questions-list
 []
 (let [counter (atom 1)]
     [:div
      (doall (for [question @(rf/subscribe [:questions])]
            ^{:key (swap! counter inc)} [question-item (assoc question :counter @counter)])])))

@counter atom不保存任何重要数据,它只是一个“可视”计数器,用于显示列表中的数字。第一次加载页面时,一切正常,如果列表显示五个问题(1..5),问题是当创建/编辑/删除订阅问题时:

 @(rf/subscribe [:questions])

再次调用,然后当然会显示列表,但现在从 6 到 11。所以我需要一种方法来重置 @counter。

4

1 回答 1

1

您不应该为此目的使用原子。您的代码应该看起来更像这样:

  (ns tst.demo.core
    (:use tupelo.test)
    (:require [tupelo.core :as t]))

  (defn display-questions-list
    []
    [:div
     (let [questions @(rf/subscribe [:questions])]
       (doall (for [[idx question] (t/indexed questions)]
                ^{:key idx}
                [question-item (assoc question :counter idx) ])))])

Tupelo 库中tupelo.core/indexed函数只是为集合中的每个项目添加一个从零开始的索引值:

(t/indexed [:a :b :c :d :e]) =>   

    ([0 :a] 
     [1 :b] 
     [2 :c] 
     [3 :d] 
     [4 :e])

源代码非常简单:

(defn zip-lazy
  "Usage:  (zip-lazy coll1 coll2 ...)

      (zip-lazy xs ys zs) => [ [x0 y0 z0]
                               [x1 y1 z1]
                               [x2 y2 z2]
                               ... ]

  Returns a lazy result. Will truncate to the length of the shortest collection.
  A convenience wrapper for `(map vector coll1 coll2 ...)`.  "
  [& colls]  
  (assert #(every? sequential? colls))
  (apply map vector colls))

(defn indexed
  "Given one or more collections, returns a sequence of indexed tuples from the collections:
      (indexed xs ys zs) -> [ [0 x0 y0 z0]
                              [1 x1 y1 z1]
                              [2 x2 y2 z2]
                              ... ] "
  [& colls]
  (apply zip-lazy (range) colls))

更新

实际上,:key元数据的主要目标是为列表中的每个项目提供一个稳定的ID 值。由于项目可能有不同的顺序,使用列表索引值实际上是一个 React反模式。使用数据元素内的唯一 ID(即用户 ID 等)或仅使用哈希码提供唯一的参考值。因此,在实践中,您的代码最好这样编写:

(defn display-questions-list
  []
  [:div
   (doall (for [question @(rf/subscribe [:questions])]
            ^{:key (hash question)}
            [question-item (assoc question :counter idx)]))])

一些哈希码示例:

(hash 1)                   =>  1392991556
(hash :a)                  => -2123407586
(hash {:a 1, :b [2 3 4]})  =>   383153859
于 2020-02-27T00:53:39.060 回答