React 16.8.0 with Hooks was released today. A big deal. Executive summary; components as functions is all the rage now.
What used to be this:
class MyComponent extends React.Component {
...
componentDidMount() {
...
}
componentDidUpdate() {
...
}
render() { STUFF }
}
...is now this:
function MyComponent() {
...
React.useEffect(() => {
...
})
return STUFF
}
Inside the useEffect
"side-effect callback" you can actually update state. But if you do, and this is no different that old React.Component.componentDidUpdate
, it will re-run the side-effect callback. Here's a simple way to cause an infinite recursion:
// DON'T DO THIS
function MyComponent() {
const [counter, setCounter] = React.useState(0);
React.useEffect(() => {
setCounter(counter + 1);
})
return <p>Forever!</p>
}
The trick is to pass a second argument to React.useEffect
that is a list of states to exclusively run on.
Here's how to fix the example above:
function MyComponent() {
const [counter, setCounter] = React.useState(0);
const [times, setTimes] = React.useState(0);
React.useEffect(
() => {
if (times % 3 === 0) {
setCounter(counter + 1);
}
},
[times] // <--- THIS RIGHT HERE IS THE KEY!
);
return (
<div>
<p>
Divisible by 3: {counter}
<br />
Times: {times}
</p>
<button type="button" onClick={e => setTimes(times + 1)}>
+1
</button>
</div>
);
}
You can see it in this demo.
Note, this isn't just about avoiding infinite recursion. It can also be used to fit your business logic and/or an optimization to avoid executing the effect too often.
Comments
...this is the entire article?