ClojureScript, Reagent, re-frame
Smyrna: a search tool for collections of texts in Polish
2011: first version
(backend: Clojure, frontend: Backbone + CoffeeScript)
2016: new backend,
frontend fully rewritten in
ClojureScript + Reagent + re-frame
(func arg1 arg2 arg3)
func
with arguments arg1
, arg2
, arg3
(js/console.log "Hello from ClojureScript")
[42 100 :cljs "WarsawJS"]
{:first 1, :second 2}
(defn hello []
[:div
[:h1 "Hello, WarsawJS!"]])
(defn coloured-hello [col]
[:div
[:h1 {:style (str "color: " col)}]
"Hello!"]])
(defn rainbow-hellos []
[:div
(for [col ["red" "orange" "yellow" "green"
"blue" "indigo" "violet"]]
[coloured-hello col])])
A stateful container for a value
(def foo (atom 42))
;=> #<atom 42>
(swap! foo + 10)
;=> nil
(deref foo) ;; or @foo
;=> 52
A variant of Atom that re-renders all components deref
ing it when the value changes
(def count (reagent.core/atom 0))
(defn counter []
[:div
"Count:" @count
[:input {:type "button" :value "Click!"
:on-click #(swap! count inc)}]])
(defn counter []
(let [count (reagent.core/atom 0)]
(fn []
[:div
"Count:" @count
[:input {:type "button" :value "Click!"
:on-click #(swap! count inc)}]])
It’s MVC, Jim, but not as we know it.
RACES (Reactive-Atom Component Event Subscription) framework
Derived Data All The Way Down!
re-frame is to Reagent what Redux is to React.
(def initial-state {:count 0})
(register-handler :initialize
(fn [empty-state event]
initial-state))
(register-handler :bump
(fn [state event]
(update-in state [:count] inc)))
(register-sub :current-count
(fn [state params]
(reaction (:count state))))
(defn counter []
(let [count (subscribe [:current-count])]
(fn []
"Count:" @count
[:button {:on-click #(dispatch [:bump])}
"Click!"]]))
shouldComponentUpdate