Jochen Bedersdorfer
Software Engineer
A short overview
Pass in as properties
Have a DOM-like component tree structure and pass in data from the root
Side-load data
Components actively or reactively get data from a global service
Local state
Keep some data, like the open/close status of a popup inside component
Data
React
React
Reagent
(defn hello-world []
[:h1 {:color :green} "Hello World"])
(defn ^:export run []
(rdom/render [hello-world] (js/document.getElementById "app")))
Sidebar Hiccup:
;;; tag opt: properties & children
[:h1 {:style {:color :black}} [:span "Something else"]]
;; ==> <h1 style="{color: 'black';}" <span>Something else</span></h1>
;;; with classes
[:h1.header.main "Meh"]
;;; reagent turns functions into react classes
(defn hello-world [name] [:span (str "Hi " name)])
[hello-world "folks"]
Reagent
Simple example:
(defonce time-color (r/atom "#f34"))
(defn color-input []
[:div.color-input
"Time color: "
[:input {:type "text"
:value @time-color
:on-change #(reset! time-color (-> % .-target .-value))}]])
Re-frame
Re-frame
Elements of a re-frame app:
;;; event handlers - two flavors
(rf/reg-event-db
::evt.setup
(fn [db _] (assoc db :setup true)))
(rf/reg-event-fx
::evt.setup
(fn [{:keys [db]} _]))
;;; Subscriptions - three flavors (also reg-sub-raw)
(rf/reg-sub
::sub.setup-names
(fn [db _] (:setup-names db)))
(rf/reg-sub
::sub.setup-names-url
:<- [::sub.setup-names]
(fn [names]
(str (-> js/location .-origin) "/?p=" (some-> names (js/encodeURIComponent names)))))
(rf/reg-sub
::sub.setup-names-url
(fn [_ _] (rf/subscribe [::sub.setup-names]))
(fn [names]
(str (-> js/location .-origin) "/?p=" (some-> names (js/encodeURIComponent names)))))
Re-frame
Elements of a re-frame app:
;;; use (rf/subscribe subs-vector) to create a reaction that reagent tracks
;;; i.e. if the data underlying ::sub.current-person changes, reagent will ask react to re-render current-person
(defn current-person []
[:center [:h2 (or @(rf/subscribe [::sub.current-person]) "Done!")]])
;;; use (rf/dispatch event-vector) to dispatch an event
(defn action-bar []
[:div
(if @(rf/subscribe [::sub.has-next?])
[:button {:on-click #(rf/dispatch [::evt.next!])} "Next!"]
[:button.secondary {:on-click #(rf/dispatch [::evt.load-persons])} "Restart!"])])
Re-frame
By Jochen Bedersdorfer