Fork me on GitHub
#reagent
<
2018-01-07
>
chris_20:01:28

Can I ask a dumb question? When semantic-ui-react expects an anonymous Js function that returns a component to render, e.g. ... {menuItem: 'Tab 1', render: () => <Tab.Pane>Tab 1 Content</Tab.Pane> } (that code is from: https://react.semantic-ui.com/modules/tab#tab-example-basic) ... what is the Clojurescript equivalent, using your approach? I assumed something like ...

(def tabs
  [{:menuItem "Login" :render [sa/TabPane [login-form]]}
   {:menuItem "Register" :render [sa/TabPane [registration-form]]}])

(defn login-or-register-form []
  [sa/Tab {:panes tabs}])
… but I get errors upon errors (e.g. “e.call is not a function”; screenshot attached). This happens whether I’m using soda-ash or kennethkalmer’s approach (https://www.opensourcery.co.za/2017/02/12/using-semantic-ui-react-with-re-frame/) Any help or insights you could offer would be greatly appreciated 🙂 Many thanks!

chris_20:01:15

To be clear, I have other semantic-ui-react components (Grid, Search) working in my app already.

mikerod20:01:53

@chris_ I think what you want is reagent.core/as-element

mikerod20:01:16

I’m not sure about doing that within a static var definition though

mikerod20:01:39

Actually, ignore that, I don’t think that matters. So for your example:

mikerod20:01:10

(require '[reagent.core :as r])

(def tabs
  [{:menuItem "Login" :render (r/as-element [sa/TabPane [login-form]])}
   {:menuItem "Register" :render (r/as-element [sa/TabPane [registration-form]])}])

(defn login-or-register-form []
  [sa/Tab {:panes tabs}])

mikerod20:01:09

I’m not 100% sure that doing it in a var that evaluated prior to the “render” being called on login-or-register-form would never have any odd consequences. I don’t think it should in this case. Especially since there are no props being passed along or any reactive atom dereferences.

mikerod20:01:30

However, I think I’d typically go with something like:

mikerod20:01:35

(defn login-or-register-form []
  (let [tabs [{:menuItem "Login" :render (r/as-element [sa/TabPane [login-form]])}
              {:menuItem "Register" :render (r/as-element [sa/TabPane [registration-form]])}]]
    [sa/Tab {:panes tabs}]))

chris_20:01:43

(def tabs
  [{:menuItem "Login" :render (fn [] (reagent/as-element [sa/TabPane [login-form]]))}
   {:menuItem "Register" :render (fn [] (reagent/as-element [sa/TabPane [registration-form]]))}])

chris_20:01:54

^^ That just worked beautifully

mikerod20:01:56

Oh yeanh, you actually need to supply a render fn right? I missed that part

mikerod20:01:01

Sorry for confusion

chris_20:01:17

np; you identified the major problem 😄

mikerod20:01:24

Yes, a fn that returns the as-element over the hiccup makes sense.

chris_20:01:48

I think I’ll need to dig deeper into reagent fundamentals.

mikerod20:01:11

It’s a bit old

mikerod20:01:18

however, I did find reading all posts in http://reagent-project.github.io/news valuable

mikerod20:01:27

Just read them starting at oldest and realizing things have changed a bit over time hah

mikerod20:01:11

In particular, http://reagent-project.github.io/news/news050.html discusses enhancements that were made for React interop

mikerod20:01:17

And as-element is mentioned among them.

chris_20:01:18

I guess I had assumed that “coercion to react element” happened automatically

mikerod20:01:02

Not in cases like htat

mikerod20:01:10

Probably not too feasible

mikerod20:01:27

hard to know that the underlying React component you are interoperating with has props with that semantic meaning

mikerod20:01:50

i.e. hard to know there is a prop named :render that is specifically wanting you to pass a render fn - this isn’t a React built-in concept

mikerod20:01:55

When interop’ing with various React libs, you’ll probably typically find you have to use one of the few interop functions of Reagent

mikerod20:01:09

as-component and adapt-react-class are too I’ve commonly used

mikerod20:01:15

(for different reasons)

chris_20:01:00

I ran into an issue with semantic-ui-react’s Popover component’s trigger prop, so I’ll see if I can solve that too using Reagent’s interop functions

chris_20:01:30

and thank you @gadfly361 for the nice soda-ash library

mikerod20:01:41

No problem. Feel free to ask if you have more questions like this.