This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-02-02
Channels
- # announcements (3)
- # asami (29)
- # babashka (62)
- # beginners (131)
- # biff (7)
- # calva (31)
- # cider (5)
- # clerk (14)
- # clj-kondo (3)
- # cljsrn (12)
- # clojars (18)
- # clojure (72)
- # clojure-austin (17)
- # clojure-dev (6)
- # clojure-europe (31)
- # clojure-indonesia (1)
- # clojure-nl (1)
- # clojure-norway (18)
- # clojure-sweden (11)
- # clojure-uk (6)
- # clr (47)
- # conjure (42)
- # cursive (88)
- # datalevin (2)
- # datomic (25)
- # emacs (42)
- # exercism (1)
- # fulcro (10)
- # funcool (8)
- # gratitude (2)
- # honeysql (16)
- # introduce-yourself (5)
- # jobs-discuss (26)
- # leiningen (5)
- # lsp (31)
- # malli (21)
- # matcher-combinators (14)
- # missionary (2)
- # nbb (1)
- # off-topic (40)
- # pathom (38)
- # portal (2)
- # re-frame (7)
- # reagent (18)
- # reitit (1)
- # releases (5)
- # shadow-cljs (62)
- # sql (12)
- # testing (4)
- # xtdb (37)
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.
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 😐
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.
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.
@U2FRKM4TW this is what I was trying to do. thanks for clearing it up
@U2FRKM4TW 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)
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.
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] ())])
You can use into
:
(when children
(into [:ul.tree-view-group] children))
(no need for empty lists)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>)
Don't do that - don't use positional indices as keys. React describes why not in its documentation.
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.
Thanks for the help, the when construct is really handy to know about. But I'm curious, why does it into
work here?
into
is just adding the elements into the vector
e.g. [:div "hello" "clojure" "world"]
=== (into [:div] (list "hello" "clojure" "world"))
I understand that much. I don't understand why doing that solves the error
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.
> 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.