I am trying to use an external library thing (https://github.com/sanderlab/AlignmentViewer2.0) in my Reagent project.
[:> AlignmentViewer {:alignment (.fromFileContents FastaAlignment "ALIGNMENT_NAME" fasta)}]
This fails because of an Invalid hook call. Hooks can only be called inside of the body of a function component. originating in the AlignmentViewer AlignmentViewerHook.js:118
Okay so it's a functional component, I guess. Am I doing the interop wrong or is there something else going on?Quickly checked the lib, but I'd need more context of your code. The error is about using a hook outside a component, is your function inside a Reagent component?
Probably this component you imported has a hook inside and that's the reason fo the error. The code you showed doesn't has a hook usage, please share more context to get a more accurate answer
Yeah, it is in a Reagent component I am basically trying to translate this hello world section of their readme to CLJS https://github.com/sanderlab/AlignmentViewer2.0?tab=readme-ov-file#embedding-alignment-viewer-20 Here is what basically what I am doing
(require '["alignment-viewer-2" :refer [AlignmentViewer FastaAlignment]])
(def fasta
(str ">target\n"
"ATGCATGC\n"
">seq1\n"
"AAAACCCC\n"
">seq2\n"
"ATGCATTT\n"
">seq3\n"
"ATGCAAAA\n"))
(defn ^:dev/after-load mount-root []
(let [root-el (.getElementById js/document "app")]
(rdom/unmount-component-at-node root-el)
(rdom/render [:> AlignmentViewer {:alignment (.fromFileContents FastaAlignment "ALIGNMENT_NAME" fasta)}]
root-el)))
I assume the :> interop doesn't really work with functional components (i.e. components using hooks)
No, that should be fine. I just tried - it seems that it's exactly the same issue as here: https://clojurians.slack.com/archives/C0620C0C8/p1736964220580399?thread_ts=1736962115.578929&cid=C0620C0C8
In other words, try adding
"overrides": {
"alignment-viewer-2": {
"react": "$react",
"react-dom": "$react-dom"
}
}
to package.json, nuke node_modules and package-lock.json, and run npm i again. I really, really hate NPM for crap like this, among a plethora of other things.In any case, even with that it will not work because the package expects to have that SCSS import available, which shadow-cljs cannot provide. If you use webpack or something like that, it should work just fine. If not, at the very least you have to create and provide the color scheme explicitly. Maybe something else will fail after that - I haven't tried fixing anything beyond the hooks error.
There are 15 SCSS files that are imported in JS. So unless you want to keep on fixing stuff that might be not fixable, you would be better of with just using webpack together with shadow-cljs.
The SCSS compilation error didn't raise its head again after I added :js-options {:ignore-asset-requires true} , although I am not at all aware of the consequences of this. I'll look into the webpack thing instead.
It seems the AlignmentViewer does need at least react 18, it tries to use stuff that doesnt exist when I fix everything to react 17 - so I updated but that throws over my rendering
ReactDOM.render is no longer supported in React 18. Use createRoot instead.
I remember having seen that before but I can't find how to call createRoot
It was something like this, right?
(defonce root-el (createRoot (gdom/getElement "app")))
(defn ^:dev/after-load mount-root []
(let [root (createRoot root-el)]
(rdom/unmount-component-at-node root-el)
(.render root (r/as-element [:> AlignmentViewer {:alignment (.fromFileContents FastaAlignment "ALIGNMENT_NAME" fasta)}]))))
Error: createRoot(...): Target container is not a DOM element.Okay its late for me, I was just calling createRoot twice and now color schemes are missing, so obviously it was a stupid idea to ignore asset requires. But that should set me on the way, will learn about webpack tomorrow then. Thanks a lot @p-himik you're a hero