Fork me on GitHub
#reagent
<
2024-01-11
>
ozimos06:01:25

Is there an existing clj-kondo rule for reagent such that if a component is rendered with a function component tag :f> and is also rendered elsewhere without a :f> both usages are marked as an error

[:f> some-component props]
;; apply error to both because of inconsistent function tagging
[some-component props]

hifumi12301:01:55

this would probably have to be a clojure-lsp linter rather than clj-kondo, since clj-kondo operates on single files, not entire project. with that said, it may be tough differentiating when something is hiccup or simply a collection of functions e.g. if we have

(defn component-1 []
  [:f> some-component])

(defn component-2 []
  (into [:<>] (for [component [some-component other-component ...]]
                [:f> component])))
then we must not mark the into form as an error, as it is correctly using some-component as function component

ozimos09:01:47

thanks for the pointer. for now I don't need to validate dynamically constructed hiccup. I'll look into making a basic linter

samoleary16:01:19

Hello! I'm messing around with Portals for the first time and I'm happy enough with the example from the https://cljdoc.org/d/reagent/reagent/1.2.0/doc/tutorials/react-features. What I'm trying to figure out now is how I can pass a form-3 component to the portal so that I can access it's lifecycle methods. I'm certainly misunderstanding something when it comes to passing r/as-element to react-dom/createPortal and trying to swap in r/create-class instead. Is there another bit of translation needed or an alternative way to access :component-did-mount?

(defn- modal-div [data]
    (r/create-class
     {:display-name "modal-div"
      :component-did-mount (fn [_] (setup-modal-listeners))
      :reagent-render
      (fn [data]
        [:div {:id "modal-div" :class "modal"}
         [:div {:class "modal-background"}]
         [:div {:class "modal-content"}
          [:div {:class "box"}
           (dashboard data)]]
         [:button {:class "modal-close is-large" :aria-label "close"}]])}))

  (defn- modal [data]
    (let [modal-portal (.createElement js/document "div")]
      (.setAttribute modal-portal "id" "modal-portal")
      (.appendChild (.-body js/document) modal-portal)
      (react-dom/createPortal [modal-div data] modal-portal))))
This doesn't throw any errors, it just renders an empty div -> <div id="modal-portal"></div>

juhoteperi17:01:11

create-class doesn't replace as-element use (react-dom/createPortal (r/as-element [modal-div data]) modal-portal) no matter if the modal-div is form-1/2/3

juhoteperi17:01:45

You could consider using hooks instead of form-3 lifecycle methods also

samoleary17:01:13

Thanks! I'll check out how to use hooks 👍