Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Awesome React
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Nguyễn Nhật Hoàng
September 28, 2016
Technology
0
380
Awesome React
Open Discussion about Modern Web Design, Solution Forum, FSOFT HCM 28/09/2016
Nguyễn Nhật Hoàng
September 28, 2016
Tweet
Share
More Decks by Nguyễn Nhật Hoàng
See All by Nguyễn Nhật Hoàng
JS Promise the right way
codeaholicguy
0
230
Other Decks in Technology
See All in Technology
Context Engineeringが企業で不可欠になる理由
hirosatogamo
PRO
3
410
小さく始めるBCP ― 多プロダクト環境で始める最初の一歩
kekke_n
1
350
GitLab Duo Agent Platform × AGENTS.md で実現するSpec-Driven Development / GitLab Duo Agent Platform × AGENTS.md
n11sh1
0
120
顧客の言葉を、そのまま信じない勇気
yamatai1212
1
340
Meshy Proプラン課金した
henjin0
0
250
IaaS/SaaS管理における SREの実践 - SRE Kaigi 2026
bbqallstars
4
1.7k
Amazon S3 Vectorsを使って資格勉強用AIエージェントを構築してみた
usanchuu
3
430
SREのプラクティスを用いた3領域同時 マネジメントへの挑戦 〜SRE・情シス・セキュリティを統合した チーム運営術〜
coconala_engineer
2
590
Bill One急成長の舞台裏 開発組織が直面した失敗と教訓
sansantech
PRO
1
290
AzureでのIaC - Bicep? Terraform? それ早く言ってよ会議
torumakabe
1
350
学生・新卒・ジュニアから目指すSRE
hiroyaonoe
2
550
あたらしい上流工程の形。 0日導入からはじめるAI駆動PM
kumaiu
5
760
Featured
See All Featured
Building Applications with DynamoDB
mza
96
6.9k
Git: the NoSQL Database
bkeepers
PRO
432
66k
Tell your own story through comics
letsgokoyo
1
800
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
64
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
120
Technical Leadership for Architectural Decision Making
baasie
1
240
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
450
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.8k
Optimizing for Happiness
mojombo
379
71k
Prompt Engineering for Job Search
mfonobong
0
160
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Transcript
Awesome React Nguyen Nhat Hoang @codeaholicguy
Before we begin: Not a tutorial.
Before we begin: Design decisions, not implementations.
Meet React A library for creating user interfaces.
Meet React Render your UI and responds to events.
Meet React V in MVC
What makes user interfaces difficult to build?
What makes user interfaces difficult to build? Human verified
What makes user interfaces difficult to build? Lot of states
What makes user interfaces difficult to build? Tooling mismatch
Lot of complexity
How to solve that problems?
Trying to be predictable.
Trying to be reliable.
How do we make user interfaces more reliable?
UI is a dynamic process
None
Galaxy Note4 is online
iPhone 5 is online
Galaxy S5 is offline
iPhone 5 is favorited
iPhone 5 is utilizing
?
It is very difficult for human to visualize dynamic processes
that evolve over time!
[{ "name": "Galaxy S5", "isOnline": true, "isUltilizing": false, "isFavorite": true
}, { "name": "Galaxy Note4", "isOnline": false, "isUltilizing": false, "isFavorite": true }, { "name": "iPhone 5", "isOnline": true, "isUltilizing": true, "isFavorite": false }]
Data binding!
Data binding makes UI look more like a static program
relative to your data model.
Data binding sync state in your UI with state in
your data model.
Is it simple?
Simplicity is prerequisite for reliability.
Simplicity is that there is no interleaving.
familiar things == simple things?
Key-Value Observation Ember, Knockout, Backbone etc
Observables & Computed Properties
[{ "title": "Awesome React", "upvotes": 90, "downvotes": 5 }, {
"title": "Progessive Web App", "upvotes": 112, "downvotes": 11 }, { "title": "Modern Web Technologies", "upvotes": 20, "downvotes": 8 }]
None
<script type="text/x-handlebars"> {{outlet}} </script> <script type="text/x-handlebars" data-template-name="index"> <ul> {{#each topTopics}}
<li>{{title}} {{percent}}%</li> {{/each}} </ul> </script>
function totalVotes(topic) { return topic.upvotes + topic.downvotes; } var Topic
= Ember.Object.extend({ percent: function() { return (this.upvotes * 100 / totalVotes(this)).toFixed(2); }.property('upvotes', 'downvotes') }); var AppModel = Ember.Object.extend({ topTopics: function() { return this.topics.sort(function(a, b) { return totalVotes(a) - totalVotes(b); }).slice(0, 3) }.property('topics') }); var appModel = AppModel.create({ topics: topics.map(function(topic) { return Topic.create(topic) }) })
function totalVotes(topic) { return topic.upvotes + topic.downvotes; } var Topic
= Ember.Object.extend({ percent: function() { return (this.upvotes * 100 / totalVotes(this)).toFixed(2); }.property('upvotes', 'downvotes') }); var AppModel = Ember.Object.extend({ topTopics: function() { return this.topics.sort(function(a, b) { return totalVotes(a) - totalVotes(b); }).slice(0, 3) }.property('topics') }); var appModel = AppModel.create({ topics: topics.map(function(topic) { return Topic.create(topic) }) })
function totalVotes(topic) { return topic.upvotes + topic.downvotes; } var Topic
= Ember.Object.extend({ percent: function() { return (this.upvotes * 100 / totalVotes(this)).toFixed(2); }.property('upvotes', 'downvotes') }); var AppModel = Ember.Object.extend({ topTopics: function() { return this.topics.sort(function(a, b) { return totalVotes(a) - totalVotes(b); }).slice(0, 3) }.property(‘
[email protected]
’, ‘
[email protected]
’) }); var appModel = AppModel.create({ topics: topics.map(function(topic) { return Topic.create(topic) }) })
Demo https://goo.gl/eXszlj
Dirty Checking Angular
None
<div ng-app="app"> <div ng-controller="AvatarController"> <fb-avatar user="user"></fb-avatar> </div> </div>
var app = angular.module('app',[]); app.controller('AvatarController', function($scope) { $scope.user = {
username: 'codeaholicguy', fbid: '632571376813536', fullName: ‘Hoàng Nguyễn' } }); app.directive('fbAvatar', function() { return { restrict: 'E', scope: {user: '='}, template: '<div class="fbAvatar"><fb-pic user="user"></fb- pic>{{user.fullName}}</div>' } }) app.directive('fbPic', function() { return { restrict: 'E', scope: {user: '='}, template: '<img src="http://graph.facebook.com/{{user.fbid}}/ picture"></img>' } })
var app = angular.module('app',[]); app.controller('AvatarController', function($scope) { $scope.user = {
username: 'codeaholicguy', fbid: '632571376813536', fullName: ‘Hoàng Nguyễn' } }); app.directive('fbAvatar', function() { return { restrict: 'E', scope: {user: '='}, template: '<div class="fbAvatar"><fb-pic user="user"></fb- pic>{{user.fullName}}</div>' } }) app.directive('fbPic', function() { return { restrict: 'E', scope: {user: '='}, template: '<img src="http://graph.facebook.com/{{user.fbid}}/ picture"></img>' } })
Demo https://goo.gl/iGuVrq
What if we had a “reactive” JavaScript?
Re-rendering on every change makes things simple.
function totalVotes(topic) { return topic.upvotes + topic.downvotes; } function renderApp(topics)
{ return DOM.ul({className: 'list'}, topics.sort(function(a, b) { return totalVotes(a) - totalVotes(b); }) .slice(0, 3) .map(function(topic) { return DOM.li({className: 'item'}, topic.title, ' ', (topic.upvotes * 100 / totalVotes(this)).toFixed(2), '%' ); }) ); } var topics = getTopics(); render(renderApp(topics), document.body);
function totalVotes(topic) { return topic.upvotes + topic.downvotes; } function renderTopic(topic)
{ return DOM.li({className: 'item'}, topic.title, ' ', (topic.upvotes * 100 / totalVotes(this)).toFixed(2), '%' ); } function renderApp(topics) { return DOM.ul({className: 'list'}, topics.sort(function(a, b) { return totalVotes(a) - totalVotes(b); }) .slice(0, 3) .map(renderTopic) ); } var topic = getTopics(); render(renderApp(topic), document.body);
But
JavaScript is not reactive.
DOM is stateful!
You can’t just throw out the DOM and rebuild it
on each update.
It’s EXPENSIVE!
Virtual DOM
Virtual DOM Whenever anything may have changed, re-render everything to
a virtual DOM representation.
Virtual DOM Diff the previous representation with the next one.
Virtual DOM Only update the real DOM part which actually
changed.
None
Every system has constrains.
KVO entangles app code with observables.
Angular-style dirty checking forces everything through $scope, $watch and directives.
Data binding systems with domain specific language are not statically
analyzable. Linting - Minification - Type checking
Virtual DOM needs a signal to say anything may have
changed.
Most expressive way to build an user interface in JavaScript.
Let’s see some React fundamentals
Build components, not templates
Separate of concerns Reduce coupling, increase cohesion
Templates separate technologies, not concerns
Use components to separate your concerns. Full power of JavaScript,
no template language
Components are reusable.
Components are composable.
Components are unit testable.
render() { return ( <p>Hello {this.props.world}</p> ) }
JSX is an optional preprocessor to let you use HTML-like
syntax.
render() { return ( React.DOM.p({}, 'Hello', this.props.world) ) }
One way data flow
Props and State
Data handed from parent to child
Events flow up, data flows down
Virtual DOM is fast!
DOM is slow!
Computes minimal DOM operations
Batched reads and writes for optimal DOM performance
Automatic top-level event delegation (with cross- browser HMTL5 event)
Provides hooks for custom update logic shouldComponentUpdate, forceUpdate
It can run in Node.js
Moreover
Easy to test
SVG, canvas support
Key take aways
Components, not templates
Re-render, don’t mutate
Virtual DOM is simple, powerful and fast
Thank you Nguyen Nhat Hoang @codeaholicguy