'

Enjoyable Front-end Development with Reagent

Понравилась презентация – покажи это...





Слайд 0

ENJOYABLE FRONT-END DEVELOPMENT WITH REAGENT @TH1AGOFM


Слайд 1

@TH1AGOFM


Слайд 2

@TH1AGOFM


Слайд 3

A tale of excitement in Clojure


Слайд 4

~2010 1.2 @TH1AGOFM


Слайд 5

1 (defn factorial 2 ([n] 3 (factorial n 1)) 4 ([n acc] 5 (if (= n 0) acc 6 (recur (dec n) (* acc n))))) got inspired by the beauty of a factorial implementation.


Слайд 6

() @TH1AGOFM


Слайд 7

Hped got hyped by node.js and completely forgot about clojure for a while @TH1AGOFM


Слайд 8

2013 (datomic: an awesome database) @TH1AGOFM


Слайд 9

Hped hyped by elixir @TH1AGOFM


Слайд 10

2014 CLJS hyped by david nolen's talk about cljs and Om, but felt it was too hard, so tried reagent and enjoyed it! FINALLY! @TH1AGOFM


Слайд 11

WHAT I WAS LOOKING FOR? KILLER APP FOR CLOJURE @TH1AGOFM


Слайд 12

WHAT I’VE GOT INSTEAD: ENJOYMENT. Reagent(or Om) have to mature way more to be a killer app, for this we need a nice community around it. But it’s very enjoyable to work with. @TH1AGOFM


Слайд 13

@TH1AGOFM


Слайд 14

“You believe that, by early 2015, ReactJS had won the JavaScript framework wars and you are curious about the bigger implications. Is the combination of reactive programming, functional programming and immutable data going to completely change everything? And, if so, what would that look like in a language that embraces those paradigms?” — Re-frame (Reagent framework for writing SPAs) So, in this bold statement by re-frame you can guess react.js is a great thing. @TH1AGOFM


Слайд 15

WHY REACT? PROBLEM: DOM WASN’T CREATED TO CREATE UI’S THAT ARE TOO DYNAMIC. MOVING 1000 DIVS AROUND TAKES A LOT OF TIME. SOLUTION: INSTEAD OF MOVING ALL THOSE 1000 DIVS, ONE BY ONE, WE CAN COMPUTE THE NEW STATE AND REPLACE IT ALL WITH THIS NEW STATE WITH THE SMALLEST AMOUNT OF PERMUTATIONS. 1 BIG INSERT VS. 1000 SMALL INSERTS. @TH1AGOFM


Слайд 16

Here I show a project called memcachedmanager in angular.js(very old version) that I do create trying to render 1000 divs/ memcached keys and completely freezing the browser for a couple of seconds. This is the problem that React tries to solve.


Слайд 17

WHY REACT? REACT SOLVES THIS PROBLEM BY USING SOMETHING CALLED VIRTUAL DOM. @TH1AGOFM


Слайд 18

THE ANATOMY OF A REACT COMPONENT 1 React.createClass({ 2 getInitialState: function() { 3 return {secondsElapsed: 0}; 4 }, 5 tick: function() { 6 this.setState({secondsElapsed: this.state. 7 secondsElapsed + 1}); 8 }, 9 componentDidMount: function() { 10 this.interval = setInterval(this.tick, 1000) 11 ; 12 }, 13 componentWillUnmount: function() { 14 clearInterval(this.interval); 15 }, 16 render: function() { 17 return ( 18 <div>Seconds Elapsed: {this.state. 19 secondsElapsed}< 20 /div> 21 ); 22 } 23 }); 24 25 React.render(<Timer />, mountNode); DECLARATIVE, BUT TONS OF BOILERPLATE. @TH1AGOFM


Слайд 19

REACT ONLY TAKES CARE ABOUT THE V OF THE MVC. IT’S JUST A LIBRARY. @TH1AGOFM


Слайд 20

SO, IT MAKES SENSE TO USE IT WITH SOMETHING ELSE… @TH1AGOFM


Слайд 21

REAGENT clojure(script) has a lot of power to create powerful dsl’s reagent explores this nice spot with both react has a declarative way to do frontend development, is very fast but have too much boilerplate. @TH1AGOFM


Слайд 22

IF YOU KNOW CLOJURE, YOU KNOW REAGENT. (AND CLOJURESCRIPT) @TH1AGOFM


Слайд 23

IF YOU DON’T, IT’S A GOOD PLAYGROUND TO BEGIN. @TH1AGOFM


Слайд 24

Here I show a demo of a project I wrote specially for this talk, the demo link is in the last slides, you can see for yourself.


Слайд 25

FIGWHEEL, THE CLJS BROWSER REPL. figwheel does: cljs -> js gives you a browser REPL


Слайд 26

Here there’s a video where you see that you can interact with the frontend you build through this REPL


Слайд 27

THE 2048 GAME WAS MADE USING THE REAGENT-TEMPLATE. (VERY EASY TO SET UP!) @TH1AGOFM


Слайд 28

COMPONENTS 
 
 
 247 (defn application-layout [rest] 248 [:div {:class "container"} 249 (heading-component) 250 [:p {:class "game-intro"} "Join the numbers 251 and get to the " 252 [:strong "2048 tile!"]] 253 [:div {:class "game-container"} 254 (when @game-over 255 [:div {:class "game-message game-over"} 256 [:p "Game over!" ] 257 [:div {:class "lower"} 258 [:a {:class "retry-button" :href "/"} 259 "Try again"]]]) 260 rest] Components looks like HTML with some clojure. Syntax is hiccup style. 261 (game-explanation-component) Pretty simple. 262 [:hr] 263 (footer-component)]) 272 (tile-component)]))
 @TH1AGOFM


Слайд 29


 
 
 COMPONENTS 224 225 (defn game-explanation-component [] 226 [:p {:class "game-explanation"} 227 [:strong {:class "important"} "How to play:"] 228 " Use your " 229 [:strong "arrow keys"] " to move the tiles. 230 When two tiles with the same number touch, 231 they " 232 [:strong "merge into one!"]]) 233 234 (defn footer-component [] 235 [:p "\n Created by " 236 [:a {:href "http://gabrielecirulli.com", : 237 target "_blank"} "Gabriele Cirulli."] " 238 Based on " 239 [:a {:href "https://itunes.apple. 240 com/us/app/1024!/id823499224", :target html, for real 241 "_blank"} "1024 by Veewo Studio"] " and 242 conceptually similar to " 243 [:a {:href "http://asherv.com/threes/", : 244 target "_blank"} "Threes by Asher 245 Vollmer."]]) 246 
 @TH1AGOFM


Слайд 30


 
 
 
 TILES COMPONENT 
 
 
 215 (defn tile-component [] 216 [:div {:class "tile-container"} 217 (remove nil? (map-indexed how does the game display the tiles 218 (fn[y row-of-tiles] 219 (map-indexed 220 (fn[x tile] 221 (when (> tile 0) 222 [:div {:class (str 223 "tile tile-" tile " tile-position224 " (inc x) "-" (inc y))} tile])) 225 row-of-tiles)) 226 @tiles))])
 15 (def empty-tiles 
 16 [[0 0 0 0] 
 17 [0 0 0 0] 
 18 [0 0 0 0] 
 19 [0 0 0 0]]) 
 
 @TH1AGOFM 
 



Слайд 31

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 (footer-component)]) ;; ------------------------;; Pages (defn start-game-page [] (application-layout [:div (grid-component) (tile-component)])) ROUTING (defn current-page [] [:div [(session/get :current-page)]]) ;; ------------------------;; Routes (secretary/set-config! :prefix "#") (secretary/defroute "/" [] (session/put! :current-page #'start-game-page) ) ;; ------------------------;; History ;; must be called after routes have been defined (defn hook-browser-navigation! [] (doto (History.) (events/listen whenever you access /, it calls startgame-page function. game uses only this page, so this is straightforward. @TH1AGOFM


Слайд 32

OK, THIS LOOKS PRETTY STATIC. HOW DO I CHANGE A COMPONENT STATE? @TH1AGOFM


Слайд 33

(SOMETHING THAT HOLDS STATE) @TH1AGOFM


Слайд 34

ATOMS 247 (defn application-layout [rest] 248 [:div {:class "container"} 249 (heading-component) 250 [:p {:class "game-intro"} "Join the numbers 251 and get to the " 252 [:strong "2048 tile!"]] 253 [:div {:class "game-container"} 254 
 255 256 257 258 259 260 261 262 263 272 (when @game-over [:div {:class "game-message game-over"} [:p "Game over!" ] [:div {:class "lower"} [:a {:class "retry-button" :href "/"} "Try again"]]]) rest] (game-explanation-component) [:hr] (footer-component)]) (tile-component)]))
 game-over is a atom/state, and using the @ means we are reading it’s content. This is called derefing in clojure whenever game-over = true, it would show what is nested inside it. a view telling the game is over with the option to retry. @TH1AGOFM 
 



Слайд 35

11 12 13 14 15 16 17 18 19 20 21 31 32 33 34 35 36 37 ;; ------------------------;; Definitions (def empty-tiles [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]) (def no-score-addition 0) (R)ATOMS ;; ------------------------;; Atoms (defonce score (atom 0)) (defonce score-addition (atom 0)) (defonce tiles (atom empty-tiles)) 38 (defonce game-over (atom false)) 39 
 
 
 
 @TH1AGOFM 
 



Слайд 36

here I play with the atoms of the game, seeing it update in the browser(right side). reagent atoms behave exactly as clojure atoms so you can call swap! and reset! on them, for more info about that, read the docs from the reagent project provided in the last slide. (pst: it’s easy)


Слайд 37

COMPONENTS + ATOMS = ALL YOU NEED. not much secret to write the game beyond that, check the readme of my version of the game in github how I build it having subpar clojure skills and learned some stuff in the way. @TH1AGOFM


Слайд 38

1 React.createClass({ 2 3 4 5 6 7 8 9 10 11 12 13 14 15 getInitialState: function() { return {secondsElapsed: 0}; }, tick: function() { this.setState({secondsElapsed: this.state. secondsElapsed + 1}); }, componentDidMount: function() { this.interval = setInterval(this.tick, 1000) ; }, componentWillUnmount: function() { clearInterval(this.interval); }, render 16 : function() { 17 return ( 18 <div>Seconds Elapsed: {this.state. 19 secondsElapsed}< 20 /div> 21 ); 22 } 23 }); 24 25 React.render(<Timer />, mountNode); we don’t need that boilerplate, just use reagent :) @TH1AGOFM


Слайд 39

IS MAGIC @TH1AGOFM


Слайд 40

THAT’S ALL FOLKS! READ THE GUIDE: http://reagent-project.github.io USE THE TEMPLATE: https://github.com/reagent-project/reagent-template CHECK THE COOKBOOKS: https://github.com/reagent-project/reagent-cookbook MAKE YOUR OWN 2048: https://github.com/thiagofm/reagent-2048 && HAVE FUN! shoot me an e-mail if you play with it and have some kind of trouble, thiagown@gmail.com thanks! @TH1AGOFM


Слайд 41


×

HTML:





Ссылка: