简体   繁体   中英

In clojurescript, how to evaluate a list

Suppose having

(def defining-list `(def one 1))

How can I evaluate defining-list so that one becomes 1 ? (in clojurescript)

EDIT: I will give an idea of the broader image and what I am trying to accomplish here to avoid falling into an X/y problem.

I am trying to use cljsjs/material-ui from cljsjs package Instead of defining each time a react component to use it as following:

(def app-bar 
  (r/adapt-react-class (aget js/MaterialUI (name :AppBar)))

I would like to define all the components from an array of tags:

(def material-ui-tags '[AppBar Avatar Backdrop])

So I was thinking if it's possible to do this without the usage of a macro as I found this

Something like:

(doseq [component material-ui-tags]
  `(def ~(symbol (->kebab-case component)) (r/adapt-react-class (aget js/MaterialUI ~(name component)))))

But the above does only create a list of defs, I would like to evaluate these. In clojure eval would do the trick.

With reagent, you can use :> as shorthand for adapt-react-class as documented in https://github.com/reagent-project/reagent/blob/master/docs/InteropWithReact.md

Also, you can use dot notation with js/ and I think in shadow-cljs or cljs above 1.9.854 you can require to import the symbol instead of using aget .

In your case, it would be something like:

(ns example.core
  (:require [MaterialUI]))

(defn component-two []
  [:> MaterialUI/AppBar {:some-prop "some-value"}
    [:div "children-here"]])

(defn component-two []
  ;; If the require above doesn't work
  [:> js/MaterialUI.AppBar {:some-prop "some-value"}
    [:div "children-here"]])

To do what you wanted using def, you either need eval or macro. Eval is not ideal as Jared Smith explained in the comment.

The example that you linked from reagent-material-ui uses macro. Invoking a macro actually performs expansion and then evaluation. So your code needs to be something like this:

clj file

(def material-ui-tags '[AppBar Avatar Backdrop])

(defmacro adapt-components []
  (for [component material-ui-tags]
    `(def ~(symbol (->kebab-case component)) (reagent.core/adapt-react-class (aget js/MaterialUI ~(name component))))))

cljs file

(adapt-components) ;; your defs will be available below this line

(defn my-component []
  [app-bar ...])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM