Fork me on GitHub
#reagent
<
2021-12-05
>
Dharmendra20:12:50

Hi, For one of the props below I tried to do the same in Reagent but seems it is not working. Can you please let me know what is wrong in below code.

renderOption={(props, option) => (
        <li {...props}>
          {option.value}
        </li>
      )}
Trying in in Reagent below but it is not working.
:render-option   (fn [props option]
                      [:li props
                          (:value option)])

p-himik20:12:15

renderOption expects a function that returns a React element. Yours returns a vector - you have to turn it into a React element yourself, so wrap its result in reagent.core/as-element. Do note that props and option are probably JS objects - it should be fine when you just pass props to :li, but you definitely won't get the value by using (:value option). Instead, use (.-value ^js option).

Dharmendra20:12:00

Just now tried as-element but it is still not working 😞

:render-option (fn [props option]
                 (reagent.core/as-element [:li props
                                           (.-value ^js option)]))
and
:render-option (fn [^js props ^js option]
                   (r/as-element [:li props
                                  (.-value option)]))

p-himik20:12:24

How exactly does it not work? Are you sure it's this exact place that's causing the issue? What if you wrap props in js->clj?

👍 1
Dharmendra20:12:52

Thank you, it is working fine if I wrap props in js->clj like below. But I did not understand. Do I need to use js->clj here?

:render-option (fn [^js props ^js option]
                  (r/as-element [:li (merge (js->clj props) {:key (.-value option)})
                                 (.-value option)]))

p-himik21:12:32

With merge - yeah. But as is - I was half-certain you didn't need to convert the JS object into a CLJS map, but maybe I'm wrong. Ideally, you wouldn't use js->clj because it's deep, whereas you'd need a shallow conversion here. When I was presented with a similar issue, I had to write my own version of a shallow js->clj, but fortunately is an easy task given that you don't have to check for any types - you know that it's a regular JS object here.

👍 1
p-himik21:12:06

Just in case - js->clj is not just a performance concern. By converting objects deeply, it violates identities which might be important, e.g. for refs. A ref object must be the same - js->clj will create a new one, breaking something.