reagent

p4ulcristian 2023-11-29T00:48:52.558289Z

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"]]))

wevrem 2023-11-29T02:18:39.502689Z

Should you be using an r/atom?

liebs 2023-11-29T02:23:46.271479Z

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.

liebs 2023-11-29T02:24:28.895249Z

Also I see no calls to subscribe in your code.

p4ulcristian 2023-11-29T02:33:07.882199Z

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.

p4ulcristian 2023-11-29T02:34:27.387269Z

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