Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Add Superpowers to your React components using ...
Search
Siddharth Kshetrapal
January 14, 2017
Technology
390
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Add Superpowers to your React components using ES7 decorators
Siddharth Kshetrapal
January 14, 2017
More Decks by Siddharth Kshetrapal
See All by Siddharth Kshetrapal
We need to talk about our frontend workflow
siddharthkp
1
280
Advanced Component Patterns
siddharthkp
0
130
The life of CSS and it's future
siddharthkp
1
260
Building real time data heavy interfaces for SaaS
siddharthkp
1
230
A portal to the future
siddharthkp
7
2.9k
Do you even jam bruh?
siddharthkp
1
200
Designing in React
siddharthkp
0
240
ES2015 on production? Not so fast
siddharthkp
1
380
Building node modules
siddharthkp
2
540
Other Decks in Technology
See All in Technology
いちAWSエンジニアのAI活用を振り返る #devio2026 / devio osaka 2026 kawahara
masahirokawahara
1
290
生成AIを使って「人が」考える技術 ― AI時代の人機共想と実践ノウハウ|UNITT AC2026
ishiirikie
0
450
AI感のないAWS構成図をAIエージェントに描かせたい!
sagochiko
2
480
AIエージェント時代のPlatform as a Product —— テックリードがPdMとして回す発見・導入・計測 / Platform as a Product in the AI Agent Era
toshi0607
1
530
PQC移行の今 -- IETF からみた現在地
satokan
4
690
地方移住と都心キャリアの両立は「金・時間・人」のリソースをフル活用すれば実現できる!〜Snowflake女子会 vol.8
snowwmn0824
0
140
なぜAI任せのゲームは面白くならないのか?
hirohasuyoutube
0
330
AWS DevOps Agent スキルをつかいこなそう / Master AWS DevOps Agent Skills
kinunori
2
640
顧客の成果創出とプロダクトの成長を 両立するためのFDE
sansantech
PRO
0
510
セルフサービスのオブザーバビリティ基盤をOpenTelemetryで作る / Building a Self-Service Observability Platform with OpenTelemetry
ymotongpoo
3
480
LT:「このままでいいのかな?」から一歩踏み出した私のデータキャリア選択〜社会人3年目に上京を決意したリアル〜Snowflake女子会 vol.8
snowwmn0824
0
120
カンファレンスに参加した後の浮遊感とセルフケア
pauli
0
250
Featured
See All Featured
The Cult of Friendly URLs
andyhume
79
7k
More Than Pixels: Becoming A User Experience Designer
marktimemedia
3
540
We Are The Robots
honzajavorek
0
380
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
58k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
2
930
Joys of Absence: A Defence of Solitary Play
codingconduct
1
530
The Pragmatic Product Professional
lauravandoore
37
7.5k
RailsConf 2023
tenderlove
30
1.6k
Transcript
add superpowers to your React components with ES7 decorators
javascript architect @ practo @siddharthkp
ES7 decorators stage 2 https://tc39.github.io/proposal-decorators
https://babeljs.io/docs/plugins/transform-decorators/ npm install babel-plugin-transform-decorators-legacy --save
but, first template literals ES 6 Classes arrow functions
const firstName = 'siddharth' const lastName = 'kshetrapal' const fullName
= firstName + ' ' + lastName Template literals
const firstName = 'siddharth' const lastName = 'kshetrapal' const fullName
= firstName + ' ' + lastName const fullName = `${firstName} ${lastName}` Template literals
class Human { } ES 6 classes
class Human { constructor(name) { this.name = name } speak()
{ console.log(`Hi! My name is ${this.name}`) } } ES 6 classes
class Human { constructor(name) { this.name = name } speak()
{ console.log(`Hi! My name is ${this.name}`) } } const siddharth = new Human('siddharth') siddharth.speak() // Hi! My name is siddharth ES 6 classes
function log(message) { return console.log(message) } arrow functions
function log(message) { return console.log(message) } const log = (message)
=> { return console.log(message) } arrow functions
function log(message) { return console.log(message) } const log = message
=> { return console.log(message) } arrow functions
function log(message) { return console.log(message) } const log = message
=> console.log(message) arrow functions
function log(message) { return function () { return console.log(message) }
} arrow functions
arrow functions function log(message) { return function () { return
console.log(message) } } const log = message => { return () => { return console.log(message) } }
arrow functions function log(message) { return function () { return
console.log(message) } } const log = message => { return () => console.log(message) }
arrow functions function log(message) { return function () { return
console.log(message) } } const log = message => () => console.log(message)
ES7 decorators and we’re back https://tc39.github.io/proposal-decorators
class decorators class method decorators ES7 decorators
syntax class Title extends React.Component { render () { return
<div>hello {this.props.name}</div> } }
class className { func() {} } syntax
@class-decorator class className { @class-method-decorator func() {} } syntax
class className { @class-method-decorator func() {} } class method decorators
class Human { constructor(name) { this.name = name } speak()
{ console.log(`Hi! My name is ${this.name}`) } }
class Human { constructor(name) { this.name = name } speak()
{ console.log(`Hi! My name is ${this.name}`) } } const siddharth = new Human('siddharth') siddharth.speak() // Hi! My name is siddharth
... speak() { console.log(`Hi! My name is ${this.name}`) } }
const siddharth = new Human('siddharth') siddharth.speak = () => {console.log('Hi! My name is dum dum')
... speak() { console.log(`Hi! My name is ${this.name}`) } }
const siddharth = new Human('siddharth') siddharth.speak = () => {console.log('Hi! My name is dum dum') siddharth.speak() // Hi! My name is dum dum
class Human { constructor(name) { this.name = name } @readonly
speak() { console.log(`Hi! My name is ${this.name}`) } }
syntax @decorator = function const decorator = (target, key, descriptor)
=> { }
const readonly = (target, key, descriptor) => { }
const readonly = (target, key, descriptor) => { console.log(target, key,
descriptor) } /* Human {}, 'speak', { value: [Function: speak], writable: true, enumerable: false, configurable: true } */
const readonly = (target, key, descriptor) => { descriptor.writable =
false return descriptor }
@readonly speak() { console.log(`Hi! My name is ${this.name}`) } }
const siddharth = new Human('siddharth') siddharth.speak = () => {console.log('Hi! My name is dum dum'} siddharth.speak() // Hi! My name is siddharth
class Human { constructor(name) {this.name = name} useAngular() { console.log('writing
angular code') } } siddharth.writeAngular() // writing angular code
class Human { constructor(name) {this.name = name} @deprecate useAngular() {
console.log('writing angular code') } } siddharth.writeAngular() // speak@Human: this feature will be deprecated soon! // writing angular code
const deprecate = (target, key, descriptor) => { }
const deprecate = (target, key, descriptor) => { const original
= descriptor.value const name = `${target.constructor.name}.${key}` }
const deprecate = (target, key, descriptor) => { const original
= descriptor.value const name = `${target.constructor.name}.${key}` const message = 'this feature will be deprecated soon!' descriptor.value = () => { console.log(`${name} : ${message}`) original.apply(this, arguments) } }
const deprecate = (target, key, descriptor) => { const original
= descriptor.value const name = `${target.constructor.name}.${key}` const message = 'this feature will be deprecated soon!' descriptor.value = () => { console.log(`${name} : ${message}`) original.apply(this, arguments) } return descriptor }
class Human { constructor(name) {this.name = name} @deprecate useAngular() {
console.log('writing angular code') } }
class Human { constructor(name) {this.name = name} @deprecate useAngular() {
console.log('writing angular code') } } siddharth.writeAngular() // speak@Human: this feature will be deprecated soon! // writing angular code
class Human { constructor(name) {this.name = name} @deprecate('will be deprecated
in v2.0.0') useAngular() { console.log('writing angular code') } } siddharth.writeAngular() // speak@Human: will be deprecated in v2.0.0 // writing angular code
syntax @decorator = function const decorator = (target, key, descriptor)
=> { } @decorator(argument) = higher order function const decorator = (argument) => { return (target, key, descriptor) => { } }
syntax @decorator = function const decorator = (target, key, descriptor)
=> { } @decorator(argument) = higher order function const decorator = argument => (target, key, descriptor) => { }
@deprecate = function const deprecate = (target, key, descriptor) =>
{ const original = descriptor.value const name = `${target.constructor.name}.${key}` const message = 'this feature will be deprecated soon!' descriptor.value = () => { console.log(`${name} : ${message}`) original.apply(this, arguments) } return descriptor }
@deprecate(message) = higher order function const deprecate = message =>
(target, key, descriptor) => { const original = descriptor.value const name = `${target.constructor.name}.${key}` const message = 'this feature will be deprecated soon!' descriptor.value = () => { console.log(`${name} : ${message}`) original.apply(this, arguments) } return descriptor }
@deprecate(message) = higher order function const deprecate = message =>
(target, key, descriptor) => { const original = descriptor.value const name = `${target.constructor.name}.${key}` message = message || 'this feature will be deprecated soon!' descriptor.value = () => { console.log(`${name} : ${message}`) original.apply(this, arguments) } return descriptor }
don’t fret
jayphelps/core-decorators npm install core-decorators --save
import {readonly} from 'core-decorators' class Human { constructor(name) { this.name
= name } @readonly speak() { console.log('Hi! My name is ' + this.name) } } core-decorators
import {time} from 'core-decorators' class Human { constructor(name) { this.name
= name } @time('speak') // Human.speak-0: 1.582ms speak() { console.log('Hi! My name is ' + this.name) } } core-decorators
class decorators class method decorators ES7 decorators
@class-decorator class className { func() {} } class decorators
@type('mammal') class Human { constructor(name) { this.name = name console.log('I
am' + this.name + ', a ' + this.type) } } /* class Dolphin class Crocodile class Fish */ class decorators
@type('mammal') class Human { constructor(name) { this.name = name console.log('I
am' + this.name + ', a ' + this.type) } } const type = value => target => { // add {type: value} to the target class } class decorators
None
HOC: design pattern higher order components
A higher-order component is a function that takes a component
and returns a new (modified) component. class Label extends React.Component
HOC = class decorators
class Title extends React.Component { render () { return <div>hello
{this.props.name}</div> } }
class Title extends React.Component { render () { return <div>hello
{this.props.name}</div> } } /* <Post> <Title name="..."/> </Post> /*
@loading('name') class Title extends React.Component { render () { return
<div>hello {this.props.name}</div> } } /* <Post> <Title name="..."/> </Post> /* HOC
@loading('name') class Title extends React.Component { render () { return
<div>hello {this.props.name}</div> } } const loading = key => target => class extends React.Component { } HOC
@loading('name') class Title extends React.Component { render () { return
<div>hello {this.props.name}</div> } } const loading = key => Component => class extends React.Component { } HOC
@loading('name') class Title extends React.Component { render () { return
<div>hello {this.props.name}</div> } } const loading = key => Component => class extends React.Component { render () { if (this.props[key]) return <Component {...this.props} else return <div>loading...</div> } } HOC
https://github.com/acdlite/recompose npm install recompose --save
import {withProps} from 'recompose' recompose
import {withProps} from 'recompose' @withProps({name: 'world'}) class Title extends React.Component
{ render () { return <div>hello {this.props.name}</div> } } recompose
import {withHandlers, compose} from 'recompose' const handlers = withHandlers({ onClick:
props => event => mixpanel.track('Clicked', props) }) recompose
import {withHandlers, compose} from 'recompose' const handlers = withHandlers({ onClick:
props => event => mixpanel.track('Clicked', props) }) const analytics = compose(handlers) recompose
import {withHandlers, compose} from 'recompose' const handlers = withHandlers({ onClick:
props => event => mixpanel.track('Clicked', props) }) const analytics = compose(handlers) @analytics class Title extends React.Component { render () { return <div>hello {this.props.label}</div> } } recompose
import {onlyUpdateForKeys} from 'recompose' @onlyUpdateForKeys(['name']) class Title extends React.Component {
render () { return <div>hello {this.props.name}</div> } } /* <Post> <Title {...props}/> </Post> /* recompose
class Title extends React.Component { constructor () {} /* javascript
constructor */ css () {} /* css constructor ? */ render () { return <div>hello {this.props.name}</div> } } rant/wish
None
https://github.com/siddharthkp/css-constructor npm install css-constructor --save
import css from 'css-constructor' class Title extends React.Component { constructor
() {} @css` font-size: 16px; color: {this.props.colors}; &:hover {color: #FFF;} @media {max-width: 480px} {&: font-size: 18px;} ` render () { return <div>hello {this.props.name}</div> } } css-constructor
@css(styles) = higher order function const css = styles =>
(target, key, descriptor) => { } css-constructor
@css(styles) = higher order function const css = styles =>
(target, key, descriptor) => { const prettyCSS = process(styles) // fill props, media queries, etc. const cssClass = getUniqueClassName(prettyCSS) document.head.styles += {cssClass: prettyCSS} return componentWithClassName(cssClass) } css-constructor
Fin.
@siddharthkp