React v16.8
React v16.8
The One With Hooks
Road Map
-
What are Hooks?
-
Why?
-
Initial Concerns
-
Examples
What are Hooks?
-
Class Features in a Function
-
State in a Function
-
Reusable Logic
-
New Direction of React
Why?
-
What's wrong with classes?
-
Code co-location
-
One standard for components
Hopefully: Simplicity
Initial Concerns
-
Backwards compatible
-
Only affects functional components
-
No Reason to change old code
Examples
-
useState
-
useEffect
-
useReducer
useState()
Class Component
Functional Component
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
handleClick = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={this.handleClick}>
Click me
</button>
</div>
);
}
}const Example = () => {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>
Click me
</button>
</div>
);
};useState()
Multiple State Variables
function ExampleWithManyStates() {
// Declare multiple state variables!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);function handleOrangeClick() {
// Similar to this.setState({ fruit: 'orange' })
setFruit('orange');
}Note: State can still be an object, but updating is not a merge, it is a replacement.
useEffect()
useEffect(() => {
// Do something when I render
return () => {
// do this when I unrender/unmount
}
}, [ // only run when this list has changed ]);useEffect()
Class Component
Functional Component
class Example extends React.Component {
constructor(props) {
...
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate() {
document.title = `You clicked ${this.state.count} times`;
}
handleClick = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
...
}
}const Example = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
const handleClick = () => {
setCount(count + 1);
}
return (
...
);
};cDM and cDU
useEffect()
Class Component
Functional Component
class Example extends React.Component {
constructor(props) {
...
}
componentDidMount() {
document.title = `You clicked ${this.state.count} times`;
}
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
document.title = `You clicked ${this.state.count} times`;
}
}
handleClick = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
...
}
}const Example = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
const handleClick = () => {
setCount(count + 1);
}
return (
...
);
};Conditional cDU
useEffect()
Class Component
Functional Component
class Example extends React.Component {
constructor(props) {
...
}
componentDidMount() {
const savedClicks = fetch(clicks);
this.setState({
count: savedClicks
});
}
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
document.title = `You clicked ${this.state.count} times`;
}
}
handleClick = () => {
this.setState({ count: this.state.count + 1 });
}
render() {
...
}
}const Example = () => {
const [count, setCount] = useState(0);
useEffect(() => {
const savedClicks = fetch(clicks);
setCount(savedClicks);
}, []);
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]);
const handleClick = () => {
setCount(count + 1);
}
return (
...
);
};Data Fetching
useReducer()
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}
function Counter({initialState}) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<>
Count: {state.count}
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</>
);
}Additional Reading
-
useReducer()
-
useContext()
-
Custom Hooks
-
reactjs.org - Great docs covering Hooks
-
overreacted.io - Dan Abramov's Blog
-
React Today and Tomorrow - Video introducing Hooks
Additional Topics
React v16.8
By Michael Klosterboer
React v16.8
Github with examples: https://github.com/mklosterboer/hooks-demo CodeSandBox: https://codesandbox.io/s/github/mklosterboer/hooks-demo
- 51