SlideShare a Scribd company logo
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

More Related Content

Similar to 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 Hooks
Soluto
 
Integrating React.js with PHP projects
Integrating React.js with PHP projectsIntegrating React.js with PHP projects
Integrating React.js with PHP projects
Ignacio Martín
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
Tikal 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 be
Jana 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 microservices
András Papp
 
Hitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional ProgrammingHitchhiker's Guide to Functional Programming
Hitchhiker's Guide to Functional Programming
Sergey Shishkin
 
Road to react hooks
Road to react hooksRoad to react hooks
Road to react hooks
Younes (omar) Meliani
 
ReactJS
ReactJSReactJS
ReactJS
Kamlesh Singh
 
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
Loiane 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 2
Martin Zapletal
 
Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303Dip into Coroutines - KTUG Munich 202303
Dip into Coroutines - KTUG Munich 202303
Alex 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 Efficiently
Martin Zapletal
 
React Back to the Future
React Back to the FutureReact Back to the Future
React Back to the Future
500Tech
 
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
indiaartz
 
ES6 patterns in the wild
ES6 patterns in the wildES6 patterns in the wild
ES6 patterns in the wild
Joe 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 React
Jonne Kats
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
진성 오
 

Similar to 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 함수 커링 사용하기
 

More from 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 story
Codemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
Codemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
Codemotion
 
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 2019
Codemotion
 
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
Codemotion
 
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 2019
Codemotion
 
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
Codemotion
 
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
Codemotion
 
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 2019
Codemotion
 
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
Codemotion
 
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
Codemotion
 

More from 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
 

Recently uploaded

Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
Jen Stirrup
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
Kari Kakkonen
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
UiPathCommunity
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
sonjaschweigert1
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
UiPathCommunity
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
Vlad Stirbu
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 

Recently uploaded (20)

Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...The Metaverse and AI: how can decision-makers harness the Metaverse for their...
The Metaverse and AI: how can decision-makers harness the Metaverse for their...
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Climate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing DaysClimate Impact of Software Testing at Nordic Testing Days
Climate Impact of Software Testing at Nordic Testing Days
 
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
Le nuove frontiere dell'AI nell'RPA con UiPath Autopilot™
 
A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...A tale of scale & speed: How the US Navy is enabling software delivery from l...
A tale of scale & speed: How the US Navy is enabling software delivery from l...
 
UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..UiPath Community Day Dubai: AI at Work..
UiPath Community Day Dubai: AI at Work..
 
Quantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIsQuantum Computing: Current Landscape and the Future Role of APIs
Quantum Computing: Current Landscape and the Future Role of APIs
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 

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