reagent

Michael 2023-02-02T00:02:10.694469Z

How feasible is it to create a reagent project that's used as a react component library? Looks like the starter project is meant to be served as a web application.

p-himik 2023-02-02T09:13:41.577859Z

If you mean creating a Reagent-using component that you will use from a plain React app, then it's not feasible. Re-com is a different thing - it's a Reagent library intended to be used from Reagent. Reagent even uses a custom render function to render the whole app - you can't tell a third-party app to somehow do that.

Rupert (Sevva/All Street) 2023-02-02T10:15:46.161229Z

You can expose clojurescript functions that can be called from JavaScript. With reagent these may need to start a new react context - so there will be a little overhead. Might be worth seeing if this is possible with uix or helix - but it might be the same. Another new/experimental/unfinished option is to use https://github.com/squint-cljs/squint to write JavaScript with Clojure like syntax.

Michael 2023-02-02T20:29:06.391169Z

@p-himik this is what I was trying to do. thanks for clearing it up

hifumi123 2023-02-02T01:01:33.611799Z

I would say “very feasible”. Take a look at re-com for some inspiration, although it uses re-frame for state management. Some workplaces also have their own UI library. Unfortunately that code is not open source 😐

Michael 2023-02-02T02:18:53.596069Z

thanks. will take a look

Michael 2023-02-07T09:33:32.443759Z

@p-himik sorry to ping you, but (concerning reagent-react interop) have you seen/tried https://cljdoc.org/d/reagent/reagent/1.0.0/doc/tutorials/interop-with-react#creating-react-components-from-reagent-components? I might give this a shot when I have time tomorrow but just wondering since all I've tried regarding reagent so far was just the default template they provide (which I think does the custom rendering stuff you were talking about)

p-himik 2023-02-07T09:34:44.239369Z

That document describes how to create React components that you consume within the same Reagent app. It won't work for a library that needs to be embedded in a larger React-only app.

Izzy Lancaster 2023-02-02T04:53:16.811439Z

Hello everyone! I'm a bit new to clojurescript and reagent, but familiar with web dev and react. I'm trying to figure out how to define a component that takes children for a tree-view component I'm building. I'm using & children in the component's parameters, but when this renders, Reagent complains about how "Every element in a seq should have a unique :key". Anyone know fix this? Here's the code for my tree-view component:

(defn tree-view-item [{:keys [label]} & children]
  [:li.tree-view-item 
   [:div 
    [:span.icon-container (if children "\u25B9" ())]
    [:span.label label]]
   (if children [:ul.tree-view-group children] ())])

p-himik 2023-02-02T09:15:05.440549Z

You can use into:

(when children
  (into [:ul.tree-view-group] children))
(no need for empty lists)

Rupert (Sevva/All Street) 2023-02-02T10:11:15.138859Z

I think into is a good solution - another one is to add the :key metadata to each item e.g. (map-indexed (fn [i x] (with-meta x { :key (str "x" i)})) <data>)

p-himik 2023-02-02T10:21:51.205339Z

Don't do that - don't use positional indices as keys. React describes why not in its documentation.

👍 1
Rupert (Sevva/All Street) 2023-02-02T14:49:04.771919Z

I think it's fine if you know they the items are not going to change (ie no additions/removals or re-ordering). map-indexed was just as a generic example - if you have a stable key then certainly use that first or the into code you mentioned.

Izzy Lancaster 2023-02-02T18:18:02.356139Z

Thanks for the help, the when construct is really handy to know about. But I'm curious, why does it into work here?

Rupert (Sevva/All Street) 2023-02-02T18:20:21.215899Z

into is just adding the elements into the vector e.g. [:div "hello" "clojure" "world"] === (into [:div] (list "hello" "clojure" "world"))

Izzy Lancaster 2023-02-02T18:21:00.513739Z

I understand that much. I don't understand why doing that solves the error

Rupert (Sevva/All Street) 2023-02-02T18:23:48.525619Z

When you have a list with keys or elements directly inside of vectors - reagent/react can efficiently work out which elements have changed and only re-render the ones that it needs to. If you have a list of 100s of elements and the first one is removed - it doesn't have to rerender all the others if you are using a list with keys.

p-himik 2023-02-02T19:32:35.889429Z

> why doing that solves the error Reagent checks if something is a seq, and if it is, it issues that warning because, I assume, it doesn't want to try and figure out whether it's a lazy seq or not. Using into removes that lazy seq and makes all children known in advance. And Rupert's message describes why such a warning is useful. Although the commit in Reagent that introduced it makes me think that there were some issues besides performance.