Fork me on GitHub
#reagent
<
2020-06-26
>
David Pham07:06:01

Can you wrap the body of the let in a (fn [] body)

juhoteperi09:06:39

People were asking about Framer-motion hera and on Github so I tested it with Reagent and at least this simple case works: https://github.com/reagent-project/reagent/compare/framer-motion-example

🎉 3
👍 3
❤️ 3
👏 3
pmooser10:06:22

Can anyone help me understand how to translate a component like this into a reagent one?

import ReactMarkdown from 'react-markdown';
import MathJax from 'react-mathjax';
import RemarkMathPlugin from 'remark-math';

function MarkdownRender(props) {
    const newProps = {
        ...props,
        plugins: [
          RemarkMathPlugin,
        ],
        renderers: {
          ...props.renderers,
          math: (props) => 
            <MathJax.Node formula={props.value} />,
          inlineMath: (props) =>
            <MathJax.Node inline formula={props.value} />
        }
      };
      return (
        <MathJax.Provider input="tex">
            <ReactMarkdown {...newProps} />
        </MathJax.Provider>
      );
}

export default MarkdownRender

pmooser10:06:41

I specifically don't quite know how to handle the renderers and with the return statement.

pmooser10:06:49

I always have the hardest time figuring out any kind of direct React interop in any non-trivial case.

pmooser10:06:04

The examples consist mostly of like [:> ReactComponent] and whee you're done.

juhoteperi10:06:48

(defn markdown-render [props]
  [:> (.-Provider MathJax)
   {:input "text"}
   [:> ReactMarkdown
    (merge props
           {:plugins [RemarkMathPlugin]
            :renderers (merge (:renderers props)
                              {:math (fn [js-props]
                                       (r/as-element [:> (.-Node MathJax) {:formula (.-value js-props)}]))
                               :inlineMath (fn [js-props]
                                             (r/as-element [:> (.-Node MathJax) {:inline true :formula (.-value js-props)}]))})})]])

pmooser10:06:24

@juhoteperi Thank you so much. Let me give this a try.

juhoteperi10:06:46

... is just into or merge, not really React specific. Only gotcha is to use as-element or reactify-component or such with function in the props that need to return React elements

juhoteperi10:06:04

As hiccup syntax within the function is not autoamtically converted by Reagent

juhoteperi10:06:40

And note that props argument for those renderers is the js object

p-himik10:06:17

There are 3 main things one has to understand in order to painlessly interop with React components - A difference between components, instances, and elements - When and how Reagent converts CLJS data structures into JS ones and vice versa - How exactly the props you pass to the underlying React components will be used Maybe I'm forgetting something - let me know.

pmooser10:06:50

@juhoteperi So in that case, how do you use markdown-render ? What has to be in props?

juhoteperi10:06:03

markdown-render props is cljs map

pmooser10:06:21

@p-himik Yeah, despite having used reagent itself for a few years now, I don't have a great understanding of those things, unfortunately.

pmooser11:06:56

Wow, it works!

pmooser11:06:04

Now I just have to dig into this example to really understand it.

juhoteperi11:06:07

:> is unfortunately not very clear on what it converts. :r> or create-element is more obvious as you have to convert everything to JS objects yourself.

juhoteperi11:06:46

With :r> and create-element it could look like this:

(defn markdown-render [props]
  [:r> (.-Provider MathJax)
   #js {:input "text"}
   [:> ReactMarkdown
    (clj->js (merge props
                    {:plugins #js [RemarkMathPlugin]
                     :renderers (clj->js (merge (:renderers props)
                                                {:math (fn [js-props]
                                                         (r/create-element (.-Node MathJax) #js {:formula (.-value js-props)}))
                                                 :inlineMath (fn [js-props]
                                                               (r/create-element (.-Node MathJax) #js {:inline true :formula (.-value js-props)}))}))}))]])

pmooser11:06:29

So the fundamental things I got wrong was: 1. not calling as-element on my return values from the renderers 2. Not knowing how to express "MathJax.Node" (for example) as (.-Node MathJax).

pmooser11:06:44

I didn't even know :r> existed!!!!

juhoteperi11:06:10

Just in latest 1.0.0-alpha2

juhoteperi11:06:50

It is probably only mentioned in the changelog and the issue

pmooser11:06:24

@juhoteperi Thanks again for your help. If I ever run into you at a clojure conference, I owe you the drink of your choice. 🙂

🍻 6