The One With Hooks
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>
);
};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(() => {
// Do something when I render
return () => {
// do this when I unrender/unmount
}
}, [ // only run when this list has changed ]);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
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
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
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>
</>
);
}