enjoyable front-end development with reagent
TRANSCRIPT
![Page 1: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/1.jpg)
ENJOYABLE FRONT-END DEVELOPMENTWITHREAGENT
@TH1AGOFM
![Page 2: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/2.jpg)
@TH1AGOFM
![Page 3: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/3.jpg)
@TH1AGOFM
![Page 4: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/4.jpg)
A tale of excitement in Clojure
![Page 5: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/5.jpg)
@TH1AGOFM
~2010
1.2
![Page 6: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/6.jpg)
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.
![Page 7: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/7.jpg)
( ) @TH1AGOFM
![Page 8: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/8.jpg)
Hped
@TH1AGOFM
got hyped by node.js and completely forgot about clojure for a while
![Page 9: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/9.jpg)
@TH1AGOFM
2013
(datomic: an awesome database)
![Page 10: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/10.jpg)
Hped
@TH1AGOFM
hyped by elixir
![Page 11: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/11.jpg)
@TH1AGOFM
2014
CLJS
FINALLY!hyped by david nolen's talk about cljs and Om, but felt it was too hard, so tried reagent and enjoyed it!
![Page 12: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/12.jpg)
@TH1AGOFM
KILLER APP FOR CLOJURE
WHAT I WAS LOOKING FOR?
![Page 13: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/13.jpg)
@TH1AGOFM
ENJOYMENT. WHAT I’VE GOT INSTEAD:
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.
![Page 14: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/14.jpg)
@TH1AGOFM
![Page 15: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/15.jpg)
@TH1AGOFM
“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.
![Page 16: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/16.jpg)
@TH1AGOFM
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.
![Page 17: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/17.jpg)
Here I show a project called memcached-manager 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.
![Page 18: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/18.jpg)
@TH1AGOFM
WHY REACT?
REACT SOLVES THIS PROBLEM BY USING SOMETHING CALLED VIRTUAL DOM.
![Page 19: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/19.jpg)
@TH1AGOFM
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.
![Page 20: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/20.jpg)
@TH1AGOFM
REACT ONLY TAKES CARE ABOUT THE V OF THE MVC. IT’S JUST A LIBRARY.
![Page 21: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/21.jpg)
@TH1AGOFM
SO, IT MAKES SENSE TO USE IT WITH SOMETHING ELSE…
![Page 22: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/22.jpg)
@TH1AGOFM
clojure(script) has a lot of power to create powerful dsl’s
react has a declarative way to do frontend development, is very fast but have too much boilerplate.
REAGENTreagent explores this nice spot with both
![Page 23: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/23.jpg)
@TH1AGOFM
IF YOU KNOW CLOJURE, YOU KNOW REAGENT. (AND CLOJURESCRIPT)
![Page 24: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/24.jpg)
@TH1AGOFM
IF YOU DON’T, IT’S A GOOD PLAYGROUND TO BEGIN.
![Page 25: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/25.jpg)
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.
![Page 26: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/26.jpg)
FIGWHEEL, THE CLJS BROWSER REPL.
figwheel does:cljs -> jsgives you a browser REPL
![Page 27: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/27.jpg)
Here there’s a video where you see that you can interact with the frontend you build through this REPL
![Page 28: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/28.jpg)
@TH1AGOFM
THE 2048 GAME WAS MADE USING THE REAGENT-TEMPLATE.
(VERY EASY TO SET UP!)
![Page 29: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/29.jpg)
@TH1AGOFM
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-over255 [: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]261 (game-explanation-component)262 [:hr]263 (footer-component)])272 (tile-component)]))
COMPONENTS
Components looks like HTML with some clojure. Syntax is hiccup style.
Pretty simple.
![Page 30: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/30.jpg)
@TH1AGOFM
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 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
html, for real
![Page 31: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/31.jpg)
@TH1AGOFM
TILES COMPONENT
215 (defn tile-component []216 [:div {:class "tile-container"}217 (remove nil? (map-indexed218 (fn[y row-of-tiles]219 (map-indexed220 (fn[x tile]221 (when (> tile 0)222 [:div {:class (str 223 "tile tile-" tile " tile-position-224 " (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]])
how does the game display the tiles
![Page 32: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/32.jpg)
@TH1AGOFM
ROUTING
263 (footer-component)])264 265 ;; -------------------------266 ;; Pages267 268 (defn start-game-page []269 (application-layout270 [:div271 (grid-component)272 (tile-component)]))273 274 (defn current-page []275 [:div [(session/get :current-page)]])276 277 ;; -------------------------278 ;; Routes279 (secretary/set-config! :prefix "#")280 (secretary/defroute "/" []281 (session/put! :current-page #'start-game-page)282 )283 284 ;; -------------------------285 ;; History286 ;; must be called after routes have been 287 defined288 (defn hook-browser-navigation! []289 (doto (History.)290 (events/listen
whenever you access /, it calls start-game-page function.
game uses only this page, so this is straightforward.
![Page 33: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/33.jpg)
@TH1AGOFM
OK, THIS LOOKS PRETTY STATIC. HOW DO I CHANGE A COMPONENT STATE?
![Page 34: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/34.jpg)
@TH1AGOFM(SOMETHING THAT HOLDS STATE)
![Page 35: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/35.jpg)
@TH1AGOFM
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-over255 [: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]261 (game-explanation-component)262 [:hr]263 (footer-component)])272 (tile-component)]))
ATOMS
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.
![Page 36: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/36.jpg)
@TH1AGOFM
(R)ATOMS
11 12 ;; ------------------------- 13 ;; Definitions 14 15 (def empty-tiles 16 [[0 0 0 0] 17 [0 0 0 0] 18 [0 0 0 0] 19 [0 0 0 0]]) 20 (def no-score-addition 21 0)
31 32 ;; ------------------------- 33 ;; Atoms 34 35 (defonce score (atom 0)) 36 (defonce score-addition (atom 0)) 37 (defonce tiles (atom empty-tiles))
38 (defonce game-over (atom false)) 39
![Page 37: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/37.jpg)
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)
![Page 38: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/38.jpg)
@TH1AGOFM
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.
![Page 39: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/39.jpg)
@TH1AGOFM
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);
we don’t need that boilerplate, just use reagent :)
![Page 40: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/40.jpg)
@TH1AGOFM
IS MAGIC
![Page 41: Enjoyable Front-end Development with Reagent](https://reader033.vdocuments.us/reader033/viewer/2022051707/58ee559f1a28ab7e228b4697/html5/thumbnails/41.jpg)
@TH1AGOFM
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, [email protected]
thanks!