Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ClojureScript + React.js: How I learned to stop worrying and love the browser.

ClojureScript + React.js: How I learned to stop worrying and love the browser.

Over the last few years, there has been a stronger emphasis on functional programming languages and constructs in mainstream programming. The rise of FP popularity is not due to concurrency (although still valid), but the recognition that minimizing side-effects yields to smaller code that is easier to test and reason about. ClojureScript finally brings that perspective to the front-end world.

This talk is an introduction to a different kind of front-end development. Together, we will explore how ClojureScript helps accelerate front-end development and how to avoid the most common pitfalls; a molotov cocktail of information and pizazz to put you on the fast-track towards web development nirvana.

ClojureScriptHero.com is coming soon! In the meantime, you can learn more about ClojureScript by subscribing to the newsletter: http://bit.ly/cljs-hero

Norbert Wójtowicz

March 15, 2015
Tweet

More Decks by Norbert Wójtowicz

Other Decks in Programming

Transcript

  1. LISP Programmers know the cost of everything and the value

    of nothing. Alan Perlis Programmers Experience
  2. MV*

  3. your code react.js [{:tweet “At @wroc_love.rb”}] [:ul [:li [:span “At

    @wroc_love.rb”]]] <ul> <li><span>At @wroc_love.rb</span></li> </ul>
  4. your code react.js [{:tweet “At @wroc_love.rb”} {:tweet “It’s awesome!”}] [:ul

    [:li [:span “At @wroc_love.rb”]] [:li [:span “It’s awesome!”]]] <ul> <li><span>At @wroc_love.rb</span></li> <li><span>It’s awesome!</span></li> </ul>
  5. • Lisp • STM • Runtime polymorphism • REPL •

    Functional programming • Macros • Namespaces • Protocols • Interop with JVM • Transducers • Immutable datastructures • Uniform API over immutable datastructures • Lazy sequences • Destructuring • State vs Identity • core.async • core.logic • core.typed • And more! Clojure
  6. • Lisp • STM • Runtime polymorphism • REPL •

    Functional programming • Macros • Namespaces • Protocols • Interop with Javascript • Transducers • Immutable datastructures • Uniform API over immutable datastructures • Lazy sequences • Destructuring • State vs Identity • core.async • core.logic • core.typed • And more! ClojureScript
  7. <!doctype html> <html> <head> <title>My App</title> <link rel=“stylesheet" href="css/main.css"> </head>

    <body> <div id="app"></div> <script src="main.js"></script> </body> </html> html/index.html
  8. (ns hello.core (:require [rum :as r])) (def post {:text “First

    Post" :author "Jane"}) (r/defc render-post [{:keys [:text :author]}] [:blockquote text [:cite author]]) (r/mount (render-post post) (.getElementById js/document "app")) src/hello/core.cljs
  9. (set-env! :source-paths #{"src"} :resource-paths #{"html"} :dependencies '[[org.clojure/clojure "1.7.0-alpha5" :scope "provided"]

    [org.clojure/clojurescript "0.0-2985" :scope "provided"] [rum "0.2.6"] [adzerk/boot-cljs "0.0-2814-3" :scope "test"] [cljsjs/boot-cljsjs "0.4.6" :scope "test"] [adzerk/boot-cljs-repl "0.1.9" :scope "test"] [adzerk/boot-reload "0.2.6" :scope "test"] [pandeiro/boot-http "0.6.3-SNAPSHOT" :scope "test"]]) (require '[adzerk.boot-cljs :refer [cljs]] '[cljsjs.boot-cljsjs :refer [from-cljsjs]] '[adzerk.boot-cljs-repl :refer [cljs-repl start-repl]] '[adzerk.boot-reload :refer [reload]] '[pandeiro.boot-http :refer [serve]]) build.boot
  10. (deftask dev "Start the dev env..." [] (comp (watch) (serve

    :dir "target" :port 3000) (cljs-repl) (from-cljsjs :profile :development) (cljs :unified true :source-map true :optimizations :none)) (reload))) build.boot
  11. cljs.user=> (+ 1 "2") WARNING: cljs.core/+, all arguments must be

    numbers, got [number string] instead. at line 1 <cljs repl> "12" cljs.user=> (js/alert "hello!") Auto-Reload via Websockets Browser REPL and
  12. (def todo (atom {:title “Hello”}})) (rum/defc item < reactive [state]

    [:span (:title (rum/react state))]) (rum/mount (item todo) element) (swap! todo assoc :title “Hello”) (swap! todo assoc :title “Goodbye”)
  13. (rum/defc search-box < reactive [] (let [val (atom "I'm looking

    for...")] [:div [:input {:type “text" :value (:value (rum/react val)) :on-change #(reset! val (-> % .-target .-value))}] [:input {:type “button" :value "Search!" :on-click #(search-tweets world (rum/react val))}]]))
  14. (def state (atom {:app {:settings {:color "red"}} :text "Hello"})) (rum/defc

    label < rum/cursored [color text] [:.label {:style {:color @color}} @text]) (rum/defc body < rum/cursored [state] [:div (label (rum/cursor state [:app :settings :color]) (rum/cursor state [:text]))])
  15. (d/q '[ :find ?k ?x :in [[?k [?min ?max]] ...]

    ?range :where [(?range ?min ?max) [?x ...]] [(even? ?x)] ] { :a [1 7], :b [2 4] } range)
  16. (go (while true (<! (timeout 250)) (>! c 1))) (go

    (while true (<! (timeout 1000)) (>! c 2))) (go (while true (<! (timeout 2000)) (>! c 3))) (go (loop [q []] (set-html! out (render q)) (recur (-> (conj q (<! c)) (peekn 10))))
  17. (let [c (chan) t (timeout 1000)] (go (>! c (<!

    web query))) (go (>! c (<! image query))) (go (>! c (<! video query))) (go (>! c (<! local-storage query))) (alt! [c t] ([v] v)))