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
Nguyễn Nhật Hoàng
September 28, 2016
Technology
380
0
Share
Awesome React
Open Discussion about Modern Web Design, Solution Forum, FSOFT HCM 28/09/2016
Nguyễn Nhật Hoàng
September 28, 2016
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
Claude Code で使える DuckDB Skills を試してみた / DuckDB Skills and Claude Code
masahirokawahara
1
2k
DI コンテナ自動生成ツールを実装してみた / intro-autodi
uhzz
0
770
Oracle AI Database@AWS:サービス概要のご紹介
oracle4engineer
PRO
4
2.6k
JaSSTに関わることで変わった人生観 #jasstnano
makky_tyuyan
0
170
AWSアップデートから考える継続的な運用改善
toru_kubota
2
330
Claude Code / Codex / Kiro に AWS 権限を 渡すとき、何を設計すべきか
k_adachi_01
6
1.9k
はじめてのAI-DLC
yoshidashingo
1
320
AI飲み会幹事エージェントを作っただけなのに
ykimi
0
250
TypeScript の型で副作用の実行順序を制御する
yanaemon
1
140
20260516_SecJAWS_Days
takuyay0ne
2
550
The Making of AI Chips
pfn
PRO
0
630
ECSのTerraformモジュールにコントリビュートした話
harukasakihara
0
280
Featured
See All Featured
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
340
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
Speed Design
sergeychernyshev
33
1.7k
The Cost Of JavaScript in 2023
addyosmani
55
9.9k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
180
Believing is Seeing
oripsolob
1
130
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
We Have a Design System, Now What?
morganepeng
55
8.1k
The browser strikes back
jonoalderson
0
1.1k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
1
80
Chasing Engaging Ingredients in Design
codingconduct
0
190
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