reagent 2023-11-29

Hi, I am using reagent with functional compiler with re-frame , and when using a subscribe all the elements re-render, even thought the value itself didn't change. Imagine a selection, where every item decides if it is the one selected. Only two items should re-render, the one swapping to true, and the one swapping to false. Unfortunately when using subscribe it re-renders all children. Any ideas? Example code, re-rendering all components, based on react profiler

(def x (atom 1))

(defn something-inner [value]
   [:div (str value)])
            
(defn something [selected-number]
 [:<>
  (map 
   (fn [a] ^{:key a}[something-inner (= selected-number a)])
   (range 10))])

(defn view []
  (let [selected-number x]
     [:div 
      [something @selected-number]
      [:div {:on-click #(reset! x (rand-int 10))}
        "Choose number"]]))

Should you be using an r/atom?

What Mike said, but also if you want local state in a component you should probably keep it in that let block and use a form-2 component as described https://github.com/reagent-project/reagent/blob/a14faba55e373000f8f93edfcfce0d1222f7e71a/doc/CreatingReagentComponents.md#form-2--a-function-returning-a-function.

Also I see no calls to subscribe in your code.

I found the solution. Yes I tried it multiple ways. [:<>] fragment is at fault. Believe or not, if I change the fragment to a [:div] around the map it works as expected.

And it's not just for the subscribe It's also r/atom and (react/useState)