SlideShare ist ein Scribd-Unternehmen logo
1 von 34
Downloaden Sie, um offline zu lesen
React, The Inglorious Way
Matteo Antony Mistretta
Inglorious Coderz
@antonymistretta
Why
React is evolving rapidly
A few rules, lots of strategies
Learning them makes us better coders
antony@ingloriouscoderz ~> whoami
Agenda
Class Components
Container/Presentational
Higher-Order Components
Render Props
Hooks
42
-1 +1
class Counter extends Component {
constructor(props) {
super(props)
this.state = { count: props.initialCount }
this.increment = this.increment.bind(this)
}
increment() {
this.setState({ count: this.state.count + 1 })
}
decrement() {
this.setState({ count: this.state.count - 1 })
}
render() {
const { count } = this.state
return (
<div>
<h1>{count}</h1>
<div className="input-group">
<button onClick={this.decrement.bind(this)}>-1</button>
<input
type="number"
value={count}
onChange={event => {
this.setState({ count: parseInt(event.target.value) })
}}
/>
<button onClick={this.increment}>+1</button>
</div>
</div>
)
}
}
render(<Counter initialCount={42} />)
42
42
-1 +1
class Counter extends PureComponent {
state = { count: this.props.initialCount }
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
render() {
const { count } = this.state
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={this.decrement}>-1</button>
<input type="number" value={count} onChange={this.handleChange} />
<button onClick={this.increment}>+1</button>
</div>
</>
)
}
}
render(<Counter initialCount={42} />)
42
Agenda
Class Components
Container/Presentational
Higher-Order Components
Render Props
Hooks
42
-1 +1
class Counter extends PureComponent {
state = { count: this.props.initialCount }
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
render() {
const { count } = this.state
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={this.decrement}>-1</button>
<input type="number" value={count} onChange={this.handleChange} />
<button onClick={this.increment}>+1</button>
</div>
</>
)
}
}
render(<Counter initialCount={42} />)
42
42
-1 +1
class CounterContainer extends PureComponent {
state = { count: this.props.initialCount }
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
render() {
return (
<Counter
count={this.state.count}
increment={this.increment}
decrement={this.decrement}
handleChange={this.handleChange}
/>
)
}
}
function Counter({ count, increment, decrement, handleChange }) {
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<CounterContainer initialCount={42} />)
42
42
-1 +1
class CounterContainer extends PureComponent {
state = { count: this.props.initialCount }
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
render() {
// NOTE: this is bad
return Counter({
count: this.state.count,
increment: this.increment,
decrement: this.decrement,
handleChange: this.handleChange,
})
}
}
function Counter({ count, increment, decrement, handleChange }) {
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<CounterContainer initialCount={42} />)
42
Agenda
Class Components
Container/Presentational
Higher-Order Components
Render Props
Hooks
42
-1 +1
class CounterContainer extends PureComponent {
state = { count: this.props.initialCount }
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
render() {
return (
<Counter
count={this.state.count}
increment={this.increment}
decrement={this.decrement}
handleChange={this.handleChange}
/>
)
}
}
function Counter({ count, increment, decrement, handleChange }) {
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<CounterContainer initialCount={42} />)
42
42
-1 +1
const withCounter = Enhanced =>
class CounterContainer extends PureComponent {
state = { count: this.props.initialCount }
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
render() {
return (
<Enhanced
count={this.state.count}
increment={this.increment}
decrement={this.decrement}
handleChange={this.handleChange}
/>
)
}
}
Counter = withCounter(Counter)
function Counter({ count, increment, decrement, handleChange }) {
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<Counter initialCount={42} />)
42
42
-1 +1
const enhance = compose(
withState('count', 'setCount', ({ initialCount }) => initialCount),
withHandlers({
increment: ({ setCount }) => () => setCount(count => count + 1),
decrement: ({ setCount }) => () => setCount(count => count - 1),
handleChange: ({ setCount }) => event =>
setCount(parseInt(event.target.value)),
}),
pure,
)
Counter = enhance(Counter)
function Counter({ count, increment, decrement, handleChange }) {
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<Counter initialCount={42} />)
42
Agenda
Class Components
Container/Presentational
Higher-Order Components
Render Props
Hooks
Hello world!
function Parent() {
return (
<Wrapper>
<Child who="world" />
</Wrapper>
)
}
function Child({ who }) {
return `Hello ${who}!`
}
function Wrapper({ children }) {
return <h1>{children}</h1>
}
render(Parent)
Hello
WORLD!
function Parent() {
return <Wrapper who="world" Component={Child} />
}
function Child({ who }) {
return `Hello ${who}!`
}
function Wrapper({ who, Component }) {
const shoutedWho = who.toUpperCase()
return (
<h1>
<Component who={shoutedWho} />
</h1>
)
}
render(Parent)
Hello
WORLDz!
function Parent() {
return <Wrapper who="world" render={who => <Child who={who + 'z'} />} />
}
function Child({ who }) {
return `Hello ${who}!`
}
function Wrapper({ who, render }) {
const shoutedWho = who.toUpperCase()
return <h1>{render(shoutedWho)}</h1>
}
render(Parent)
Hello
WORLDz!
function Parent() {
return <Wrapper who="world">{who => <Child who={who + 'z'} />}</Wrapper>
}
function Child({ who }) {
return `Hello ${who}!`
}
function Wrapper({ children, who }) {
const shoutedWho = who.toUpperCase()
return <h1>{children(shoutedWho)}</h1>
}
render(Parent)
42
-1 +1
class CounterContainer extends PureComponent {
state = { count: this.props.initialCount }
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
render() {
return (
<Counter
count={this.state.count}
increment={this.increment}
decrement={this.decrement}
handleChange={this.handleChange}
/>
)
}
}
function Counter({ count, increment, decrement, handleChange }) {
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<CounterContainer initialCount={42} />)
42
42
-1 +1
class CounterContainer extends PureComponent {
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
state = {
count: this.props.initialCount,
increment: this.increment,
decrement: this.decrement,
handleChange: this.handleChange,
}
render() {
return this.props.children(this.state)
}
}
function Counter({ initialCount }) {
return (
<CounterContainer initialCount={initialCount}>
{({ count, increment, decrement, handleChange }) => (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)}
</CounterContainer>
)
}
render(<Counter initialCount={42} />)
42
42
-1 +1
class CounterContainer extends PureComponent {
increment = () => this.setState(({ count }) => ({ count: count + 1 }))
decrement = () => this.setState(({ count }) => ({ count: count - 1 }))
setCount = count => this.setState({ count })
handleChange = event => this.setCount(parseInt(event.target.value))
state = {
count: this.props.initialCount,
increment: this.increment,
decrement: this.decrement,
handleChange: this.handleChange,
}
render() {
return this.props.children(this.state)
}
}
class Counter extends PureComponent {
renderCounter = ({ count, increment, decrement, handleChange }) => (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
render() {
return (
<CounterContainer initialCount={this.props.initialCount}>
{this.renderCounter}
</CounterContainer>
)
}
}
render(<Counter initialCount={42} />)
42
Agenda
Class Components
Container/Presentational
Higher-Order Components
Render Props
Hooks
They separate stateful logic
They are composable functions
They allow us to go fully functional
They keep our component hierarchy flat
42
-1 +1
const enhance = compose(
withState('count', 'setCount', ({ initialCount }) => initialCount),
withHandlers({
increment: ({ setCount }) => () => setCount(count => count + 1),
decrement: ({ setCount }) => () => setCount(count => count - 1),
handleChange: ({ setCount }) => event =>
setCount(parseInt(event.target.value)),
}),
pure,
)
Counter = enhance(Counter)
function Counter({ count, increment, decrement, handleChange }) {
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<Counter initialCount={42} />)
42
42
-1 +1
function useCounter(initialCount) {
const [count, setCount] = useState(initialCount)
const increment = () => setCount(count + 1)
const decrement = () => setCount(count - 1)
const handleChange = event => setCount(parseInt(event.target.value))
return { count, increment, decrement, handleChange }
}
Counter = memo(Counter)
function Counter({ initialCount }) {
const { count, increment, decrement, handleChange } = useCounter(initialCount)
return (
<>
<h1>{count}</h1>
<div className="input-group">
<button onClick={decrement}>-1</button>
<input type="number" value={count} onChange={handleChange} />
<button onClick={increment}>+1</button>
</div>
</>
)
}
render(<Counter initialCount={42} />)
42
Which to use?
Hello
WORLD!
function Hello({ who }) {
return <h1>{`Hello ${who}!`}</h1>
}
const enhance = Enhanced => ({ who, ...props }) => {
if (!who.length) return 'Name too short'
const shoutedWho = who.toUpperCase()
return <Enhanced {...props} who={shoutedWho} />
}
Hello = enhance(Hello)
render(<Hello who="world" />)
world
though
ly
tual
issey
const SimpleList = ({ whos }) => (
<ul style={styles.list}>
{whos.map(who => (
<li>{who}</li>
))}
</ul>
)
const ComplexList = ({ renderEven, renderOdd, whos }) => (
<ul style={styles.list}>
{whos.map((who, index) => (index % 2 ? renderEven(who) : renderOdd(who)))}
</ul>
)
const Parent = ({ whos, simple }) => {
if (simple) return <SimpleList whos={whos} />
return (
<ComplexList
renderEven={who => <li style={styles.even}>{'Even ' + who}</li>}
renderOdd={who => <li style={styles.odd}>{'Odd ' + who}</li>}
whos={whos}
/>
)
}
render(
<Parent whos={['world', 'though', 'ly', 'tual', 'issey']} simple={true} />,
)
const styles = {
list: { textAlign: 'left' },
odd: { color: 'grey' },
even: { color: 'cornflowerblue' },
}
Which to use?
Classes: getSnapshotBeforeUpdate / componentDidCatch
HOCs: proxy / before render (change props, prevent renders)
Render Props: mix logic / multiple sub-items / switch behavior
Hooks: everything else
Thank you.
Questions?
html | pdf | source

Weitere ähnliche Inhalte

Ähnlich wie Matteo Antony Mistretta - React, the Inglorious way - Codemotion Amsterdam 2019

React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to HooksSoluto
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projectsIgnacio Martín
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersTikal Knowledge
 
Modern JavaScript Engine Performance
Modern JavaScript Engine PerformanceModern JavaScript Engine Performance
Modern JavaScript Engine PerformanceCatalin Dumitru
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JSFestUA
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to beJana Karceska
 
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)indeedeng
 
Functional programming techniques in real-world microservices
Functional programming techniques in real-world microservicesFunctional programming techniques in real-world microservices
Functional programming techniques in real-world microservicesAndrás Papp
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingSergey Shishkin
 
Gerenciamento de estado no Angular com NgRx
Gerenciamento de estado no Angular com NgRxGerenciamento de estado no Angular com NgRx
Gerenciamento de estado no Angular com NgRxLoiane Groner
 
Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2Martin Zapletal
 
Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Alex Semin
 
Data in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyData in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyMartin Zapletal
 
React Back to the Future
React Back to the FutureReact Back to the Future
React Back to the Future500Tech
 
This is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfThis is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfindiaartz
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wildJoe Morgan
 
Building complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactBuilding complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactJonne Kats
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기진성 오
 

Ähnlich wie Matteo Antony Mistretta - React, the Inglorious way - Codemotion Amsterdam 2019 (20)

React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to Hooks
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 
Modern JavaScript Engine Performance
Modern JavaScript Engine PerformanceModern JavaScript Engine Performance
Modern JavaScript Engine Performance
 
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to be
 
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
Indeed My Jobs: A case study in ReactJS and Redux (Meetup talk March 2016)
 
Functional programming techniques in real-world microservices
Functional programming techniques in real-world microservicesFunctional programming techniques in real-world microservices
Functional programming techniques in real-world microservices
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional Programming
 
Road to react hooks
Road to react hooksRoad to react hooks
Road to react hooks
 
ReactJS
ReactJSReactJS
ReactJS
 
Gerenciamento de estado no Angular com NgRx
Gerenciamento de estado no Angular com NgRxGerenciamento de estado no Angular com NgRx
Gerenciamento de estado no Angular com NgRx
 
Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2Data in Motion: Streaming Static Data Efficiently 2
Data in Motion: Streaming Static Data Efficiently 2
 
Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303
 
Data in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data EfficientlyData in Motion: Streaming Static Data Efficiently
Data in Motion: Streaming Static Data Efficiently
 
React Back to the Future
React Back to the FutureReact Back to the Future
React Back to the Future
 
This is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdfThis is a C# project . I am expected to create as this image shows. .pdf
This is a C# project . I am expected to create as this image shows. .pdf
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wild
 
Building complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and ReactBuilding complex User Interfaces with Sitecore and React
Building complex User Interfaces with Sitecore and React
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
 

Mehr von Codemotion

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyCodemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaCodemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserCodemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 - Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Codemotion
 

Mehr von Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Kürzlich hochgeladen

Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 

Kürzlich hochgeladen (20)

Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 

Matteo Antony Mistretta - React, the Inglorious way - Codemotion Amsterdam 2019

  • 1. React, The Inglorious Way Matteo Antony Mistretta Inglorious Coderz @antonymistretta
  • 2. Why React is evolving rapidly A few rules, lots of strategies Learning them makes us better coders
  • 5. 42 -1 +1 class Counter extends Component { constructor(props) { super(props) this.state = { count: props.initialCount } this.increment = this.increment.bind(this) } increment() { this.setState({ count: this.state.count + 1 }) } decrement() { this.setState({ count: this.state.count - 1 }) } render() { const { count } = this.state return ( <div> <h1>{count}</h1> <div className="input-group"> <button onClick={this.decrement.bind(this)}>-1</button> <input type="number" value={count} onChange={event => { this.setState({ count: parseInt(event.target.value) }) }} /> <button onClick={this.increment}>+1</button> </div> </div> ) } } render(<Counter initialCount={42} />) 42
  • 6. 42 -1 +1 class Counter extends PureComponent { state = { count: this.props.initialCount } increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) render() { const { count } = this.state return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={this.decrement}>-1</button> <input type="number" value={count} onChange={this.handleChange} /> <button onClick={this.increment}>+1</button> </div> </> ) } } render(<Counter initialCount={42} />) 42
  • 8. 42 -1 +1 class Counter extends PureComponent { state = { count: this.props.initialCount } increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) render() { const { count } = this.state return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={this.decrement}>-1</button> <input type="number" value={count} onChange={this.handleChange} /> <button onClick={this.increment}>+1</button> </div> </> ) } } render(<Counter initialCount={42} />) 42
  • 9. 42 -1 +1 class CounterContainer extends PureComponent { state = { count: this.props.initialCount } increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) render() { return ( <Counter count={this.state.count} increment={this.increment} decrement={this.decrement} handleChange={this.handleChange} /> ) } } function Counter({ count, increment, decrement, handleChange }) { return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<CounterContainer initialCount={42} />) 42
  • 10. 42 -1 +1 class CounterContainer extends PureComponent { state = { count: this.props.initialCount } increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) render() { // NOTE: this is bad return Counter({ count: this.state.count, increment: this.increment, decrement: this.decrement, handleChange: this.handleChange, }) } } function Counter({ count, increment, decrement, handleChange }) { return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<CounterContainer initialCount={42} />) 42
  • 12. 42 -1 +1 class CounterContainer extends PureComponent { state = { count: this.props.initialCount } increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) render() { return ( <Counter count={this.state.count} increment={this.increment} decrement={this.decrement} handleChange={this.handleChange} /> ) } } function Counter({ count, increment, decrement, handleChange }) { return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<CounterContainer initialCount={42} />) 42
  • 13. 42 -1 +1 const withCounter = Enhanced => class CounterContainer extends PureComponent { state = { count: this.props.initialCount } increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) render() { return ( <Enhanced count={this.state.count} increment={this.increment} decrement={this.decrement} handleChange={this.handleChange} /> ) } } Counter = withCounter(Counter) function Counter({ count, increment, decrement, handleChange }) { return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<Counter initialCount={42} />) 42
  • 14. 42 -1 +1 const enhance = compose( withState('count', 'setCount', ({ initialCount }) => initialCount), withHandlers({ increment: ({ setCount }) => () => setCount(count => count + 1), decrement: ({ setCount }) => () => setCount(count => count - 1), handleChange: ({ setCount }) => event => setCount(parseInt(event.target.value)), }), pure, ) Counter = enhance(Counter) function Counter({ count, increment, decrement, handleChange }) { return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<Counter initialCount={42} />) 42
  • 16. Hello world! function Parent() { return ( <Wrapper> <Child who="world" /> </Wrapper> ) } function Child({ who }) { return `Hello ${who}!` } function Wrapper({ children }) { return <h1>{children}</h1> } render(Parent)
  • 17. Hello WORLD! function Parent() { return <Wrapper who="world" Component={Child} /> } function Child({ who }) { return `Hello ${who}!` } function Wrapper({ who, Component }) { const shoutedWho = who.toUpperCase() return ( <h1> <Component who={shoutedWho} /> </h1> ) } render(Parent)
  • 18. Hello WORLDz! function Parent() { return <Wrapper who="world" render={who => <Child who={who + 'z'} />} /> } function Child({ who }) { return `Hello ${who}!` } function Wrapper({ who, render }) { const shoutedWho = who.toUpperCase() return <h1>{render(shoutedWho)}</h1> } render(Parent)
  • 19. Hello WORLDz! function Parent() { return <Wrapper who="world">{who => <Child who={who + 'z'} />}</Wrapper> } function Child({ who }) { return `Hello ${who}!` } function Wrapper({ children, who }) { const shoutedWho = who.toUpperCase() return <h1>{children(shoutedWho)}</h1> } render(Parent)
  • 20. 42 -1 +1 class CounterContainer extends PureComponent { state = { count: this.props.initialCount } increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) render() { return ( <Counter count={this.state.count} increment={this.increment} decrement={this.decrement} handleChange={this.handleChange} /> ) } } function Counter({ count, increment, decrement, handleChange }) { return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<CounterContainer initialCount={42} />) 42
  • 21. 42 -1 +1 class CounterContainer extends PureComponent { increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) state = { count: this.props.initialCount, increment: this.increment, decrement: this.decrement, handleChange: this.handleChange, } render() { return this.props.children(this.state) } } function Counter({ initialCount }) { return ( <CounterContainer initialCount={initialCount}> {({ count, increment, decrement, handleChange }) => ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> )} </CounterContainer> ) } render(<Counter initialCount={42} />) 42
  • 22. 42 -1 +1 class CounterContainer extends PureComponent { increment = () => this.setState(({ count }) => ({ count: count + 1 })) decrement = () => this.setState(({ count }) => ({ count: count - 1 })) setCount = count => this.setState({ count }) handleChange = event => this.setCount(parseInt(event.target.value)) state = { count: this.props.initialCount, increment: this.increment, decrement: this.decrement, handleChange: this.handleChange, } render() { return this.props.children(this.state) } } class Counter extends PureComponent { renderCounter = ({ count, increment, decrement, handleChange }) => ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) render() { return ( <CounterContainer initialCount={this.props.initialCount}> {this.renderCounter} </CounterContainer> ) } } render(<Counter initialCount={42} />) 42
  • 24. They separate stateful logic They are composable functions They allow us to go fully functional They keep our component hierarchy flat
  • 25. 42 -1 +1 const enhance = compose( withState('count', 'setCount', ({ initialCount }) => initialCount), withHandlers({ increment: ({ setCount }) => () => setCount(count => count + 1), decrement: ({ setCount }) => () => setCount(count => count - 1), handleChange: ({ setCount }) => event => setCount(parseInt(event.target.value)), }), pure, ) Counter = enhance(Counter) function Counter({ count, increment, decrement, handleChange }) { return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<Counter initialCount={42} />) 42
  • 26. 42 -1 +1 function useCounter(initialCount) { const [count, setCount] = useState(initialCount) const increment = () => setCount(count + 1) const decrement = () => setCount(count - 1) const handleChange = event => setCount(parseInt(event.target.value)) return { count, increment, decrement, handleChange } } Counter = memo(Counter) function Counter({ initialCount }) { const { count, increment, decrement, handleChange } = useCounter(initialCount) return ( <> <h1>{count}</h1> <div className="input-group"> <button onClick={decrement}>-1</button> <input type="number" value={count} onChange={handleChange} /> <button onClick={increment}>+1</button> </div> </> ) } render(<Counter initialCount={42} />) 42
  • 28.
  • 29.
  • 30.
  • 31. Hello WORLD! function Hello({ who }) { return <h1>{`Hello ${who}!`}</h1> } const enhance = Enhanced => ({ who, ...props }) => { if (!who.length) return 'Name too short' const shoutedWho = who.toUpperCase() return <Enhanced {...props} who={shoutedWho} /> } Hello = enhance(Hello) render(<Hello who="world" />)
  • 32. world though ly tual issey const SimpleList = ({ whos }) => ( <ul style={styles.list}> {whos.map(who => ( <li>{who}</li> ))} </ul> ) const ComplexList = ({ renderEven, renderOdd, whos }) => ( <ul style={styles.list}> {whos.map((who, index) => (index % 2 ? renderEven(who) : renderOdd(who)))} </ul> ) const Parent = ({ whos, simple }) => { if (simple) return <SimpleList whos={whos} /> return ( <ComplexList renderEven={who => <li style={styles.even}>{'Even ' + who}</li>} renderOdd={who => <li style={styles.odd}>{'Odd ' + who}</li>} whos={whos} /> ) } render( <Parent whos={['world', 'though', 'ly', 'tual', 'issey']} simple={true} />, ) const styles = { list: { textAlign: 'left' }, odd: { color: 'grey' }, even: { color: 'cornflowerblue' }, }
  • 33. Which to use? Classes: getSnapshotBeforeUpdate / componentDidCatch HOCs: proxy / before render (change props, prevent renders) Render Props: mix logic / multiple sub-items / switch behavior Hooks: everything else