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
React.js for WordPress Developers
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Nikolay Bachiyski
April 16, 2016
Programming
300
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React.js for WordPress Developers
Nikolay Bachiyski
April 16, 2016
More Decks by Nikolay Bachiyski
See All by Nikolay Bachiyski
Building Calypso-like Applications
nb
3
870
Else Considered Harmful
nb
2
1.1k
On Learning
nb
2
830
WordPress: To OOP or not to OOP
nb
4
8.2k
On Creeds and Manifestos
nb
2
240
Welcome to the Chaos – The Distributed Workplace
nb
3
240
To a thousand servers and beyond: scaling a massive PHP application
nb
3
1.6k
Взимане на продуктови решения (Making product decisions)
nb
0
170
Other Decks in Programming
See All in Programming
tsc.rip を支える技術 / Kyoto.なんか #8
susisu
0
4.1k
夏だ!祭りだ!祭りとはドメインモデリングでは?
ryugen04
0
500
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
7
2.3k
Cloudflare is Agents
chimame
0
190
typoなんかねぇよ
raspython3
0
640
[DroidKaigi 26] How We Moved from Android Studio to Slack
thisaay
0
140
AIと壁打ちしながら進めるコスト管理
fufuhu
2
1.9k
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.8k
Discordを用いたラボオートメーション関連情報収集の自動化
noguhiro2002
0
480
Dockerfile CMD for Node.js
grazie1999
0
160
{ Android | Kotlin } Gradle Plugin in 2026
ryunen344
1
160
ALB ログから Trace を気合で繋げる技術
fohte
7
840
Featured
See All Featured
sira's awesome portfolio website redesign presentation
elsirapls
0
370
YesSQL, Process and Tooling at Scale
rocio
174
15k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
490
So, you think you're a good person
axbom
PRO
2
2.1k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
640
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.1k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Large-scale JavaScript Application Architecture
addyosmani
515
110k
We Have a Design System, Now What?
morganepeng
55
8.3k
Ruling the World: When Life Gets Gamed
codingconduct
0
310
Designing Powerful Visuals for Engaging Learning
tmiket
1
520
Transcript
N I KO L AY B A C H I
Y S K I , A U TO M AT T I C , W O R D C A M P H E L S I N K I , A P R I L 1 6 , 2 0 1 6
None
A U TO M AT T I C
A U TO M AT T I C E X
T R A P O L AT E . M E
A U TO M AT T I C E X
T R A P O L AT E . M E @ N I KO L AY B
R E S T A P I
R E S T A P I CALYPSO
R E S T A P I ↓ S I
N G L E - PA G E A P P S
W H Y ?
None
FA S T E R
None
M O R E E N G A G I
N G
None
None
C H A N G E L E T '
S TA L K A B O U T
None
None
None
None
None
None
S TAT E L E T ' S TA L
K A B O U T
None
None
None
C L A S S I C V S .
S I N G L E - PA G E A P P S
C L A S S I C
None
None
C H A N G E 㱺 R E F
R E S H C L A S S I C
C H A N G E 㱺 S I N
G L E - PA G E
C H A N G E 㱺 S I N
G L E - PA G E
None
None
U I L I B R A RY
N OT A F R A M E W O
R K
U I L I B R A RY
const Post = React.createClass( { render() { return ( <div
className="post"> <p className="content"> { this.props.post.content } </p> <PostMeta post={ this.props.post } /> </div> ); } } );
const Post = React.createClass( { render() { return ( <div
className="post"> <p className="content"> { this.props.post.content } </p> <PostMeta post={ this.props.post } /> </div> ); } } );
const Post = React.createClass( { render() { return ( <div
className="post"> <p className="content"> { this.props.post.content } </p> <PostMeta post={ this.props.post } /> </div> ); } } ); J SX
const Post = React.createClass( { function render() { return (
React.DOM.div( {className: 'post'}, [ React.DOM.p( null, this.props.post.content ), PostMeta( {post: this.props.post} ) ); ); } } );
const Post = React.createClass( { render() { return ( <div
className="post"> <p className="content"> { this.props.post.content } </p> <PostMeta post={ this.props.post } /> </div> ); } } );
const PostMeta = React.createClass( { … } );
const Post = React.createClass( { render() { return ( <div
className="post"> <p className="content"> { this.props.post.content } </p> <PostMeta post={ this.props.post } /> </div> ); } } );
const PostMeta = React.createClass( { getInitialState() { return { hidden:
true }; }, onToggle() { this.setState( { hidden: ! this.state.hidden } ); }, render() { return ( <div className="meta"> { this.props.post.author } <button onClick={ this.onToggle }> { this.state.hidden ? 'More' : 'Hide' } </button> ( this.state.hidden ? <p>…extra meta…</p> : null ) </div> ); } } );
const PostMeta = React.createClass( { getInitialState() { return { hidden:
true }; }, onToggle() { this.setState( { hidden: ! this.state.hidden } ); }, render() { return ( <div className="meta"> { this.props.post.author } <button onClick={ this.onToggle }> { this.state.hidden ? 'More' : 'Hide' } </button> ( this.state.hidden ? <p>…extra meta…</p> : null ) </div> ); } } );
const PostMeta = React.createClass( { getInitialState() { return { hidden:
true }; }, onToggle() { this.setState( { hidden: ! this.state.hidden } ); }, render() { return ( <div className="meta"> { this.props.post.author } <button onClick={ this.onToggle }> { this.state.hidden ? 'More' : 'Hide' } </button> ( this.state.hidden ? <p>…extra meta…</p> : null ) </div> ); } } );
const PostMeta = React.createClass( { getInitialState() { return { hidden:
true }; }, onToggle() { this.setState( { hidden: ! this.state.hidden } ); }, render() { return ( <div className="meta"> { this.props.post.author } <button onClick={ this.onToggle }> { this.state.hidden ? 'More' : 'Hide' } </button> ( this.state.hidden ? <p>…extra meta…</p> : null ) </div> ); } } );
const PostMeta = React.createClass( { getInitialState() { return { hidden:
true }; }, onToggle() { this.setState( { hidden: ! this.state.hidden } ); }, render() { return ( <div className="meta"> { this.props.post.author } <button onClick={ this.onToggle }> { this.state.hidden ? 'More' : 'Hide' } </button> ( this.state.hidden ? <p>…extra meta…</p> : null ) </div> ); } } ); R E - R E N D E RS
C O M P O N E N T S
L E T ' S TA L K A B I T M O R E A B O U T
C O M P O S A B L E
<MasterBar> <UserGreeting user="…"> <Avatar login={ this.props.user.login } /> Howdy, {
this.props.user.nickname } <LogOutLink id={ this.props.user.id } /> </UserGreeting> </MasterBar>
B U I L D I N G B LO
C KS O F O U R A P P L I C AT I O N
<MasterBar /> <MastHead /> <Navigation active="archive" /> <Posts date="2015-04-01" author="crumb">
<Post> … </Post> <Post> … </Post> … </Posts>
const Post = React.createClass( { … <p class="content"> { this.props.post.content}
</p> <PostMeta post="…" /> …
None
T E S TA B L E
P R E V E N T S XS S
<p>{ this.props.content }</p> <img src="javascript:alert('XSS');"> <img src="javascript:alert('XSS');">
<p dangerouslySetInnerHTML={{ __html: this.props.content }} />
N OT T E M P L AT E S
<div class="posts"> {{#each posts}} <div class="post"> {{#if author}} </div> {{/each}}
{{^posts}} Not Found {{/posts}} </div>
R E U S A B L E
<Comment> <Avatar email={ this.props.comment.author.email } /> … </Comment>
<PostMeta> <Avatar email={ this.props.comment.author.email} /> … </PostMeta>
AV ATA R = I M G + H O
V E R J S
W A I T!
K E E P LO G I C A N
D M A R K U P … A P O P U L A R B E S T P R A C T I C E S A Y S …
… S E PA R AT E !
S E PA R AT I O N O F
C O N C E R N S I S G O O D, R I G H T ?
W H E N D O W E N E
E D A N E V E N T H A N D L E R W I T H O U T T H E D O M E L E M E N T I T I S B O U N D TO ?
W H E N D O W E N E
E D A N E V E N T H A N D L E R W I T H O U T T H E D O M E L E M E N T I T I S B O U N D TO ? onClick() <button>
W H E N D O W E N E
E D A D O M E L E M E N T W I T H O U T T H E E V E N T H A N D L E R S F O R I T S A C T I O N S ? onClick() <button>
H TM L
D I S P L AY LO G I C
T H E S A M E C O N
C E R N
H TM L J S
H TM L
D I S P L AY LO G I C
T H E S A M E C O N
C E R N
None
None
None
R E - R E N D E R I
N G
None
None
None
None
V I R T U A L D O M
0 . R U N r e n d e
r ( ) O N E V E RY U P D A T E
1 . D I F F W I T H
P R E V I O U S T R E E O N E V E RY U P D A T E
http://calendar.perfplanet.com/2013/diff/
2 . CO M P U T E M I
N I M U M S E T O F D O M C H A N G E S O N E V E RY U P D A T E
3 . B ATC H - E X E C
U T E A L L D O M U P D AT E S O N E V E RY U P D A T E
V I R T U A L D O M
: N OT O N LY S P E E D!
S E R V E R-S I D E R
E N D E R I N G
S V G , V M L , C A
N V A S
R U N N I N G I N A
W E B W O R K E R
D E C L A R AT I V E
None
None
sample
M A G I C!
None
render() { return ( <div className="meta"> { this.props.post.author } <button
onClick={ this.onToggle }> { this.state.hidden ? 'More' : 'Hide' } </button> ( this.state.hidden ? <p>…extra meta…</p> : null ) </div> ); }
render() { return ( <div className="meta"> { this.props.post.author } <button
onClick={ this.onToggle }> { this.state.hidden ? 'More' : 'Hide' } </button> ( this.state.hidden ? <p>…extra meta…</p> : null ) </div> ); }
None
None
RO U T E R + S TAT E http://redux.js.org
https://github.com/reactjs/react-router https://egghead.io
N OT A F R A M E W O
R K
A RC H I T E C T U R
E
http:/ /github.com/Automattic/wp-calypso
L E T ' S C H AT
S U M M A RY
C O M P O N E N T S
, N OT T E M P L AT E S
R E - R E N D E R ,
D O N ' T TO U C H T H E D O M
V I R T U A L D O M
I S S I M P L E , FA S T, F U N L E T ' S TA L K A B O U T
C O N T R I B U TO R
D AY!
Q U E S T I O N S ?
@ N I KO L AY B