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
820
WordPress: To OOP or not to OOP
nb
4
8.1k
On Creeds and Manifestos
nb
2
230
Welcome to the Chaos – The Distributed Workplace
nb
3
240
To a thousand servers and beyond: scaling a massive PHP application
nb
3
1.5k
Взимане на продуктови решения (Making product decisions)
nb
0
170
Other Decks in Programming
See All in Programming
Google Apps Script で Ruby を動かす
kawahara
0
220
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
400
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.9k
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.8k
メールのエイリアス機能を履き違えない
isshinfunada
0
240
OpenSpecのproposalにbrainstormingを持たせてみた
tigertora7571
1
220
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
210
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
180
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
0
1.8k
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
500
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
110
進化を続けるGo toolsの現在地 / The Current State of Ever-Evolving Go Tools
hond0413
0
210
Featured
See All Featured
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
390
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.8k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
380
Skip the Path - Find Your Career Trail
mkilby
1
180
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
320
The agentic SEO stack - context over prompts
schlessera
0
860
How to build a perfect <img>
jonoalderson
1
5.9k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.2k
Embracing the Ebb and Flow
colly
88
5.1k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
400
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