When an Effect Runs
An effect that gets only a function runs after every render, even after one that had nothing to do with it. In this exercise, the app also has a text field for the name on your ticket. Each key you type changes the state, React renders again, and the effect sets the title again, although the likes didn't change. For a title, that's only a little extra work. But an effect that loads data or starts a timer mustn't run with every key.
That's why useEffect takes a second argument: an array of dependencies, the values the effect depends on. After each render, React compares them with their values in the previous render, and runs the effect only if one of them has changed:
useEffect(() => {
console.log("After every render");
});
useEffect(() => {
console.log("Once, when the component appears");
}, []);
useEffect(() => {
console.log("At the start, and whenever likes changes");
}, [likes]);- Without the array, the effect runs after every render.
- With an empty array,
[], there's nothing that could change, so it runs only after the first render, when the component appears on the page. - With
[likes], it runs after the first render, and then after each render in whichlikeshas changed. With[likes, name], when either of them changes.
Which dependencies does an effect need? Every state variable and every prop that it uses. An effect that sets the title from likes has the dependencies [likes]. If you leave one out, the effect doesn't run when that value changes, and the page keeps showing an old value.
Instructions
Type into the field and look at the console: The title effect ran after every key. Give the effect the dependencies [likes], so that it runs only when the number of likes changes. Then try it again: typing prints nothing, and a click on ♥ prints one line.
Add a second effect, with the dependencies [], that prints Welcome to Summer Sounds! in the console. Click and type: the welcome was printed only once, when the app appeared.