reagent

A minimalistic ClojureScript interface to React.js http://reagent-project.github.io/
lepistane 2020-06-25T13:34:06.239900Z

oke what am i doing wrong i am trying to adopt this example to cljsrn (react native app) https://github.com/wuxudong/react-native-charts-wrapper/blob/master/Example/app/LiveUpdateChartScreen.js i tried it with

(defn line-chart []
  (let [values (rf/subscribe [:graph/data :line])]
    [:> rn/View {:flex 7}
     [:> charts/LineChart {:style {:flex 1
                                   :background-color :red}
                           :data (clj->js {:dataSets [{:values @values,
                                                       :label "A"
                                                       :config {:lineWidth 2
                                                                :dashedLine {:lineLength 10
                                                                             :spaceLength 10
                                                                             :phase 0}
                                                                :color (rn/processColor "white")}}]})
                           :border-color (rn/processColor "red")
                           :border-width 2
                           ;; :draw-borders true
                           :touch-enabled true
                           :drag-enabled true
                           :scale-enabled true
                           :scale-x-enabled true
                           :scale-y-enabled true
                           :pinch-zoom true
                           :double-tap-to-zoom-enabled true
                           :highlightPerTapEnabled true
                           :highlightPerDragEnabled true
                           :dragDecelerationEnabled true
                           :legend {:enabled false}
                           :chartDescription {:text ""}
                           :xAxis {:valueFormatter "date"
                                   :valueFormatterPattern "HH:mm"}

                           }]]))
Chart doesn't update everytime change to graph/data :line happens. Chart gets updated every 4-5 updates. So i get 4 pieces of data and on 5th update it renders everything. then i thought ok maybe i need to create wrapper and manage state myself so i did

lepistane 2020-06-25T13:34:06.240Z

(defn line-chart []
  (let [chart-ref (atom nil)


        update  (fn [comp]
                  (let [{:keys [values]} (r/props comp)]
                    (prn "update: ")
                    (.setState ^js @chart-ref (clj->js {:values values}))
                    (prn (goog-obj/get @chart-ref "state"))
                    ))]
    (r/create-class {:reagent-render (fn []
                                       [:> rn/View {:flex 6}
                                        [:> charts/LineChart {:ref #(reset! chart-ref %)
                                                              :style {:flex 1
                                                                      :background-color :red}
                                                              :data {:dataSets [{:values [{:x 1
                                                                                           :y 2}]
                                                                                 :label "A"
                                                                                 :config {:lineWidth 2
                                                                                          :drawValues false
                                                                                          :dashedLine {:lineLength 10
                                                                                                       :spaceLength 10
                                                                                                       :phase 0}
                                                                                          :color (rn/processColor "white")}}]}
                                                              :border-color (rn/processColor "red")
                                                              :border-width 2
                                                              ;; :draw-borders true
                                                              :touch-enabled true
                                                              :drag-enabled true
                                                              :scale-enabled true
                                                              :scale-x-enabled true
                                                              :scale-y-enabled true
                                                              :pinch-zoom true
                                                              :double-tap-to-zoom-enabled true
                                                              :highlightPerTapEnabled true
                                                              :highlightPerDragEnabled true
                                                              :dragDecelerationEnabled true
                                                              :legend {:enabled false}
                                                              :chartDescription {:text ""}
                                                              :xAxis {:valueFormatter "date"
                                                                      :valueFormatterPattern "HH:mm"}

                                                                      }]])

                     :component-did-mount (fn [comp]
                                            (.setState ^js @chart-ref (clj->js {:values [{:x 1
                                                                                          :y 2}
                                                                                         {:x 2
                                                                                          :y 4}]}))
                                            (update comp))

                     :component-did-update #(update %)}))
  )
and i see that state is updated BUT chart is not updated at all with this approach. i feel like i am missing something could anyone help? thank you in advance

lepistane 2020-06-25T17:55:22.242Z

should i be using this https://github.com/reagent-project/reagent/blob/master/examples/react-sortable-hoc/src/example/core.cljs to solve the issue i described above? am i even looking at the right place? Why would props be updated but component wouldn't be rendered? i even simplified it

(defn line-chart []
  (let [values (rf/subscribe [:graph/data :line])
        colors [(rn/processColor "red") (rn/processColor "blue") (rn/processColor "green") (rn/processColor "yellow") (rn/processColor "purple") (rn/processColor "pink")]]
    [:> rn/View {:flex 7}
     (prn @values)
     [:> charts/LineChart {:style {:flex 1
                                   :background-color :red}
                           :data (clj->js {:dataSets [{:values @values
                                                       :label "A"
                                                       :config {:lineWidth 2
                                                                :drawValues false
                                                                :dashedLine {:lineLength 10
                                                                             :spaceLength 10
                                                                             :phase 0}
                                                                :color (get colors (rand-int 6))}
                                                       }]})
                           }]])
  )
funnily enough color does change as it should but data still doesn't

p-himik 2020-06-26T07:30:34.243600Z

Can you create a public minimal reproducible example? Preferably one that doesn't require React Native.

lepistane 2020-06-26T07:56:55.243800Z

@p-himik that would be tough as the library in question is react native one. https://github.com/wuxudong/react-native-charts-wrapper would react native minimal example suffice ? i tried other RN libs like https://github.com/JesperLekland/react-native-svg-charts and those work properly but lack functionality charts-wrapper offer

p-himik 2020-06-26T07:58:51.244300Z

> would react native minimal example suffice ? Maybe, but only if other people decide to look into it. I have 0 experience with React Native.

2020-06-26T08:31:35.244500Z

Can you wrap the body of the let in a (fn [] body)

lepistane 2020-06-26T09:19:08.245600Z

@neo2551 i did try that - same behavior

2020-06-26T09:49:15.247500Z

Can you make a minimal example with reagent+reframe without RN?

2020-06-26T09:50:18.248400Z

Also what you could do is have a key metadata to destroy the chart on update

lepistane 2020-06-26T10:17:47.248600Z

I can't have minimal example without react native as it's react native lib. It's not lib that i can use on the web. mini update from me. The issue lies with config of the graph. I changed the values i receive from date/timestamp to just index and live updates started happening. so i excluded the formatting. i will dig further into this and report my findings but at the moment it seems that lib won't render newest data points until enough time has passed for it to make sense to redraw graph it could be optimization on their side but i need to dig further @neo2551 i am very curious what you mean by that could you elaborate or link example? thank you very much for taking time to answer and for your help

2020-06-26T10:34:04.250800Z

My pleasure! We are a welcoming and helpful community after all. So the concept of key for react JS can be read here: https://reactjs.org/docs/lists-and-keys.html

2020-06-26T10:35:06.251700Z

Here are two links for knowing when components rerender: https://github.com/reagent-project/reagent/blob/master/doc/WhenDoComponentsUpdate.md

2020-06-26T10:36:28.253100Z

Finally here at the chapter “providing entity” you can see how the key can be used with component http://day8.github.io/re-frame/reusable-components/

2020-06-26T10:38:45.257Z

So the quick summary is the following: the latest resort for forcing an update of a component is to destroy it and rerender all its children. How can you do this? On way to notify react is to say that the key (or the identifier) of the component changed. You achieve this in reagent as ^{:key @update-counter} [some-component].

2020-06-26T10:39:29.258300Z

This is a nuclear solution as it will rerender all the children. It useful for navigation with multimethods for example where you certain that you do want to rerender everything.

2020-06-26T10:40:46.260400Z

it is a “hack”, with clear performance considerations, and probably other might have between solutions. But when I am giving up for knowing why a component does not rerender, this is the ultimate weapon :). I hope it helps!

lepistane 2020-06-26T14:04:38.273400Z

that's a neat little trick thanks!!