Download - The Case for React.js and ClojureScript
![Page 1: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/1.jpg)
The Case for
React.js andClojureScript
Murilo Pereira
@mpereira
May 2, 2014
![Page 2: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/2.jpg)
Problem
![Page 3: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/3.jpg)
Building UIs isdifficult.
![Page 4: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/4.jpg)
Modern Web UIsvisual representations of data changing over timerespond to asynchronous user eventstransition both the underlying data and itself to new states
![Page 5: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/5.jpg)
"Data changing over time is theroot of all evil."
![Page 6: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/6.jpg)
Incidental ComplexityJavaScript isn't DOM is stateful
reactive
![Page 7: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/7.jpg)
What if the JavaScript DOMAPI was reactive?
![Page 8: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/8.jpg)
function tweetScore(tweet) { return(tweet.favorites_count + tweet.retweets_count);}
function compareTweetsByScore(a, b) { return(tweetScore(b) - tweetScore(a));}
function renderApplication(tweets) { return(document.dom.ul( { class: 'tweets' }, tweets .sort(compareTweetsByScore) .slice(0, 5) .map(function(tweet) { return(document.dom.li({ class: 'tweet' }, tweet.text); }) ));}
var tweets = fetchTweets({ username: 'mpereira' }, { limit: 20 });document.dom.render(renderApplication(tweets), document.body);
![Page 9: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/9.jpg)
Possible solution: Data binding
![Page 10: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/10.jpg)
Data BindingObservablesComputed properties
Backbone, Ember, Meteor, et al.
![Page 11: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/11.jpg)
Contemporary data binding isnot simple.
![Page 12: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/12.jpg)
SimpleNot to be mistaken for "easy"
Easiness = Familiarity (subjective)
Simplicity = "Does/is one thing" (objective)
![Page 13: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/13.jpg)
Data BindingApplication logic entangled with observablesForces us to compose our programs with frameworkconstructs instead of language constructs (functions and datastructures)
![Page 14: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/14.jpg)
"How often are you fighting theframework?"
![Page 15: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/15.jpg)
Dirty-checking (Angular)Also susceptible to the problems of data binding.
![Page 16: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/16.jpg)
https://docs.angularjs.org/guide/concepts
![Page 17: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/17.jpg)
Complex
![Page 18: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/18.jpg)
Even with shortcomings it'sstill possible to build complex,
modern UIs usingcontemporary MVC
frameworks.
![Page 19: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/19.jpg)
"We can create precisely thesame programs we're creating
right now with drasticallysimpler tools."
Rich Hickey
![Page 20: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/20.jpg)
A different solution to the sameproblem.
![Page 21: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/21.jpg)
React.js
![Page 22: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/22.jpg)
React.jsLibrary for creating UIsRenders the DOM and responds to user eventsCan be thought of as the V in MVC
![Page 23: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/23.jpg)
Remember our utopic examplea few slides back?
![Page 24: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/24.jpg)
function tweetScore(tweet) { return(tweet.favorites_count + tweet.retweets_count);}
function compareTweetsByScore(a, b) { return(tweetScore(b) - tweetScore(a));}
function renderApplication(tweets) { return(document.dom.ul( { class: 'tweets' }, tweets .sort(compareTweetsByScore) .slice(0, 5) .map(function(tweet) { return(document.dom.li({ class: 'tweet' }, tweet.text); }) ));}
var tweets = fetchTweets({ username: 'mpereira' }, { limit: 20 });document.dom.render(renderApplication(tweets), document.body);
![Page 25: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/25.jpg)
It's actually valid React.js code
![Page 26: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/26.jpg)
function tweetScore(tweet) { return(tweet.favorites_count + tweet.retweets_count);}
function compareTweetsByScore(a, b) { return(tweetScore(b) - tweetScore(a));}
function renderApplication(tweets) { return(React.DOM.ul( { className: 'tweets' }, tweets .sort(compareTweetsByScore) .slice(0, 5) .map(function(tweet) { return(React.DOM.li({ className: 'tweet' }, tweet.text); }) ));}
var tweets = fetchTweets({ username: 'mpereira' }, { limit: 20 });React.renderComponent(renderApplication(tweets), document.body);
![Page 27: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/27.jpg)
React gives us a minimallyleaky abstraction for a reactiveJavaScript/DOM environment.
![Page 28: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/28.jpg)
Data
Component
DOM
![Page 29: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/29.jpg)
Model
View
DOM
![Page 30: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/30.jpg)
M3
V2
DOM
M2 M4 M5M1
V1 V3
![Page 31: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/31.jpg)
Data
C3
DOM
C4C2 C5C1
![Page 32: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/32.jpg)
Components
![Page 33: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/33.jpg)
ComponentsIdempotent functions that describe your
UI at any point in time.
![Page 34: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/34.jpg)
component(data) = VDOM
![Page 35: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/35.jpg)
component(data_1) = VDOM_1
*user input changes data from data_1 to data_2*
component(data_2) = VDOM_2diffVDOMs(VDOM_1, VDOM_2) = diffDOMOperations(diff) = operations
applyDOMOperations(operations, document.body)
![Page 36: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/36.jpg)
Best part? You don't even haveto worry about this. Just build
components.
![Page 37: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/37.jpg)
Every place data is displayed isguaranteed to be up-to-date.
No need for KVO or markingHTML templates withframework directives.
![Page 38: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/38.jpg)
Frees the programmer fromdoing manual, explicit DOM
operations.
![Page 39: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/39.jpg)
But what about theperformance?
Isn't diffing VDOMs slow?
Why have VDOMs if thebrowser already has a DOM?
![Page 40: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/40.jpg)
The DOM is slow.
![Page 41: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/41.jpg)
The DOM is slowQuerying may require tree traversalMutations trigger viewport reflows, relayouts, repaints (CSSengine, etc.)Can also invalidate caches, requiring the entire DOM to bereconstructed on the viewport
![Page 42: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/42.jpg)
Having in-memoryrepresentations of the DOM
allows React to have extremelyfast UIs.
![Page 43: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/43.jpg)
Virtual DOM (VDOM)Allows for components to have a declarative APIPerforms the minimum amount of actual DOM operationsthrough computing diffsHandles DOM operations for you
![Page 44: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/44.jpg)
"Performance isn't the [main]goal of the VDOM, but if you'reworried with performance,
most workloads are as fast orfaster [than the MVC
alternatives] out of the box."Pete Hunt
![Page 45: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/45.jpg)
Components
![Page 46: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/46.jpg)
Components allow you toexpress your program in thelanguage of your problem
domain.
Rather than on the language ofa particular framework.
![Page 47: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/47.jpg)
Bill O'Reilly
Tide comes in, tide goes out.You can't explain that!
Top Tweets
Just had #breakfast.
@troll yes, definitely plan onthat.
pic.twitter.com/asd23 #selfie#instagram
Good# morning.
![Page 48: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/48.jpg)
Bill O'Reilly
Top Tweets
Tide comes in, tide goes out.You can't explain that! #tides
Just had #breakfast.
@troll yes, definitely plan onthat.
pic.twitter.com/asd23 #selfie#instagram
Good# morning.
Header
Profile
Tweets
Top Tweets
![Page 49: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/49.jpg)
var Profile = React.createClass({ render: function() { return(React.DOM.div(null, [ React.DOM.img(null, this.props.user.image), React.DOM.p(null, this.props.user.name) ]); }});
var Tweets = React.createClass({ render: function() { return(React.DOM.ul(null, this.props.tweets.map(function(tweet) { return(React.DOM.li(null, tweet.text)); }); }});
var TopTweets = React.createClass({ render: function() { return(React.DOM.div(null, [ React.DOM.h1(null, 'Top Tweets'), Profile({ user: this.props.user }), Tweets({ tweets: this.props.user.tweets }) ]); }});
React.renderComponent(TopTweets({ user: user }), document.body);
![Page 50: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/50.jpg)
var Profile = React.createClass({ render: function() { return( <div> <img href={this.props.user.image} /> <p>{this.props.user.name}</p> </div> ); }});
var Tweets = React.createClass({ render: function() { return( <ul> {this.props.tweets.map(function(tweet) { return(<li>tweet.text</li>); })}; </ul> ); }});
var TopTweets = React.createClass({ render: function() { return( <div> <h1>Top Tweets</h1> <Profile user={this.props.user} /> <Tweets tweets={this.props.user.tweets} /> </div> ); }
![Page 51: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/51.jpg)
TopTweets(data) = Header() + Profile(data_1) + Tweets(data_2)
![Page 52: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/52.jpg)
Components are reusable andcomposable declarative
representations of your UI.
![Page 53: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/53.jpg)
CollateralBenefits
![Page 54: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/54.jpg)
Collateral BenefitsRender the application on the server (node.js, Java 8'sNashhorn, etc.)UI testability for freeNo templates!
![Page 55: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/55.jpg)
React.js takeawaysDeclarative, fast UIsExpress your programs in the language of your problemdomain
![Page 56: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/56.jpg)
ClojureScript
![Page 57: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/57.jpg)
ProblemJavaScript sucks
We need JavaScript
![Page 58: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/58.jpg)
JavaScript sucksNo integersNo module systemVerbose syntaxConfusing, inconsistent equality operatorsConfusing, inconsistent automatic operator conversionsLack of block scopeNon-uniform iteratorsGlobal variables by defaultNaNthisNo macros (yet...)etc.
![Page 59: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/59.jpg)
We Need JavaScriptRuntime is everywhereRuntime is improving (Web Sockets, geo-location, FS API, RAF,push notifications, WebRTC, WebGL, SVG, Canvas, WebWorkers, IndexedDB, etc.)
![Page 60: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/60.jpg)
Build better languages on topof JavaScript.
![Page 61: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/61.jpg)
Compilers!Lots of them already existOnly a few bring significant improvements
Popular ones
CoffeeScript: mostly syntax sugarTypeScript: typed superset of JavaScript. Brings type checking,compile time errors
![Page 62: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/62.jpg)
ClojureScript
![Page 63: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/63.jpg)
ClojureScript is a Clojurecompiler that targets
JavaScript.
![Page 64: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/64.jpg)
Why ClojureScript?Why Clojure?Why LISP?
![Page 65: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/65.jpg)
Clojure is just a betterlanguage.
![Page 66: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/66.jpg)
Number of daysspent designingthe language v1
JavaScript Clojure
![Page 67: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/67.jpg)
ClojureScriptLISPSTMRuntime polymorphismThe REPLFunctional programmingImmutable data structuresUniform API over immutable data structuresMacrosLazy sequencesDestructuringState VS Identityetc.
![Page 68: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/68.jpg)
core.async(go (try (let [tweets (<? (get-tweets-for "swannodette")) first-url (<? (expand-url (first (parse-urls tweets)))) response (<? (http-get first-url))] (. js/console (log "Most recent link text:" response))) (catch js/Error e (. js/console (error "Error with the twitterverse:" e)))))
Asynchronous Error Handling
![Page 69: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/69.jpg)
The possibility of havingaccess to the power of Clojurein the browser is immensely
valuable.
![Page 70: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/70.jpg)
ValueTo programmers, who will be able to build better programs, with
less bugs, faster.
To the people and companies who will benefit from thoseprograms.
![Page 71: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/71.jpg)
The developer experience hasimproved significantly.
![Page 72: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/72.jpg)
Developer ExperienceSource mapsEasily reproducible tutorialsBrowser-connected in-editor REPLsFast compilation cyclesCompatible libraries
![Page 73: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/73.jpg)
Recommend you to check itout
(but you probably have, already)
![Page 74: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/74.jpg)
![Page 75: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/75.jpg)
Om
![Page 76: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/76.jpg)
ClojureScript interface to React.
![Page 77: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/77.jpg)
"Because of immutable dataOm can deliver even better
performance than React out ofthe box."
David Nolen
![Page 78: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/78.jpg)
30-40X faster than JS MVCs nothing to do with ClojureScript. Ditch stateful objects, ditch events. Be declarative. Immutability. That's it.5:39 AM - 15 Dec 2013
David Nolen @swannodette
Follow
41 RETWEETS 39 FAVORITES
![Page 79: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/79.jpg)
???
![Page 80: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/80.jpg)
ClojureScriptCompiled, slower than hand-written JavaScriptUses immutable data structures, slower than JavaScript datastructures
And yet
Om's performance beats thatof most JavaScript MVC
frameworks
![Page 81: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/81.jpg)
"Ideas have fundamentalperformance properties."
Pete Hunt
![Page 82: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/82.jpg)
Immutable data structuresmake React's diffing algorithm
really smart.
![Page 84: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/84.jpg)
Takeaways
![Page 85: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/85.jpg)
"Ideas have fundamentalperformance properties."
![Page 86: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/86.jpg)
"Don't trade simplicity forfamiliarity."
![Page 89: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/89.jpg)
Learn React.jsWhy?
Be Predictable, Not CorrectReact: Rethinking Best PracticesWhy React?
How
Getting StartedIntroduction to React.jsTutorial
![Page 90: The Case for React.js and ClojureScript](https://reader034.vdocuments.us/reader034/viewer/2022051411/53fe29858d7f72c4108b4595/html5/thumbnails/90.jpg)
Learn ClojureScriptWhy?
ClojureScript RationaleThe Future of JavaScript MVC FrameworksClojure RationaleWhy Clojure?Beating the Averages
How
ClojureScript 101Translations from JavaScriptLight Table ClojureScript TutorialOm Tutorial