Last active
December 30, 2015 10:09
-
-
Save swannodette/7813518 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns react-cljs.core | |
(:require-macros [reactjs.macros :refer [pure]]) | |
(:require React [reactjs.core :as r])) | |
(enable-console-print!) | |
(declare render-ui) | |
(defn render-counter [id state cb] | |
(pure state | |
(React/DOM.div nil | |
(React/DOM.label nil (:count state)) | |
(React/DOM.button | |
(js-obj "onClick" #(cb (update-in state [:count] inc))) | |
"+") | |
(React/DOM.button | |
(js-obj "onClick" #(cb (update-in state [:count] dec))) | |
"-")))) | |
(defn render-ui [n] | |
(let [state (atom (zipmap (range n) (repeat {:count 0})))] | |
((fn loop [] | |
(let [state' @state] | |
(React/renderComponent | |
(pure state' | |
(React/DOM.div nil | |
(into-array | |
(concat | |
[(React/DOM.h1 nil "A Counting Widget!")] | |
(map (fn [n] | |
(render-counter n (get state' n) | |
#(do (swap! state assoc n %) (loop)))) | |
(range n)))))) | |
js/document.body)))))) | |
(render-ui 10) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns reactjs.macros) | |
(defmacro pure [value children] | |
`(reactjs.core/Pure. (cljs.core/js-obj "value" ~value) (fn [] ~children))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns reactjs.core | |
(:require React)) | |
(def Pure | |
(React/createClass | |
(js-obj | |
"shouldComponentUpdate" | |
(fn [next-props next-state] | |
(this-as this | |
(not (= (.. this -props -value) (.-value next-props))))) | |
"render" | |
(fn [] | |
(this-as this | |
((.. this -props -children))))))) |
I finally started getting used to Angular, and now Reactjs comes along and makes me rethink best practices. Now I see that no matter what the framework du jour, always bet on Clojurescript. Good job
This plus the hiccup style templating I borrowed from pump is turning in to a knockout punch.
I'm still evaluating these macros but so far it's been very nice.
(defmacro deftemplate [name bindings & body]
`(defn ~name ~bindings
(react/html ~@body)))
(defmacro defhtmlcomponent [name bindings & body]
(let [data-sym (first bindings)]
`(defn ~name ~bindings
(pure ~data-sym (react/html ~@body)))))
Here's a basic example of how it looks in action.
(deftemplate link-to [href & content]
[:a {:href href} content])
(defhtmlcomponent SiteNavigation [links]
[:div {:id "site-navigation"}
[:ul
(for [link links]
[:li
(link-to (:href link) (:description link))])]])
(react/render-component
(SiteNavigation [{:href "/home" :description "Home"}
{:href "/about" :description "About us"}
{:href "/contact" :description "Contact us"}])
site-navigation-mount-point)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This will indeed rock the web.