React
• Data Caching
• Concurrent Rendering
• Hooks
• Code Splitting
Code Splitting
Developer, Consultant, Trainer

CEO @ 500Tech
Me
Adam Klein
Follow Me
@adamklein500
Code Splitting
Code Splitting
Lazy + Suspensereact-loadable
import React from 'react';
import OtherComponent from './OtherComponent';
const MyComponent = props => (
<div>
<OtherComponent />
</div>
);
import React from 'react';
import OtherComponent from './OtherComponent';
const MyComponent = props => (
<div>
<OtherComponent />
</div>
);
import React from 'react';
import OtherComponent from './OtherComponent';
const MyComponent = props => (
<div>
<OtherComponent />
</div>
);
const OtherComponent =
React.lazy(() => import('./OtherComponent'));
const OtherComponent =
React.lazy(() => import('./OtherComponent'));
const OtherComponent =
React.lazy(() => import('./OtherComponent'));
const MyComponent = (props) =>
<div>
<Suspense fallback={<div>Loading..</div>}>
<OtherComponent />
</Suspense>
</div>
const MyComponent = (props) =>
<div>
<Suspense fallback={<div>Loading..</div>}>
<OtherComponent />
</Suspense>
</div>
<Suspense fallback={<div>Loading..</div>}>
<div>
<OtherComponent />
</div>
<OtherComponent3 />
<OtherComponent2 />
</Suspense>
Data Fetcher AKA Cache
Stuttering Transition
Smooth Transition
Concurrent Rendering
AKA Async Rendering
AKA Time Slicing
React
Hooks
22 Redux Hook
Libraries
redux-hooks
react-hooks-redux
react-hook-redux
redux-react-hook
redux-react-hooks
react-redux-hooks
react-redux-hook
hook-redux
redux-hook
react-use-redux
use-store
react-hooks-easy-redux
use-redux
react-usemiddleware
react-use-dux
react-redux-peach
hux
rehux
redux-hooker
rehooker
More verbose
Binding
Harder to prepack
Functional components are limited
Code Reuse
Classes
Hard to debug / read
Prop clashing
Wrapper hell
HOC / renderProps
Maintaining an execution context without ‘this’
The Solution - Hooks
class Counter extends React.Component {
state = {
count: 1
};
render() {
return (
<button
onClick={() => this.setState({ count: this.state.count + 1 })}>
{ this.state.count }
</button>
);
}
}
State - Classes
class Counter extends React.Component {
state = {
count: 1
};
render() {
return (
<button
onClick={() => this.setState({ count: this.state.count + 1 })}>
{ this.state.count }
</button>
);
}
}
State - Classes
class Counter extends React.Component {
state = {
count: 1
};
render() {
return (
<button
onClick={() => this.setState({ count: this.state.count + 1 })}>
{ this.state.count }
</button>
);
}
}
State - Classes
const Counter = () => {
const [count, setCount] = useState(1);
return (
<button onClick={() => setCount(count + 1)}>
{ count }
</button>;
)
}
State - Hooks
const Counter = () => {
const [count, setCount] = useState(1);
return (
<button onClick={() => setCount(count + 1)}>
{ count }
</button>;
)
}
State - Hooks
const Counter = () => {
const [count, setCount] = useState(1);
return (
<button onClick={() => setCount(count + 1)}>
{ count }
</button>;
)
}
State - Hooks
const Counter = () => {
const [count, setCount] = useState(1);
return (
<button onClick={() => setCount(count + 1)}>
{ count }
</button>;
)
}
State - Hooks
const Counter = () => {
const [count, setCount] = useState(1);
const [value, setValue] = useState(‘’);
return (
<button
onClick={() => setCount(count + 1)}>{ count }
</button>;
)
}
State - Hooks
const Counter = () => {
const [count, setCount] = useState(1);
const [value, setValue] = useState(‘’);
return (
<button
onClick={() => setCount(count + 1)}>{ count }
</button>;
)
}
State - Hooks
Side Effects - Classes
componentDidMount() {
console.log("effect");
}
componentDidUpdate() {
console.log("effect");
}
useEffect(() => {
console.log("effect");
});
Side Effects - Hooks
useEffect(() => {
api.fetchData(id);
}, [id]);
On Change
Cleanup Function
useEffect(() => {
window.addEventListener(…);
return () => window.removeEventListener(…);
});
Separation of Concerns
useEffect(() => {
// listen to window resize
}, []);
useEffect(() => {
// fetch data from API
}, [id]);
Custom Hooks
= Reusable Code
function useCurrentWidth() {
const [width, setWidth] = useState(
() => document.body.clientWidth
);
const resize = () => {
setWidth(document.body.clientWidth);
}
useEffect(() => {
window.addEventListener('resize', resize);
return () => window.removeEventListener('resize', resize);
}, []);
return width;
}
function useCurrentWidth() {
const [width, setWidth] = useState(
() => document.body.clientWidth
);
const resize = () => {
setWidth(document.body.clientWidth);
}
useEffect(() => {
window.addEventListener('resize', resize);
return () => window.removeEventListener('resize', resize);
}, []);
return width;
}
function useCurrentWidth() {
const [width, setWidth] = useState(
() => document.body.clientWidth
);
const resize = () => {
setWidth(document.body.clientWidth);
}
useEffect(() => {
window.addEventListener('resize', resize);
return () => window.removeEventListener('resize', resize);
}, []);
return width;
}
function useCurrentWidth() {
const [width, setWidth] = useState(
() => document.body.clientWidth
);
const resize = () => {
setWidth(document.body.clientWidth);
}
useEffect(() => {
window.addEventListener('resize', resize);
return () => window.removeEventListener('resize', resize);
}, []);
return width;
}
const MyComp = () => {
const width = useCurrentWidth();
return <span>{ width }</span>;
}
const MyComp = () => {
const user = useCurrentUser();
return <span>{ user.name }</span>;
}
Other Hooks
•useContext
•useRef
•useMemo
•useCallback
•useReducer
•useImperativeHandle
•useLayoutEffect
•useDebugValue
How Does React Know?
const [name, setName] = useState(‘’);
const [role, setRole] = useState(‘’);
Component1
State
Count1
Count2
Component2
State
Cell 1
Cell 2
How Does React Know?
Component1
State
Current Component
Count1
Count2
Current Cell
Component2
State
Cell 1
Cell 2
Setting context before render
Component1
State
Current Cell
Count1
Count2
const [count, setCount] = useState(1);
const [count2, setCount2] = useState(1);
Current Component
const [count, setCount] = useState(1);
const [count2, setCount2] = useState(1);
Component1
State
Current Cell
Count1
Count2
Current Component
const [count, setCount] = useState(1);
const [count2, setCount2] = useState(1);
Component1
State
Current Cell
Count1
Count2
Current Component
Conditionals
Component1
State
Current Cell
Count1
Count2
const [count, setCount] = useState(1);
if (count === 0) {
const [count2, setCount2] = useState(1);
}
const [count3, setCount3] = useState(1); Count3
Component1
State
Current Cell
Count1
Count2
const [count, setCount] = useState(1);
if (count === 0) {
const [count2, setCount2] = useState(1);
}
const [count3, setCount3] = useState(1); Count3
Conditionals
Component1
State
Current Cell
Count1
Count2
Count3
const [count, setCount] = useState(1);
if (count === 0) {
const [count2, setCount2] = useState(1);
}
const [count3, setCount3] = useState(1);
Conditionals
Component1
State
Current Cell
Count1
Count2
const [count, setCount] = useState(1);
if (count === 0) {
const [count2, setCount2] = useState(1);
}
const [count3, setCount3] = useState(1); Count3
Conditionals
Rules of Hooks
•Must be used in the same order
•No conditionals, no loops
•Must be called at top level
•Must be called from a functional component
 eslint-plugin-react-hooks
Rules of Hooks
–Me. Right Now
“Start using hooks. Today”
Will classes be supported?
Is this a breaking change?
Q&A
State of Hooks
Works
State of Hooks
Works
Used inside Facebook
State of Hooks
Works
Used inside Facebook
Server-side rendering
State of Hooks
Works
Used inside Facebook
Server-side rendering
React Native
State of Hooks
Works
Used inside Facebook
Server-side rendering
React Native
Tests
State of Hooks
Works
Used inside Facebook
Server-side rendering
React Native
Tests
eco-system
State of Hooks
Works
Used inside Facebook
Server-side rendering
React Native
Tests
eco-system
DevTools
React Roadmap
• Suspense for Code Splitting - Already
Shipped 16.6 with 
• React Hooks - ~Q1 2019
• Concurrent Mode - ~Q2 2019
• Suspense for Data Fetching - ~mid
2019
• All minor releases
@adamklein500

@_500tech

slideshare.net/500tech

500tech.com/articles
Thank You

React Back to the Future