Say I want to scroll to an element after a page is rendered. How do I do this? I am using re-frame too. I’ve come to understand that the #element-anchor tag does not work. What I need to do is pick out the # element the router provides me, but here I’m stumped; when is it ok to call (.scrollTo …) or similar when rendering the page??
The anchors work, but only within a page that has already been rendered.
I usually don't think too hard about it:
- Turn a component that has an anchor into a form-3 component
- In the :component-did-mount
, check the URL if it has its fragment equal to that anchor
- If yes, scroll to the element
It won't work exactly like it works for plain HTML pages (e.g. if your component re-mounts, then the page will be scrolled again), but you can fix it if needed.
ok, do I need to remove the anchor afterwards?
I’ll guess I’ll figure that out myself, thanks for the input!!
Here’s an alternative you might consider:
(rf/reg-event-fx
::scroll-error-into-view
(fn [_ _]
(r/after-render #(when-let [el (first (dom/by-class "error"))]
(.scrollIntoView el)))
nil))
Nice!
A few things:
- The snippet above assumes using re-frame, but this is #reagent - probably, it could be replaced with just r/after-render
somewhere, not sure
- The event handler in impure, which is discouraged. But the code can be moved to an effect handler.
- The code checks for some predefined class - it has nothing to do with anchors
right, but I never seen the r/after-render used before
This worked out just fine, using a form-3 component
All valid points! I just thought it might lead to a solution that’s a little lighter-weight than a form-3 component.
where's the documentation for the current method of using react libraries from reagent (with shadow-cljs)?
On importing stuff - shadow-cljs documentation. On using React components from within Reagent - Reagent documentation. Lots and lots of relevant documents, articles, and examples, the most relevant ones are right in the Reagent repo.
a more specific question on the integration of https://github.com/plotly/react-cytoscapejs as a react component from my reagent application:
since I'm using shadow-cljs
, I installed the dependency via npm install react-cytoscapejs
, and I'm importing and try to use it via:
(ns minimal.ui
:require
["react-cytoscapejs" :as rcyto :default CytoscapeComponent])
(defn home-page []
[:div
[:> CytoscapeComponent {:elements {:data {:id 1}}}]])
This gives me a lot of errors in the console. I suspect that's because I'm not faithfully translating the example at the end of https://github.com/plotly/react-cytoscapejs#usage
Do I have to wrap the react component in a component of my own?What is the very first error?
module$node_modules$react$cjs$react_development.js:5 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `minimal.ui.home_page`.
in minimal.ui.home_page
It's the :require
section then, most likely.
Check out this part: https://shadow-cljs.github.io/docs/UsersGuide.html#_about_default_exports
I get the same error with:
(ns minimal.ui
:require
["react-cytoscapejs" :as rcyto])
(defn home-page []
[:div
[:> rcyto/CytoscapeComponent {:elements {:data {:id 1}}}]])
is this what you had in mind?Just do (js/console.log rcyto)
at the top level and see what it outputs, proceed from there.
I get an object that seems the right one
And (js/console.log rcyto/CytoscapeComponent)
outputs the component itself?
my question was more along the line: given the example at the end of https://github.com/plotly/react-cytoscapejs#usage, is what I'm doing even supposed to work?
no that prints undefined
😮
Well, there you go.
Try with just [:> rcyto ...]
.
If it works, simply rename rcyto
to CytoscapeComponent
or whatever you prefer.
no, it doesn't like the object it gets, apparently:
module$node_modules$react_cytoscapejs$dist$react_cytoscape.js:6 Uncaught TypeError: e.forEach is not a function
at least it's not undefined anymorebut rcyto
is the right object, because it has the methods I would expect
That's a different error.
And yeah, your code is incorrect. elements
is very different from the original example.
when I say In react:
<CytoscapeComponent elements={elements} style={ { width: '600px', height: '600px' } } />
how would I pass both elements
and style
? Can I use something like:
{:elements ...
:style ...}
Yep.
ok, everything works now, thank you so much for teaching me how it's done!