front-end god mode with reagent and figwheel
TRANSCRIPT
Front-enD God-modE w / ReagenT AnD FigwheeL
DaviD Y. KaY
State of Front-end Dev
State of the Art• Write Code
• Reload Browser
• Lose Application State
• Manipulate Application State
• Test/verify behavior
• Repeat
Goal for this Talk
• How to develop code interactively
• Minimal incidental complexity
• Be the coolest kid on the block
Demo
• Show what Pharmasoft / Chat App Looks Like
• Show a one-line change
• Show the recursive nature of components
The Armory
Clojurescript Figwheel Reagent
Why Clojurescript?
Clojurescript
• More sane than JS• Functional• S-expressions• Code is data
(defn square [x] (* x x))
function square(x){ return x*x; }
Why Figwheel?
Figwheel3 Steps:
• Edit
• Save
• Watch in Awe
Bret Victor - Inventing on Principle
Figwheel
• Pro:
• Code changes occur instantly
• App state is maintained
• Con:
• Have to write code so that it’s reloadable
Code Changes
Figwheel Server (Lein figwheel)
CLJS App
Figwheel Client
Why Reagent?
Reagent
• a minimal, sleek React.js
• SIMPLE
• Dataflow!
• Likened more to Elm than React.js
Atoms(defonce app-state (r/atom {:chat-input "" :messages [] :username "Anon"}))
(swap! app-state assoc :username "David")
(reset! app-state new-state)
Adjust with Feedback
• Show some mis-steps, correct them
Review
• Clojurescript
• Figwheel
• Reagent
Come for the workshop!
ReagenT AnD FigwheeL WorkshoP
Installing the Tools
brew install leiningen
Running the Code
Terminal 1:
lein ring server
Terminal 2:
lein figwheel
Part 0: Prologue
Set the Goal
• By the end of this workshop, you should be able to create a chat client using CLJS, Foundation, Reagent, and Figwheel
• Here’s what it looks like…
Demo
• Show what Chat App Looks Like
Roadmap• Clojurescript
• Data structures
• Functions
• Figwheel
• Reagent
• Atoms
• Components
• Putting it all together - Chat App
Part 1: Intro
Figwheel
• Pro:
• Code changes occur instantly
• App state is maintained
• Con:
• Have to write code so that it’s reloadable
Hello World
lein new figwheel chat
cd chat
lein figwheel
view localhost:3449
Clojurescript
(defn square [x] (* x x))
Data Structures
List - ( )
Vector - [ ]
Map - { }
Set - #{ }
(def app-db {:greeting "Hello Van FP!" :email “[email protected]" :password "" :screen :login})
(if (= id (:current-condition @app-state)) "current" "")
(fn [n] (clojure.string/join
" " "tabs-title"
(if (= n (:active-tab @app-state)) "is-active" nil)]))
Part 2: Basics
Reagent
Hiccup Syntax
[:div.top-bar-right [:ul.menu [:li [:a {:href "#"} "History"]] [:li [:a {:href "#"} "Log Out"]]]]
Button Handler
[:button {:class "button" :on-click
#(do (refresh-messages) (.preventDefault %))} "Refresh"]
Button Handler
[:button {:class "button" :on-click
(fn [ev] (refresh-messages) (.preventDefault ev))} "Refresh"]
Button Handler
(defn handle-click [ev] (refresh-messages) (.preventDefault ev))
[:button {:class "button" :on-click handle-click} "Refresh"]
Atoms(defonce app-state (r/atom {:chat-input "" :messages [] :username "Anon"}))
(swap! app-state assoc :username "David")
(reset! app-state new-state)
Atoms(swap! app-state assoc :username “David")
(swap! app-state (fn [old] (assoc old :username “david”))
(reset! app-state new-state)
Text Input
[:input {:placeholder "Neo", :type "text" :value (:username @app-state) :on-change (fn [ev] (swap! app-state assoc :username (-> ev .-target .-value)))}]
Text Input
(-> ev .-target .-value)
(:value (:target ev))
(.-value (.-target ev))
Part 3: Intermediate
HTTP Calls
(GET "/" {:handler (fn [response] (println response)) :error-handler error-handler})
(defn error-handler [{:keys [status status-text]}] (println "error code: " status " " status-text))
Reagent Component
(defn component [medication] [:div [:h2 "Pre-Interview Notes"] [:p (:general-notes @app-state)] [:form ...]])
Review• Figwheel
• Reloadable code
• Clojurescript
• Reagent
• Ratoms
• Components
Resources
• Figwheel Talk at Clojure/West 2015
• Reagent Docs - holmsand.github.io/reagent/
ExtrA ImageS