reagent

A minimalistic ClojureScript interface to React.js http://reagent-project.github.io/
John Oerter 2020-08-05T03:03:00.127400Z

The reagent docs have this code example:

(defn lister [items]
  [:ul
   (for [item items]
     ^{:key item} [:li "Item " item])])
Can anyone explain the ^{:key item} part to me? I know that it is adding the key attribute for a list in React, but I don't quite understand the Clojure/Reagent syntax part of how this is working

John Oerter 2020-08-05T13:46:50.132300Z

Ah that makes sense. Thanks @lilactown and @noisesmith

2020-08-09T11:37:21.153900Z

Ah nice I always just passed it into the props

2020-08-09T11:37:43.154100Z

Any reason to prefer setting the meta data instead?

lilactown 2020-08-09T17:05:30.156900Z

Not for html elements like :li. If you’re using a component you’ve defined, then you might not have a place to set those props. E.g. [some-component foo bar] In this case there’s no props map to pass a key to, so you’ll want to use metadata

2020-08-10T15:06:38.162900Z

ah right makes sense thanks

John Oerter 2020-08-05T03:15:26.127500Z

It seems like this is Reagent metadata?

lilactown 2020-08-05T03:23:51.128300Z

It’s syntax for adding metadata to the vector being constructed

lilactown 2020-08-05T03:24:15.129200Z

Reagent checks a few places for keys when converting a vector into a React element

lilactown 2020-08-05T03:24:36.130Z

One is props , so you could just pass in the key like any other prop

lilactown 2020-08-05T03:24:45.130400Z

Another is metadata on the vector

2020-08-05T03:44:49.130600Z

to be clear, ^{:foo bar} is vanilla clojure, and puts a metadata map onto a collection or symbol, but reagent has a special interpretation of specific metadata keys

1
2020-08-05T03:45:45.130800Z

^:foo is often seen, it translates to ^{:foo true}

2020-08-05T03:46:43.131Z

you can combine them

ins)cljs.user=> (def m ^:foo ^{:bar false} {})
#'cljs.user/m
(ins)cljs.user=> m
{}
(ins)cljs.user=> (meta m)
{:bar false, :foo true}

EmmanuelOga 2020-08-05T06:08:12.131300Z

yeah I feel some of the docs are just outdated, thing is, when learning, it is hard to determine which thing is wrong

yenda 2020-08-05T08:04:00.131500Z

I want to use functional components by default because I use hooks a lot

yenda 2020-08-05T08:05:38.131700Z

The problem is that I use react-navigation and the screens need to be react components, so my root component needs to be reactified, it's a reagent component, then it uses navigators and screens from react-navigation that take react components as params

yenda 2020-08-05T08:06:44.131900Z

(defmacro defscreen
  [name component]
  `(def ~name
     (reagent.core/reactify-component
      (fn []
        @app.navigation/cnt
        [(fn []
           ~component)])
      app.navigation/functional-compiler)))

(defmacro defroutes
  [name navigator-creation-fn navigator]
  (let [screen-class (gensym "screen-class")
        navigator-class (gensym "navigator-class")]
    `(def ~name
       (let [[~navigator-class ~screen-class] (~navigator-creation-fn)]
         (reagent.core/reactify-component
          (fn []
            (~navigator ~navigator-class ~screen-class))
          app.navigation/functional-compiler)))))

jsn 2020-08-05T09:10:38.132100Z

Well, my guess would be that that specific one at least is not just outdated, it seems just plain wrong (as in: I have doubts Reagent ever behaved that way).

John Oerter 2020-08-05T13:46:50.132300Z

Ah that makes sense. Thanks @lilactown and @noisesmith

EmmanuelOga 2020-08-05T23:47:15.132700Z

right, I meant, maybe it was correct at some point, otherwise it would not had been written (I want to think) haha

EmmanuelOga 2020-08-05T23:47:48.132900Z

would be awesome to have some sort of build for the docs: if you use a piece of code as an example, should be extracted from a test suite or something

EmmanuelOga 2020-08-05T23:48:04.133100Z

maybe once I learn the thing I should try doing something like that 🙂

jsn 2020-08-05T23:51:17.133300Z

cf. https://github.com/seancorfield/readme

1👍