Fork me on GitHub
#reagent
<
2021-05-01
>
Schpaa14:05:38

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??

p-himik14:05:54

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.

Schpaa14:05:22

ok, do I need to remove the anchor afterwards?

Schpaa14:05:51

I’ll guess I’ll figure that out myself, thanks for the input!!

jkrasnay14:05:38

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))

😀 3
p-himik14:05:30

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

Schpaa14:05:13

right, but I never seen the r/after-render used before

Schpaa15:05:03

This worked out just fine, using a form-3 component

jkrasnay15:05:41

All valid points! I just thought it might lead to a solution that’s a little lighter-weight than a form-3 component.

Carlo16:05:20

where's the documentation for the current method of using react libraries from reagent (with shadow-cljs)?

p-himik16:05:01

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.

🙌 3
Carlo17:05:48

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?

p-himik17:05:51

What is the very first error?

Carlo17:05:31

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

p-himik17:05:17

It's the :require section then, most likely. Check out this part: https://shadow-cljs.github.io/docs/UsersGuide.html#_about_default_exports

Carlo17:05:54

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?

p-himik17:05:31

Just do (js/console.log rcyto) at the top level and see what it outputs, proceed from there.

Carlo17:05:37

I get an object that seems the right one

p-himik17:05:54

And (js/console.log rcyto/CytoscapeComponent) outputs the component itself?

Carlo17:05:55

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?

Carlo17:05:37

no that prints undefined 😮

p-himik17:05:45

Well, there you go.

p-himik17:05:53

Try with just [:> rcyto ...].

p-himik17:05:15

If it works, simply rename rcyto to CytoscapeComponent or whatever you prefer.

Carlo17:05:02

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 anymore

Carlo17:05:26

but rcyto is the right object, because it has the methods I would expect

p-himik17:05:29

That's a different error. And yeah, your code is incorrect. elements is very different from the original example.

Carlo17:05:30

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 ...}

Carlo17:05:19

ok, everything works now, thank you so much for teaching me how it's done!

👍 3