在 clojurescript 中,如何评估列表
In clojurescript, how to evaluate a list
假设有
(def defining-list `(def one 1))
如何评估 defining-list 以便 one 变为 1 ?
(在 clojurescript 中)
编辑:
我将给出一个更广泛的概念,以及我在这里试图完成的事情,以避免陷入 X/y 问题。
我正在尝试使用 cljsjs 包中的 cljsjs/material-ui
而不是每次都定义一个反应组件来使用它,如下所示:
(def app-bar
(r/adapt-react-class (aget js/MaterialUI (name :AppBar)))
我想定义标签数组中的所有组件:
(def material-ui-tags '[AppBar Avatar Backdrop])
所以我在想是否可以在不使用宏的情况下做到这一点,因为我发现 this
类似于:
(doseq [component material-ui-tags]
`(def ~(symbol (->kebab-case component)) (r/adapt-react-class (aget js/MaterialUI ~(name component)))))
但是上面只创建了一个 defs 列表,我想评估这些。在 clojure 中,eval 可以解决问题。
使用试剂,您可以将 :>
用作 shorthand 用于 adapt-react-class
,如 https://github.com/reagent-project/reagent/blob/master/docs/InteropWithReact.md
中所述
此外,您可以将点符号与 js/
一起使用,我认为在 1.9.854 以上的 shadow-cljs 或 cljs 中,您可以 require
导入符号而不是使用 aget
.
在你的情况下,它会是这样的:
(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"]])
要使用 def 做您想做的事,您需要 eval 或 macro。正如 Jared Smith 在评论中解释的那样,Eval 并不理想。
您从 reagent-material-ui 链接的示例使用了宏。调用宏实际上执行扩展然后评估。所以你的代码需要是这样的:
clj 文件
(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 文件
(adapt-components) ;; your defs will be available below this line
(defn my-component []
[app-bar ...])
假设有
(def defining-list `(def one 1))
如何评估 defining-list 以便 one 变为 1 ? (在 clojurescript 中)
编辑: 我将给出一个更广泛的概念,以及我在这里试图完成的事情,以避免陷入 X/y 问题。
我正在尝试使用 cljsjs 包中的 cljsjs/material-ui 而不是每次都定义一个反应组件来使用它,如下所示:
(def app-bar
(r/adapt-react-class (aget js/MaterialUI (name :AppBar)))
我想定义标签数组中的所有组件:
(def material-ui-tags '[AppBar Avatar Backdrop])
所以我在想是否可以在不使用宏的情况下做到这一点,因为我发现 this
类似于:
(doseq [component material-ui-tags]
`(def ~(symbol (->kebab-case component)) (r/adapt-react-class (aget js/MaterialUI ~(name component)))))
但是上面只创建了一个 defs 列表,我想评估这些。在 clojure 中,eval 可以解决问题。
使用试剂,您可以将 :>
用作 shorthand 用于 adapt-react-class
,如 https://github.com/reagent-project/reagent/blob/master/docs/InteropWithReact.md
此外,您可以将点符号与 js/
一起使用,我认为在 1.9.854 以上的 shadow-cljs 或 cljs 中,您可以 require
导入符号而不是使用 aget
.
在你的情况下,它会是这样的:
(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"]])
要使用 def 做您想做的事,您需要 eval 或 macro。正如 Jared Smith 在评论中解释的那样,Eval 并不理想。
您从 reagent-material-ui 链接的示例使用了宏。调用宏实际上执行扩展然后评估。所以你的代码需要是这样的:
clj 文件
(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 文件
(adapt-components) ;; your defs will be available below this line
(defn my-component []
[app-bar ...])