reagent-project / reagent

A minimalistic ClojureScript interface to React.js
http://reagent-project.github.io/
MIT License
4.76k stars 415 forks source link

Devcards compatability #195

Closed bhauman closed 9 years ago

bhauman commented 9 years ago

Devcards relies on the magic in reactify-component to do its reloading. But because reactify-component creates a "new class" on every call, this "class type change" forces React to do a complete re-render for all the components below it every time reactify-component gets called. If however reactify-component used a class that was a stable reference then this forced re-rendering doesn't occur.

This works for me:

;; defonce not needed unless you are working on reagent itself
(defonce Reactifier
  (js/React.createClass
   #js{:displayName "react-wrapper"
       :render
       (fn []
         (this-as this
                  (reagent/as-element
                   [(aget (.-props this) "reagent_component")
                    (-> (.' this :props)
                        comp/shallow-obj-to-map
                        ;; ensure re-render, might get mutable js data
                        (assoc :-elem-count
                               (set! comp/elem-counter
                                     (inc comp/elem-counter))))])))}))

(defn reactify-component [comp]
  ;; create a class with a type this will prevent forced full re-renders
  (js/React.createElement Reactifier #js {:reagent_component comp}))

To be clear this isn't just an issue for hot reloading, its a general rendering problem when embedding Reagent in a system that ends up calling reactify-component during its render phase.

I haven't looked at the rest of Reagent but this trick could probably help with hot reloading in other areas as well.

arichiardi commented 9 years ago

Oh that's why devcards was not work, good to know.

bhauman commented 9 years ago

There is a problem with my code above in that it changes the signature of reactify-component to return a ReactElement. Looking at this right now ...

Yeah I spoke too soon. This still needs some examination. Mostly my ignorance ...

Still working out the best way to hold reagent inside Devcards.

Any help I can get here would be great.

bhauman commented 9 years ago

And now I am closing this.

I found that as-element provides everything I need. I apologize for the noise.