Fork me on GitHub
#cljsrn
<
2018-12-28
>
Kelly Innes04:12:45

Hi! Question: I'm trying to get a React Navigation tab navigator working in a Reagent/ClojureScript project. I've got the tab part working, but I can't figure out what is the right thing to pass in navigationOptions to get a custom icon to show up.

Kelly Innes04:12:23

The main part is this, which seems like it should be rendering the tabBarIcon correctly but won't for some reason:

Kelly Innes04:12:27

(defn greeter-icon
  []
  [ic {:name "smile-o"}])

(defn home
  []
  (create-tab-navigator
   (clj->js {"Counter" {"screen" (r/reactify-component counter)}
             "Greeter" {"screen" (r/reactify-component greeter)
                        "navigationOptions" (fn []
                                              (clj->js {"title" "Hello!"
                                                        "tabBarIcon" (r/reactify-component greeter-icon)}))}})))

Kelly Innes05:12:00

Is there something I'm doing that's obviously wrong? FWIW I know React pretty thoroughly, but I'm new to ClojureScript

Kelly Innes05:12:39

According to the docs the tabBarIcon option accepts either a function which returns a React element or a React element on its own

jimberlage05:12:45

Right now you have navigationOptions accepting a function, not tabBarIcon - is that intended?

Kelly Innes05:12:04

Yeah, that's intended -- it seems like a quirk of the API

Kelly Innes05:12:23

navigationOptions takes a function which returns an object, some of whose keys can have function values

Kelly Innes05:12:51

The title option works if I change it, btw.

jimberlage05:12:56

Try (r/reactify-component [greeter-icon])

jimberlage05:12:56

I think you have to wrap it in a vector. Kind of like in JSX - you wouldn’t pass in just the naked GreeterIcon class, you’d pass in <GreeterIcon />

Kelly Innes05:12:14

Ah, right, that makes sense -- I'll give it a try!

Kelly Innes05:12:05

Hm, unfortunately that didn't work. I tried out a bunch of other permutations too and the outcome would vacillate between: null is not an object (evaluations this.__reactAutobindPairs on a red error screen or actually rendering the app but complaining that I had passed an uncalled function as a child component

Kelly Innes05:12:23

This "works" in the sense that it renders to correct thing -- a null icon:

Kelly Innes05:12:29

(defn new-icon
  []
  nil)

(defn home
  []
  (create-tab-navigator
   (clj->js {"Counter" {"screen" (r/reactify-component counter)}
             "Greeter" {"screen" (r/reactify-component greeter)
                        "navigationOptions" (fn []
                                              (clj->js {"title" "Greeter!"
                                                        "tabBarIcon" new-icon}))}})))

joshmiller21:12:01

@kinnes Looking at my tab bar navigator, I’m getting tab bar icons via the tab-screen fn in cljs-react-navigation which provides a bunch of useful helper fns for this kinda stuff. Yours would end up looking like…

(tab-navigator {:Counter {:screen (tab-screen counter)} :Greeter {:screen (tab-screen greeter {:tabBarLabel "Greeeter!" :tabBarIcon new-icon})}}})

Kelly Innes22:12:59

Awesome! I saw that library but didn't try it yet. Seems like it might have a nicer interface than the thing I was trying.