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

ClojureScript and WebSockets and React (Oh, My!)

ClojureScript and WebSockets and React (Oh, My!)

We'll look at a few technologies I used to create a software estimation application:
• Reagent, an interface between ClojureScript and React, a JavaScript library for building user interfaces.
• Sente, a library that uses WebSockets to maintain an interactive communication session between a browser and server.

After this talk, you'll be able to:
• Explain how WebSockets work, and how they're different from a polling approach to client/server communication
• Understand at a high level how React and Reagent work
• Get started with Reagent on your own ClojureScript projects

Avatar for Michael Stalker

Michael Stalker

January 26, 2017
Tweet

More Decks by Michael Stalker

Other Decks in Technology

Transcript

  1. PLANNING POKER® ♠️ ♥️ ♣️ ♦️ PLANNING POKER ® is

    a registered trademark of Mountain Goat Software, LLC Sequence of values is (C) Mountain Goat Software, LLC
  2. 3 8

  3. 8 3

  4. (ns planning-poker.message-handler (:require [taoensso.sente :as sente] [planning-poker.notifier :as notifier] [planning-poker.game-table

    :as table])) (defonce players (atom {})) (defmulti message-handler :id) (defmethod message-handler :table/player-joined [{:keys [?data ring-req]}] (table/add-player! players (user-id ring-req) ?data) (notifier/notify-players-updated @connected-uids @players chsk-send!)) (defmethod message-handler :table/player-estimated [{:keys [?data ring-req]}] (table/estimate! players (user-id ring-req) ?data) (notifier/notify-players-estimated @connected-uids @players chsk-send!)) (sente/start-chsk-router! ch-chsk message-handler)
  5. CLOJURESCRIPT • Immutable data structures and locals • Protocols •

    Google’s Closure compiler • Namespaces • Macros
  6. HOW REAGENT WORKS (defn simple-component [] [:div [:p "I am

    a component!"] [:p.someclass "I have ” [:strong "bold"] [:span {:style {:color "red"}} " and red "] "text."]])
  7. HOW REAGENT WORKS (defn simple-component [] [:div [:p "I am

    a component!"] [:p.someclass "I have ” [:strong "bold"] [:span {:style {:color "red"}} " and red "] "text."]]) I am a component! I have bold and red text.
  8. COMPONENTS CAN RENDER COMPONENTS (defn simple-parent [] [:div [:p "I

    use simple-component."] [simple-component]])
  9. COMPONENTS CAN RENDER COMPONENTS (defn simple-parent [] [:div [:p "I

    use simple-component."] [simple-component]]) I use simple-component. I am a component! I have bold and red text.
  10. STATE (def click-count (r/atom 0)) (defn counting-component [] [:div "The

    atom " [:code "click-count"] " has value: ” @click-count ". ” [:input {:type "button" :value "Click me!” :on-click #(swap! click-count inc)}]])
  11. (ns planning-poker.client.game-table (:require [planning-poker.client.cards :as cards] [planning-poker.client.login :as login] [planning-poker.client.players

    :as table-players])) (defn component [players channel] [:div [login/component channel] [:div.game-table [:h1.game-table-heading "Remote Planning Poker"] [cards/component channel] [table-players/component players] [:button.reset "Play a New Round"]]])
  12. (ns planning-poker.client.cards (:require planning-poker.client.extensions)) (def cards ["?" 0 1 2

    3 5 8 13 20]) (defn component [channel] [:ol.cards (doall (for [card cards] ^{:key card} [:li [:button.card card]]))])
  13. (ns planning-poker.client.players (:require [planning-poker.client.player :as player])) (defn component [players] [:div.players

    [:h2 "Players"] [:div.names [:ul (for [[player-id player] @players] ^{:key player-id} [player/component player])]]])
  14. (ns planning-poker.client.login) (defn component [channel] (fn [] [:form.login [:fieldset [:p

    "Remote Planning Poker"] [:input {:name "player-name" :placeholder "Your Name" :auto-focus true}] [:button "Start Playing"]]])))
  15. (ns planning-poker.client.cards (:require [reagent.core :as r])) (def cards ["?" 0

    1 2 3 5 8 13 20]) (defonce active-card (r/atom nil)) ;; Activate card atom and notify server that player estimated (defn select-card [card channel] ...) (defn component [channel] [:ol.cards (doall (for [card cards] ^{:key card} [:li [:button.card {:on-click (select-card card channel) :class (if (active? card) "active" "")} card]]))])
  16. (ns planning-poker.client.players (:require [planning-poker.client.player :as player])) (defn component [players] [:div.players

    [:h2 "Players"] [:div.names [:ul (for [[player-id player] @players] ^{:key player-id} [player/component player])]]])
  17. (ns planning-poker.client.player) (defn component [player] [:li.player [:span.name (:name player)] [:span.estimate

    {:class (cond (:show-estimate? player) :estimate-show (:estimate player) :estimate-hide :else :estimate-waiting)} (when (:show-estimate? player) (:estimate player))]])
  18. (ns planning-poker.client.game-table (:require-macros [cljs.core.async.macros :refer [go]]) (:require [cljs.core.async :refer [>!]]))

    (defn- start-new-round [channel] (fn [event] (go (>! channel [:table/new-round-requested])))) (defn component [players channel] [:div [login/component channel] [:div.game-table [:h1.game-table-heading "Remote Planning Poker"] [cards/component channel] [table-players/component players] [:button.reset {:on-click (start-new-round channel)} "Play a New Round"]]])
  19. IMAGE ATTRIBUTIONS • https://commons.wikimedia.org/wiki/File:Portrait_of_Plato;_bust._Wellcome_M0005618.jpg This file is licensed under the

    Creative Commons Attribution 4.0 International license. https://creativecommons.org/licenses/by/4.0/deed.en This file comes fromWellcome Images, a website operated by WellcomeTrust, a global charitable foundation based in the United Kingdom. Refer to Wellcome blog post (archive). No changes were made, except possibly cropping • https://commons.wikimedia.org/wiki/File:Nineteenth_century_bathtub_grayscale.jpg This file is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license. https://creativecommons.org/licenses/by-sa/3.0/deed.en Doug Coldwell No changes were made, except possibly cropping
  20. IMAGES WITH NO COPYRIGHT • https://commons.wikimedia.org/wiki/File:Tage_Erlander_1960-tal.jpg • https://commons.wikimedia.org/wiki/File:Dismantling_a_Bathtub_in_the_White_House-02-10-1950.jpg • https://en.wikipedia.org/wiki/Candlestick_telephone#/media/File:Genevieve-Clark-Bain.jpeg

    • https://commons.wikimedia.org/wiki/File:JolsonTelephone.jpg • https://commons.wikimedia.org/wiki/File:Apollo_8_Borman_takes_phone_call_from_LBJ.jpg • https://commons.wikimedia.org/wiki/File:Don_Knotts_Jim_Nabors_Andy_Griffith_Show_1964.JPG • https://commons.wikimedia.org/wiki/File:Joseph_Kearns_Jay_North_Billy_Booth_Herbert_Anderson_D ennis_the_Menace_1962.JPG