目前的 ClojureScript React 绑定都是比较复杂的, 比如 Reagent, 做了不少的修改,我打算看看直接用 cljs 裸写, 按照 React 本身的语义, 会是什么样子,网上搜到几个版本的代码, 总之核心代码就是这样了(defn my-component [props context updater] (cljs.core/this-as this (js/React.Component.call this props context updater) ;; anything else you want to set-up. use goog.object/set on this this))(gobj/extend (.. my-component -prototype) js/React.Component.prototype)https://gist.github.com/peste…https://gist.github.com/peste...https://gist.github.com/thhel…最关键的部分就是定义一个子类继承 React.Component , 然后增加 render 方法, 参考:https://developer.mozilla.org…// Rectangle - subclassfunction Rectangle() { Shape.call(this); // call super constructor.}// subclass extends superclassRectangle.prototype = Object.create(Shape.prototype);Rectangle.prototype.constructor = Rectangle;最终得到的一个版本是这样,(def comp-input-area (let [Child (fn [props context updater] (this-as this (.call React/Component this props context updater) (set! (.-state this) (clj->js {:draft “initial thing”})) this))] (set! (.-prototype Child) (.create js/Object (.-prototype React/Component))) (set! (.. Child -prototype -constructor) React/Component) (set! (.. Child -prototype -render) (fn [] (this-as this (div {} (input {:value (^js .-draft (^js .-state this)), :onChange (fn [event] (.setState this (clj->js {:draft (.. event -target -value)})))}) (^js .-draft (^js .-state this)))))) Child))注意用 this-as 这个 macro 来声明 this, 这个在 cljs 是不能随便用的,https://stackoverflow.com/a/2…不过这个 macro 有坑, 我用 let 的时候, this 被绑定到 window 上去了,cljs 编译生成的代码存在一些问题, 感觉 this 怎么说其实还是很成问题的完整代码涉及到更多的 InterOp 用法, 不专门写了.大概的意思就是需要转很多类型, 在上面的例子当中也看到了.这样一来, 通过 macro 之类的手段在语法上做改进, 很难了.另外看到 JavaScript 有个 reify https://github.com/clojure/cl…按说可以简化语法, 而且在 Om 代码有到看类似的用法, 不管比较复杂.直接跟上面的例子对比, 初始化 state 的地方不好写.总之不好完全按照 React 的语义直接封装了.当日内 Hooks 出来有带来一些改变, 不是很确定能搞成什么样, 社区也在探索中.https://github.com/Lokeh/hook…
...