【问题标题】:ClojureScript. Reset atom in Reagent when re-render occursClojure 脚本。发生重新渲染时重置 Reagent 中的原子
【发布时间】:2019-12-30 23:20:24
【问题描述】:

我正在为测验测试显示一组问题,我正在为每个问题分配一个编号,以便在浏览器中显示它们时对其进行编号:

(defn questions-list
 []
  (let [counter (atom 0)]
    (fn []
      (into [:section]
           (for [question @(re-frame/subscribe [:questions])]
              [display-question (assoc question :counter (swap! counter inc))])))))

问题在于,当有人在浏览器中编辑问题时(调用调度并更新“app-db”映射)组件被重新渲染,但原子“计数器”逻辑上从最后一个数字开始不是从零开始。所以我需要重置原子,但我不知道在哪里。我尝试在匿名函数中使用 let ,但这不起作用。

【问题讨论】:

    标签: clojurescript reagent re-frame


    【解决方案1】:

    在这种情况下,我将完全删除该状态。我还没有测试过这段代码,但你的想法很重要。您尝试做的功能版本类似于: 穷但无国籍:

    (let [numbers (range 0 (count questions))
          indexed (map #(assoc (nth questions %) :index %) questions)]
      [:section
       (for [question indexed]
         [display-question question])])
    

    但这很丑陋,而且 nth 效率低下。所以让我们尝试一个更好的。结果表明 map 可以将多个集合作为参数。

    (let [numbers (range 0 (count questions))
          indexed (map (fn [idx question] (assoc question :index idx)) questions)]
      [:section
       (for [question indexed]
         [display-question question])])
    

    但更好的是,事实证明有一个内置函数可以做到这一点。我实际上会写什么:

    [:section
     (doall
      (map-indexed
       (fn [idx question]
         [display-question (assoc question :index idx)])
       questions))]
    

    注意:这些代码实际上都没有运行过,因此您可能需要对其进行一些调整才能正常工作。我建议您查看 ClojureDocs 中的所有函数,以确保您了解它们的作用。

    【讨论】:

      【解决方案2】:

      如果您需要 counter 只是一个问题的索引,您可以改用如下内容:

      (defn questions-list
       []
        (let [questions @(re-frame/subscribe [:questions])
              n (count questions)]
          (fn []
            [:section
              [:ul
                (map-indexed (fn [idx question] ^{:key idx} [:li question]) questions)]])))
      

      注意:这里我使用了[:li question],因为我认为question 是某种文本。

      此外,您可以避免为该组件中的问题计算 count 并使用 layer 3 subscription 来完成:

      (ns your-app.subs
        (:require
         [re-frame.core :as rf]))
      
      ;; other subscriptions...
      
      (rf/reg-sub
       :questions-count
       (fn [_ _]
         [(rf/subscribe [:questions])])
       (fn [[questions] _]
         (count questions)))
      

      然后在组件的let 绑定中,您需要将n (count questions) 替换为n @(re-frame/subscribe [:questions-count])

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-31
        • 1970-01-01
        • 2019-08-09
        • 2021-12-01
        • 2018-08-12
        • 2019-06-01
        • 2021-12-28
        • 2015-07-14
        相关资源
        最近更新 更多