reagent

A minimalistic ClojureScript interface to React.js http://reagent-project.github.io/
2020-07-14T04:07:40.001500Z

Anyone know how to get a react-bootstrap/Popover to work, with the overlay attribute? I’ve seen popovers which work and are always visible (https://react-bootstrap.github.io/components/overlays/#popovers), but no examples of using the overlay attr with react-bootstrap/OverlayTrigger .

2020-07-14T04:08:06.001600Z

I guess my question is how do you pass the popover component to the overlay attribute?

2020-07-14T05:54:41.001800Z

Hmmm, looks like I had to pass a plain old React element (via r/create-element) to the overlay attribute.

2020-07-14T14:07:43.003400Z

Does anyone have any insight into debugging event delivery and propagation in reagent? I'm trying to implement copy/paste on a div, and I just can't get the event handler to work on my particular div- weirdly, it worked when my div had some other random absolutely-positioned div as a child, but when I made that child user-select: none the copy-events stopped as well.

2020-07-16T13:42:39.043Z

Thank you - that's more or less what I ended up doing, with a document-level copy/paste listener. It has its own challenges, but it seems more manageable since it's in my control.

2020-07-14T14:08:36.004300Z

I've tried to use monitorEvents which lets me see that events are being fired (I guess this probably just works in Chrome), but I can't really see why they're being fired on the body of the document, instead of on my component.

2020-07-14T14:11:19.004800Z

It appears (uhhhhhh) if I include like a blank text node, like " " in the body of my div, the copy event fires.

2020-07-14T14:14:31.005300Z

But ... that only works on the first component of this type. Just as well not to have a hack like that actually fix anything.

2020-07-14T14:15:06.005700Z

Other event handlers on the same component (like on-blur ) seem totally reliable.

unbalanced 2020-07-14T15:43:49.005900Z

The way I handle this is probably not helpful to your specific use-case but perhaps something to think about -- I have a rule that everything that occurs is tied back to data, so that the page does not care if the event comes from a user click, the server, or a REPL command. All events go to a centralized queue and are processed sequentially. Then I monitor the event queue and ensure that the data is correct. This way I can separate the concerns of the event listener, the data, and the event handler

unbalanced 2020-07-14T15:44:39.006100Z

Again I realize it may not help your specific situation but it is the frustration you are experiencing that led me to write cljs apps the way I described above

2020-07-14T15:54:37.007200Z

Is it possible to write react component with ClojureScript and expose them such that other JavaScript project use them?

p-himik 2020-07-14T15:58:57.007300Z

Yes, you should be able to use exported symbols just fine.

2020-07-14T16:02:27.007700Z

Would that work? XD

p-himik 2020-07-14T16:03:03.008600Z

I don't see any reason for it to not work. React components are not magic.

2020-07-14T16:03:04.008900Z

Okay, seems I can work with other JS dev.

p-himik 2020-07-14T16:03:39.009100Z

But note that you will have to create React components, not Reagent components.

benny 2020-07-14T18:45:14.010500Z

how do i access a static member of a product of adapt-react-class?

benny 2020-07-14T18:46:24.011500Z

i.e. https://github.com/facebook/react-native/blob/master/Libraries/Components/Touchable/TouchableNativeFeedback.js

class TouchableNativeFeedback extends React.Component<Props, State> {
...
  static Ripple: (_) => ..

lilactown 2020-07-14T18:47:04.011800Z

access the underlying component

lilactown 2020-07-14T18:48:48.013100Z

(def touchable-native-feedback (r/adapt-react-class TouchableNativeFeedback))

(def ripple (.-Ripple TouchableNativeFeedback))

benny 2020-07-14T18:51:38.013600Z

that’s what i assumed and tried before i posted, but somehow am getting nothing back

lilactown 2020-07-14T18:55:29.014100Z

try logging TouchableNativeFeedback and see if it is in fact the class, or something else

benny 2020-07-14T18:56:11.014400Z

it’s #object[reagent.impl.template.NativeWrapper]

benny 2020-07-14T18:56:27.014800Z

(def feedback (reagent/adapt-react-class react/TouchableNativeFeedback))
(def ripple (.-Ripple feedback))
(prn ripple)
results in nil 😕

lilactown 2020-07-14T18:58:32.015Z

No no

lilactown 2020-07-14T18:58:44.015400Z

You have to access the class, not the wrapper

lilactown 2020-07-14T18:58:58.015900Z

Re read my example, yours is not identical

benny 2020-07-14T18:59:09.016100Z

ahh

benny 2020-07-14T18:59:46.016800Z

that does it! thanks @lilactown!

lilactown 2020-07-14T18:59:54.017100Z

Woo!

rberger 2020-07-14T19:59:52.017500Z

Ok, what does [:f> mean?

2020-07-14T20:02:22.018Z

I know that :> is used to create a react class inside the reagent vector/hash-map DSL

rberger 2020-07-14T20:02:35.018400Z

I suspect its something really good

2020-07-14T20:02:36.018500Z

I assume :f> is similar

2020-07-14T20:03:19.019400Z

here's a match in the commit history https://github.com/reagent-project/reagent/commit/44259277942fe0db77f198330467c81180f07855

rberger 2020-07-14T20:03:21.019600Z

Its hard to lookup /google the meaning of these symbol style things.

juhoteperi 2020-07-14T20:03:23.019900Z

Not properly documented yet, but: https://github.com/reagent-project/reagent/blob/master/doc/ReactFeatures.md#hooks

juhoteperi 2020-07-14T20:04:47.020200Z

https://github.com/reagent-project/reagent/issues/494

juhoteperi 2020-07-14T20:05:06.020500Z

changelog mentions them also

2020-07-14T20:06:16.020800Z

all matches in master:

est/reagent/impl/util_test.cljs:139:  (is (= 1 (util/react-key-from-vec [:f> "div" {:key 1} "bar"])))
test/reagenttest/testreagent.cljs:607:                                      [:f> f {:key 1} "a"]
test/reagenttest/testreagent.cljs:608:                                      [:f> f {:key 2} "b"])]
test/reagenttest/testreagent.cljs:1564:        (testing ":f>"
test/reagenttest/testreagent.cljs:1565:          (with-mounted-component [:f> c "foo"]
CHANGELOG.md:8:- Added `:f>` shortcut to create Function component from ClojureScript
examples/functional-components-and-hooks/src/example/core.cljs:38:     ;; Or with the default options you can create function components using :f> shortcut:
examples/functional-components-and-hooks/src/example/core.cljs:41:     [:f> clock time-color]
examples/functional-components-and-hooks/src/example/core.cljs:42:     [:f> color-input time-color update-time-color]
examples/functional-components-and-hooks/src/example/core.cljs:51:  (rdom/render [:f> simple-example] (js/document.getElementById "app"))
src/reagent/impl/template.cljs:275:      :f> (function-element (nth v 1 nil) v 2 compiler)
src/reagent/impl/util.cljs:228:        (:> :f>) (get-react-key (nth v 2 nil))

(1 of 12): (is (= 1 (util/react-key-from-vec [:f> "div" {:key 1} "bar"])))

2020-07-14T20:06:45.021400Z

that search works with ag locally, but not in the github search functionality

2020-07-14T20:08:36.021600Z

this looks informative

(testing ":f>"
          (with-mounted-component [:f> c "foo"]
            (fn [c div]
              (is (nil? c) "Render returns nil for stateless components")
              (is (= "Hello foo" (.-innerText div))))))

2020-07-14T20:09:38.021900Z

and this from an example ns

(defn simple-example []
  (let [[time-color update-time-color] (react/useState "#f34")]
    [:div
     [greeting "Hello world, it is now"]
     [clock time-color]
     [color-input time-color update-time-color]

     ;; Or with the default options you can create function components using :f> shortcut:
     #_#_#_
     [greeting "Hello world, it is now"]
     [:f> clock time-color]
     [:f> color-input time-color update-time-color]
     ]))

2020-07-14T20:11:01.022500Z

finally, the :f> tag translates to this in reagent/impl/template.cljs

(defn function-element [tag v first-arg compiler]
  (let [jsprops #js {}]
    (set! (.-reagentRender jsprops) tag)
    (set! (.-argv jsprops) (subvec v first-arg))
    ; (set! (.-opts jsprops) opts)
    (when-some [key (util/react-key-from-vec v)]
      (set! (.-key jsprops) key))
    (react/createElement (comp/functional-render-fn compiler tag) jsprops)))

2020-07-14T20:15:01.025Z

hi friends, noticing that my reagent components will re render when the r/atom value has not changed, with something like repeated (swap! state assoc :foo [1]) calls, where a repeated (swap! state assoc :foo 1) does not. Is there any explanation or literature on why this causes re-renders?

juhoteperi 2020-07-14T20:20:29.026Z

@selfsame https://github.com/reagent-project/reagent/blob/master/doc/WhenDoComponentsUpdate.md#changed (just ignore update about 0.6.0, I think that isn't accurate)

juhoteperi 2020-07-14T20:20:39.026500Z

user=> (identical? [1] [1])
false
user=> (= [1] [1])
true

2020-07-14T20:20:43.026600Z

doesn't reagent use identity checks to speed up its check for dirty nodes?

2020-07-14T20:21:01.027200Z

yeah, what @juhoteperi said

2020-07-14T20:21:58.028300Z

@selfsame I've tried, for style reasons, to group nearby changes into a single call for that reason - for example I can use assoc with N k/v pairs, or use a single swap function with multiple steps, instead of multiple steps calling swap

2020-07-14T20:22:45.029100Z

of course this kind of refactor isn't always simple, but when it is, it's like free protection from pointless re-renders

juhoteperi 2020-07-14T20:24:09.030400Z

Updating multiple atoms etc. with separate calls from same function probably doesn't trigger multiple render calls, as rendering is batched using requestAnimationFrame, but anyway, one shouldn't presume how many times render is called etc.

2020-07-14T20:24:34.031100Z

good point, thanks

2020-07-14T20:25:18.031800Z

also coming from clojure I've learned not to treat swap! as if it were free (though it's likely cheaper in cljs)

juhoteperi 2020-07-14T20:25:31.032Z

In React Strict mode, React in fact calls render multiple times and ensures it always returns the same value to ensure it is pure

2020-07-14T20:25:46.032200Z

ah great, thanks for the clarification!

rberger 2020-07-14T20:53:41.035100Z

@noisesmith Thanks for digging into it! This looks like part of an exciting new features for making it easier to work with react. Which will be really helpful! Hopefully enhanced docs will be forthcoming soon.