SlideShare a Scribd company logo
September 2018
Powering Code Reuse

with Context and Render Props
Forbes Lindesay
Thanks to our sponsors!
FUNCTIONS AS FIRST
CLASS VALUES
DOUBLE/TRIPPLE ARRAY
function doubleArr(vs) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] * 2);
}
return result;
}
// input: [1, 2, 3]
// output: [2, 4, 6]
function trippleArr(vs) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] * 3);
}
return result;
}
// input: [1, 2, 3]
// output: [3, 6, 9]
function trippleArr(vs) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] * 3);
}
return result;
}
// input: [1, 2, 3]
// output: [3, 6, 9]
function doubleArr(vs) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] * 2);
}
return result;
}
// input: [1, 2, 3]
// output: [2, 4, 6]
DOUBLE/TRIPPLE ARRAY
function multiplyArr(vs, factor) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] * factor);
}
return result;
}
MULTIPLY ARRAY
MULTIPLY/ADD ARRAY
function multiplyArr(vs, factor) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] * factor);
}
return result;
}
// input: [1, 2, 3], 3
// output: [3, 6, 9]
function addArr(vs, increment) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] + increment);
}
return result;
}
// input: [1, 2, 3], 3
// output: [4, 5, 6]
function multiplyArr(vs, factor) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] * factor);
}
return result;
}
// input: [1, 2, 3], 3
// output: [3, 6, 9]
function addArr(vs, increment) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(vs[i] + increment);
}
return result;
}
// input: [1, 2, 3], 3
// output: [4, 5, 6]
MULTIPLY/ADD ARRAY
function mapArray(vs, fn) {
const result = [];
for (let i=0;i<vs.length;i ++) {
result.push(fn(vs[i]));
}
return result;
}
MAP ARRAY
MAP ARRAY
function mapArray(vs, fn) {
return vs.map(fn);
}
REACT PROPERTIES
ARE PARAMETERS
REACT NOW
class Now extends React.Component {
state = {now: new Date()};
componentDidMount() {
this._timer = setInterval(
() => this.setState({now: new Date()}),
100,
);
}
componentWillUnmount() {
clearInterval(this._timer);
}
render() {
return this.state.now.toString();
}
}
REACT NOW
class UTCNow extends React.Component {
state = {now: new Date()};
componentDidMount() {
this._timer = setInterval(
() => this.setState({now: new Date()}),
100,
);
}
componentWillUnmount() {
clearInterval(this._timer);
}
render() {
return this.state.now.toUTCString();
}
}
class UTCNow extends React.Component {
state = {now: new Date()};
componentDidMount() {
this._timer = setInterval(
() => this.setState({now: new Date()}),
100,
);
}
componentWillUnmount() {
clearInterval(this._timer);
}
render() {
return this.state.now.toUTCString();
}
}
REACT NOW
REACT NOW
class Now extends React.Component {
state = {now: new Date()};
componentDidMount() {
this._timer = setInterval(
() => this.setState({now: new Date()}),
100,
);
}
componentWillUnmount() {
clearInterval(this._timer);
}
render() {
return this.state.now.[
this.props.utc ? 'toUTCString' : 'toString'
]();
}
}
REACT NOW
class Now extends React.Component {
state = {now: new Date()};
componentDidMount() {
this._timer = setInterval(
() => this.setState({now: new Date()}),
100,
);
}
componentWillUnmount() {
clearInterval(this._timer);
}
render() {
return this.props.render(this.state.now);
}
}
REACT NOW
function LocalTime() {
return <Now render={now => now.toTimeString()} />;
}
function UTCTime() {
return <Now render={now => now.toUTCTimeString()} />;
}
function LocalDateTime() {
return <Now render={now => now.toString()} />;
}
function UTCDateTime() {
return <Now render={now => now.toUTCString()} />;
}
DATE FORMATTING
Fri Sep 14 2018 15:47:26 GMT+0200 (Central European
Summer Time)
<strong>Fri Sep 14 2018 </strong> 15:47:26
GMT+0200 (Central European Summer Time)
REACT NOW
function DateTime() {
return (
<Now render={now => (
<React.Fragment>
<strong>{now.toDateString()} </strong>
{' ' + now.toTimeString()}
</React.Fragment>
)} />
);
}
“CHILDREN” IS JUST
A SPECIAL PROPERTY
REACT NOW
class Now extends React.Component {
state = {now: new Date()};
componentDidMount() {
this._timer = setInterval(
() => this.setState({now: new Date()}),
100,
);
}
componentWillUnmount() {
clearInterval(this._timer);
}
render() {
return this.props.render(this.state.now);
}
}
REACT NOW
class Now extends React.Component {
state = {now: new Date()};
componentDidMount() {
this._timer = setInterval(
() => this.setState({now: new Date()}),
100,
);
}
componentWillUnmount() {
clearInterval(this._timer);
}
render() {
return this.props.children(this.state.now);
}
}
function DateTime() {
return (
<Now render={now => (
<React.Fragment>
<strong>{now.toDateString()} </strong>
{' ' + now.toTimeString()}
</React.Fragment>
)} />
);
}
REACT NOW
REACT NOW
function DateTime() {
return (
<Now>
{now => (
<React.Fragment>
<strong>{now.toDateString()} </strong>
{' ' + now.toTimeString()}
</React.Fragment>
)}
</Now>
);
}
STATE IS ANYTHING THAT
CHANGES OVER TIME
REACT TREE
COMPONENT
COMPONENT COMPONENT
COMPONENT COMPONENTCOMPONENTCOMPONENT
COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT
REACT TREE
COMPONENT
COMPONENT COMPONENT
COMPONENT COMPONENTCOMPONENTCOMPONENT
COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTA
REACT TREE
COMPONENT
COMPONENT COMPONENT
COMPONENT COMPONENTCOMPONENTCOMPONENT
COMPONENT COMPONENT COMPONENT COMPONENTBA
REACT TREE
COMPONENT
COMPONENT COMPONENT
PARENT COMPONENTCOMPONENTCOMPONENT
COMPONENT COMPONENT COMPONENT COMPONENTBA
REACT TREE
COMPONENT
COMPONENT COMPONENT
PARENT COMPONENTCOMPONENTCOMPONENT
COMPONENT C COMPONENT COMPONENTBA
REACT TREE
ROOT
COMPONENT COMPONENT
PARENT COMPONENTCOMPONENTCOMPONENT
COMPONENT C COMPONENT COMPONENTBA
REACT TREE
ROOT
COMPONENT COMPONENT
PARENT COMPONENTCOMPONENTCOMPONENT
COMPONENT C COMPONENT COMPONENTBA
REACT TREE
ROOT
COMPONENT COMPONENT
COMPONENT COMPONENTCOMPONENTCOMPONENT
COMPONENT C COMPONENT COMPONENTBA
External Store?
REACT TREE
ROOT
COMPONENT COMPONENT
COMPONENT COMPONENTCOMPONENTCOMPONENT
COMPONENT C COMPONENT COMPONENTBA
REACT TREE
ROOT
COMPONENT COMPONENT
COMPONENT COMPONENTCOMPONENTCOMPONENT
COMPONENT C COMPONENT COMPONENTBA
REACT TREE
ROOT
SHARED
PARENT COMPONENT
COMPONENT COMPONENTCOMPONENT
C
COMPONENT
COMPONENT COMPONENT COMPONENTBA
REACT TREE
ROOT
SHARED
PARENT COMPONENT
COMPONENT COMPONENT
C
COMPONENT
COMPONENT D EBA
SHARED
PARENT 2
const Color = React.createContext('black');
function ThemedCircle() {
return (
<Color.Consumer>
{color => <Circle color={color} />}
</Color.Consumer>
)
}
<React.Fragment>
<Color.Provider value="blue">
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</Color.Provider>
<Color.Provider value="red">
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</Color.Provider>
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</React.Fragment>
const Color = React.createContext('black');
function ThemedCircle() {
return (
<Color.Consumer>
{color => <Circle color={color} />}
</Color.Consumer>
)
}
<React.Fragment>
<Color.Provider value="blue">
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</Color.Provider>
<Color.Provider value="red">
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</Color.Provider>
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</React.Fragment>
const Color = React.createContext('black');
function ThemedCircle() {
return (
<Color.Consumer>
{color => <Circle color={color} />}
</Color.Consumer>
)
}
<React.Fragment>
<Color.Provider value="blue">
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</Color.Provider>
<Color.Provider value="red">
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</Color.Provider>
<ThemedCircle /><ThemedCircle /><ThemedCircle />
</React.Fragment>
const Toggle = React.createContext({on: false, onToggle: () => {}});
class ToggleProvider extends React.Component {
state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))};
render() {
return (
<Toggle.Provider value={this.state}>
{this.props.children}
</Toggle.Provider>
);
}
}
function ToggleButton() {
return (
<Toggle.Consumer>
{({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>}
</Toggle.Consumer>
)
}
<ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
const Toggle = React.createContext({on: false, onToggle: () => {}});
class ToggleProvider extends React.Component {
state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))};
render() {
return (
<Toggle.Provider value={this.state}>
{this.props.children}
</Toggle.Provider>
);
}
}
function ToggleButton() {
return (
<Toggle.Consumer>
{({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>}
</Toggle.Consumer>
)
}
<ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
const Toggle = React.createContext({on: false, onToggle: () => {}});
class ToggleProvider extends React.Component {
state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))};
render() {
return (
<Toggle.Provider value={this.state}>
{this.props.children}
</Toggle.Provider>
);
}
}
function ToggleButton() {
return (
<Toggle.Consumer>
{({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>}
</Toggle.Consumer>
)
}
<ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
const Toggle = React.createContext({on: false, onToggle: () => {}});
class ToggleProvider extends React.Component {
state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))};
render() {
return (
<Toggle.Provider value={this.state}>
{this.props.children}
</Toggle.Provider>
);
}
}
function ToggleButton() {
return (
<Toggle.Consumer>
{({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>}
</Toggle.Consumer>
)
}
<ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
OFF OFF OFF
const Toggle = React.createContext({on: false, onToggle: () => {}});
class ToggleProvider extends React.Component {
state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))};
render() {
return (
<Toggle.Provider value={this.state}>
{this.props.children}
</Toggle.Provider>
);
}
}
function ToggleButton() {
return (
<Toggle.Consumer>
{({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>}
</Toggle.Consumer>
)
}
<ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
ON ON ON
const Toggle = React.createContext({on: false, onToggle: () => {}});
class ToggleProvider extends React.Component {
state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))};
render() {
return (
<Toggle.Provider value={this.state}>
{this.props.children}
</Toggle.Provider>
);
}
}
function ToggleButton() {
return (
<Toggle.Consumer>
{({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>}
</Toggle.Consumer>
)
}
<ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
OFF OFF OFF
const Toggle = React.createContext({on: false, onToggle: () => {}});
class ToggleProvider extends React.Component {
state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))};
render() {
return (
<Toggle.Provider value={this.state}>
{this.props.children}
</Toggle.Provider>
);
}
}
function ToggleButton() {
return (
<Toggle.Consumer>
{({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>}
</Toggle.Consumer>
)
}
<ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
ON ON ON
SUMMARY
▸ Functions being first class values means we can use them as
parameters to enable more flexible code re-use
▸ Using functions as parameters allows highly customisable
shared components, complete with state and lifecycle hooks.
▸ React Context lets you share state across the tree of your
application
▸ Context still uses the React tree. This means it works with
server side rendering and you can safely use it in parts of your
app, as well as using it as a whole app solution.
@ForbesLindesay

More Related Content

PDF
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
PPTX
Rxjs marble-testing
PDF
Gearman, from the worker's perspective
PPT
Gearmam, from the_worker's_perspective copy
PPTX
Typescript barcelona
PDF
Effective Java with Groovy - How Language Influences Adoption of Good Practices
PDF
AJUG April 2011 Cascading example
PDF
Grid gain paper
JS Fest 2019. Glenn Reyes. With great power comes great React hooks!
Rxjs marble-testing
Gearman, from the worker's perspective
Gearmam, from the_worker's_perspective copy
Typescript barcelona
Effective Java with Groovy - How Language Influences Adoption of Good Practices
AJUG April 2011 Cascading example
Grid gain paper

What's hot (20)

PDF
React hooks beyond hype
ODT
Logic Equations Resolver J Script
DOCX
Big data unit iv and v lecture notes qb model exam
PPT
Gwt RPC
PPTX
An introduction to Test Driven Development on MapReduce
PDF
How MapReduce part of Hadoop works (i.e. system's view) ?
PDF
Clojure functions midje
PDF
Chapter 8- Advanced Views and URLconfs
PDF
React new features and intro to Hooks
PPTX
A quick introduction to R
PDF
Recompacting your react application
PDF
Higher-Order Components — Ilya Gelman
PPTX
Introduction to nsubstitute
PPTX
What's new for developers in Dynamics 365 v9: Client API enhancement
PDF
React Back to the Future
PDF
Deep Dive into React Hooks
DOC
Converting Db Schema Into Uml Classes
PDF
Testing in those hard to reach places
 
PPTX
The redux saga begins
PDF
Zenddispatch en
React hooks beyond hype
Logic Equations Resolver J Script
Big data unit iv and v lecture notes qb model exam
Gwt RPC
An introduction to Test Driven Development on MapReduce
How MapReduce part of Hadoop works (i.e. system's view) ?
Clojure functions midje
Chapter 8- Advanced Views and URLconfs
React new features and intro to Hooks
A quick introduction to R
Recompacting your react application
Higher-Order Components — Ilya Gelman
Introduction to nsubstitute
What's new for developers in Dynamics 365 v9: Client API enhancement
React Back to the Future
Deep Dive into React Hooks
Converting Db Schema Into Uml Classes
Testing in those hard to reach places
 
The redux saga begins
Zenddispatch en
Ad

Similar to Powering code reuse with context and render props (20)

PDF
JSLab. Алексей Волков. "React на практике"
PDF
React lecture
PDF
Higher Order Components and Render Props
PPTX
React & Redux for noobs
PDF
React for Re-use: Creating UI Components with Confluence Connect
PDF
Dive into React Performance
PDF
ES6 patterns in the wild
PPTX
Fact, Fiction, and FP
PDF
react-hooks.pdf
PPTX
React hooks
PDF
Intro to Redux | DreamLab Academy #3
PDF
React, Redux and es6/7
PDF
Exploring Angular 2 - Episode 2
PDF
Introduction to Redux
PDF
Decoding Kotlin - Your Guide to Solving the Mysterious in Kotlin - Devoxx PL ...
PDF
Intro to React | DreamLab Academy
PDF
Road to react hooks
PDF
Pragmatic functional refactoring with java 8 (1)
PPTX
React/Redux
PDF
What is new in sulu 2.0
JSLab. Алексей Волков. "React на практике"
React lecture
Higher Order Components and Render Props
React & Redux for noobs
React for Re-use: Creating UI Components with Confluence Connect
Dive into React Performance
ES6 patterns in the wild
Fact, Fiction, and FP
react-hooks.pdf
React hooks
Intro to Redux | DreamLab Academy #3
React, Redux and es6/7
Exploring Angular 2 - Episode 2
Introduction to Redux
Decoding Kotlin - Your Guide to Solving the Mysterious in Kotlin - Devoxx PL ...
Intro to React | DreamLab Academy
Road to react hooks
Pragmatic functional refactoring with java 8 (1)
React/Redux
What is new in sulu 2.0
Ad

Recently uploaded (20)

PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PPTX
Transform Your Business with a Software ERP System
PPTX
Reimagine Home Health with the Power of Agentic AI​
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PPTX
assetexplorer- product-overview - presentation
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PPTX
history of c programming in notes for students .pptx
PPTX
L1 - Introduction to python Backend.pptx
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
medical staffing services at VALiNTRY
PDF
System and Network Administration Chapter 2
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
VVF-Customer-Presentation2025-Ver1.9.pptx
PPTX
Introduction to Artificial Intelligence
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
Transform Your Business with a Software ERP System
Reimagine Home Health with the Power of Agentic AI​
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
assetexplorer- product-overview - presentation
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Odoo Companies in India – Driving Business Transformation.pdf
Design an Analysis of Algorithms I-SECS-1021-03
history of c programming in notes for students .pptx
L1 - Introduction to python Backend.pptx
How to Choose the Right IT Partner for Your Business in Malaysia
medical staffing services at VALiNTRY
System and Network Administration Chapter 2
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Wondershare Filmora 15 Crack With Activation Key [2025
Softaken Excel to vCard Converter Software.pdf
How to Migrate SBCGlobal Email to Yahoo Easily
VVF-Customer-Presentation2025-Ver1.9.pptx
Introduction to Artificial Intelligence
Adobe Illustrator 28.6 Crack My Vision of Vector Design

Powering code reuse with context and render props

  • 1. September 2018 Powering Code Reuse with Context and Render Props Forbes Lindesay
  • 2. Thanks to our sponsors!
  • 4. DOUBLE/TRIPPLE ARRAY function doubleArr(vs) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] * 2); } return result; } // input: [1, 2, 3] // output: [2, 4, 6] function trippleArr(vs) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] * 3); } return result; } // input: [1, 2, 3] // output: [3, 6, 9]
  • 5. function trippleArr(vs) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] * 3); } return result; } // input: [1, 2, 3] // output: [3, 6, 9] function doubleArr(vs) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] * 2); } return result; } // input: [1, 2, 3] // output: [2, 4, 6] DOUBLE/TRIPPLE ARRAY
  • 6. function multiplyArr(vs, factor) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] * factor); } return result; } MULTIPLY ARRAY
  • 7. MULTIPLY/ADD ARRAY function multiplyArr(vs, factor) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] * factor); } return result; } // input: [1, 2, 3], 3 // output: [3, 6, 9] function addArr(vs, increment) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] + increment); } return result; } // input: [1, 2, 3], 3 // output: [4, 5, 6]
  • 8. function multiplyArr(vs, factor) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] * factor); } return result; } // input: [1, 2, 3], 3 // output: [3, 6, 9] function addArr(vs, increment) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(vs[i] + increment); } return result; } // input: [1, 2, 3], 3 // output: [4, 5, 6] MULTIPLY/ADD ARRAY
  • 9. function mapArray(vs, fn) { const result = []; for (let i=0;i<vs.length;i ++) { result.push(fn(vs[i])); } return result; } MAP ARRAY
  • 10. MAP ARRAY function mapArray(vs, fn) { return vs.map(fn); }
  • 12. REACT NOW class Now extends React.Component { state = {now: new Date()}; componentDidMount() { this._timer = setInterval( () => this.setState({now: new Date()}), 100, ); } componentWillUnmount() { clearInterval(this._timer); } render() { return this.state.now.toString(); } }
  • 13. REACT NOW class UTCNow extends React.Component { state = {now: new Date()}; componentDidMount() { this._timer = setInterval( () => this.setState({now: new Date()}), 100, ); } componentWillUnmount() { clearInterval(this._timer); } render() { return this.state.now.toUTCString(); } }
  • 14. class UTCNow extends React.Component { state = {now: new Date()}; componentDidMount() { this._timer = setInterval( () => this.setState({now: new Date()}), 100, ); } componentWillUnmount() { clearInterval(this._timer); } render() { return this.state.now.toUTCString(); } } REACT NOW
  • 15. REACT NOW class Now extends React.Component { state = {now: new Date()}; componentDidMount() { this._timer = setInterval( () => this.setState({now: new Date()}), 100, ); } componentWillUnmount() { clearInterval(this._timer); } render() { return this.state.now.[ this.props.utc ? 'toUTCString' : 'toString' ](); } }
  • 16. REACT NOW class Now extends React.Component { state = {now: new Date()}; componentDidMount() { this._timer = setInterval( () => this.setState({now: new Date()}), 100, ); } componentWillUnmount() { clearInterval(this._timer); } render() { return this.props.render(this.state.now); } }
  • 17. REACT NOW function LocalTime() { return <Now render={now => now.toTimeString()} />; } function UTCTime() { return <Now render={now => now.toUTCTimeString()} />; } function LocalDateTime() { return <Now render={now => now.toString()} />; } function UTCDateTime() { return <Now render={now => now.toUTCString()} />; }
  • 18. DATE FORMATTING Fri Sep 14 2018 15:47:26 GMT+0200 (Central European Summer Time) <strong>Fri Sep 14 2018 </strong> 15:47:26 GMT+0200 (Central European Summer Time)
  • 19. REACT NOW function DateTime() { return ( <Now render={now => ( <React.Fragment> <strong>{now.toDateString()} </strong> {' ' + now.toTimeString()} </React.Fragment> )} /> ); }
  • 20. “CHILDREN” IS JUST A SPECIAL PROPERTY
  • 21. REACT NOW class Now extends React.Component { state = {now: new Date()}; componentDidMount() { this._timer = setInterval( () => this.setState({now: new Date()}), 100, ); } componentWillUnmount() { clearInterval(this._timer); } render() { return this.props.render(this.state.now); } }
  • 22. REACT NOW class Now extends React.Component { state = {now: new Date()}; componentDidMount() { this._timer = setInterval( () => this.setState({now: new Date()}), 100, ); } componentWillUnmount() { clearInterval(this._timer); } render() { return this.props.children(this.state.now); } }
  • 23. function DateTime() { return ( <Now render={now => ( <React.Fragment> <strong>{now.toDateString()} </strong> {' ' + now.toTimeString()} </React.Fragment> )} /> ); } REACT NOW
  • 24. REACT NOW function DateTime() { return ( <Now> {now => ( <React.Fragment> <strong>{now.toDateString()} </strong> {' ' + now.toTimeString()} </React.Fragment> )} </Now> ); }
  • 25. STATE IS ANYTHING THAT CHANGES OVER TIME
  • 26. REACT TREE COMPONENT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT
  • 27. REACT TREE COMPONENT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTA
  • 28. REACT TREE COMPONENT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT COMPONENT COMPONENT COMPONENT COMPONENTBA
  • 29. REACT TREE COMPONENT COMPONENT COMPONENT PARENT COMPONENTCOMPONENTCOMPONENT COMPONENT COMPONENT COMPONENT COMPONENTBA
  • 30. REACT TREE COMPONENT COMPONENT COMPONENT PARENT COMPONENTCOMPONENTCOMPONENT COMPONENT C COMPONENT COMPONENTBA
  • 31. REACT TREE ROOT COMPONENT COMPONENT PARENT COMPONENTCOMPONENTCOMPONENT COMPONENT C COMPONENT COMPONENTBA
  • 32. REACT TREE ROOT COMPONENT COMPONENT PARENT COMPONENTCOMPONENTCOMPONENT COMPONENT C COMPONENT COMPONENTBA
  • 33. REACT TREE ROOT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT COMPONENT C COMPONENT COMPONENTBA External Store?
  • 34. REACT TREE ROOT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT COMPONENT C COMPONENT COMPONENTBA
  • 35. REACT TREE ROOT COMPONENT COMPONENT COMPONENT COMPONENTCOMPONENTCOMPONENT COMPONENT C COMPONENT COMPONENTBA
  • 36. REACT TREE ROOT SHARED PARENT COMPONENT COMPONENT COMPONENTCOMPONENT C COMPONENT COMPONENT COMPONENT COMPONENTBA
  • 37. REACT TREE ROOT SHARED PARENT COMPONENT COMPONENT COMPONENT C COMPONENT COMPONENT D EBA SHARED PARENT 2
  • 38. const Color = React.createContext('black'); function ThemedCircle() { return ( <Color.Consumer> {color => <Circle color={color} />} </Color.Consumer> ) } <React.Fragment> <Color.Provider value="blue"> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </Color.Provider> <Color.Provider value="red"> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </Color.Provider> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </React.Fragment>
  • 39. const Color = React.createContext('black'); function ThemedCircle() { return ( <Color.Consumer> {color => <Circle color={color} />} </Color.Consumer> ) } <React.Fragment> <Color.Provider value="blue"> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </Color.Provider> <Color.Provider value="red"> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </Color.Provider> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </React.Fragment>
  • 40. const Color = React.createContext('black'); function ThemedCircle() { return ( <Color.Consumer> {color => <Circle color={color} />} </Color.Consumer> ) } <React.Fragment> <Color.Provider value="blue"> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </Color.Provider> <Color.Provider value="red"> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </Color.Provider> <ThemedCircle /><ThemedCircle /><ThemedCircle /> </React.Fragment>
  • 41. const Toggle = React.createContext({on: false, onToggle: () => {}}); class ToggleProvider extends React.Component { state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))}; render() { return ( <Toggle.Provider value={this.state}> {this.props.children} </Toggle.Provider> ); } } function ToggleButton() { return ( <Toggle.Consumer> {({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>} </Toggle.Consumer> ) } <ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
  • 42. const Toggle = React.createContext({on: false, onToggle: () => {}}); class ToggleProvider extends React.Component { state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))}; render() { return ( <Toggle.Provider value={this.state}> {this.props.children} </Toggle.Provider> ); } } function ToggleButton() { return ( <Toggle.Consumer> {({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>} </Toggle.Consumer> ) } <ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
  • 43. const Toggle = React.createContext({on: false, onToggle: () => {}}); class ToggleProvider extends React.Component { state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))}; render() { return ( <Toggle.Provider value={this.state}> {this.props.children} </Toggle.Provider> ); } } function ToggleButton() { return ( <Toggle.Consumer> {({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>} </Toggle.Consumer> ) } <ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider>
  • 44. const Toggle = React.createContext({on: false, onToggle: () => {}}); class ToggleProvider extends React.Component { state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))}; render() { return ( <Toggle.Provider value={this.state}> {this.props.children} </Toggle.Provider> ); } } function ToggleButton() { return ( <Toggle.Consumer> {({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>} </Toggle.Consumer> ) } <ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider> OFF OFF OFF
  • 45. const Toggle = React.createContext({on: false, onToggle: () => {}}); class ToggleProvider extends React.Component { state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))}; render() { return ( <Toggle.Provider value={this.state}> {this.props.children} </Toggle.Provider> ); } } function ToggleButton() { return ( <Toggle.Consumer> {({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>} </Toggle.Consumer> ) } <ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider> ON ON ON
  • 46. const Toggle = React.createContext({on: false, onToggle: () => {}}); class ToggleProvider extends React.Component { state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))}; render() { return ( <Toggle.Provider value={this.state}> {this.props.children} </Toggle.Provider> ); } } function ToggleButton() { return ( <Toggle.Consumer> {({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>} </Toggle.Consumer> ) } <ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider> OFF OFF OFF
  • 47. const Toggle = React.createContext({on: false, onToggle: () => {}}); class ToggleProvider extends React.Component { state = {on: false, onToggle: () => this.setState(s => ({on: !s.on}))}; render() { return ( <Toggle.Provider value={this.state}> {this.props.children} </Toggle.Provider> ); } } function ToggleButton() { return ( <Toggle.Consumer> {({on, onToggle}) => <button onClick={onToggle}>{on ? 'on' : 'off'} </button>} </Toggle.Consumer> ) } <ToggleProvider><ToggleButton /><ToggleButton /><ToggleButton /> </ToggleProvider> ON ON ON
  • 48. SUMMARY ▸ Functions being first class values means we can use them as parameters to enable more flexible code re-use ▸ Using functions as parameters allows highly customisable shared components, complete with state and lifecycle hooks. ▸ React Context lets you share state across the tree of your application ▸ Context still uses the React tree. This means it works with server side rendering and you can safely use it in parts of your app, as well as using it as a whole app solution. @ForbesLindesay