Your First Effect
So far, your components have done one thing: they return what the page should look like. React calls the component, takes its JSX and puts it on the page. That's rendering, and it happens again every time the component's state changes.
But some things an app does aren't JSX: it changes the title in the browser's tab, starts a timer, loads data from a server or saves something in localStorage. Those things happen outside React, and React wants rendering to do nothing but work out what the page looks like. So they go into an effect: code that React runs after it has rendered the component and the page shows the result.
You write an effect with useEffect. It's a hook, like useState: a function of React whose name starts with use, which you call at the top of a component. You give it a function, and React calls that function after the component has rendered:
import { useEffect, useState } from "react";
export default function App() {
const [tickets, setTickets] = useState(1);
useEffect(() => {
document.title = `Tickets: ${tickets}`;
});
return (
<button onClick={() => setTickets((tickets) => tickets + 1)}>
Tickets: {tickets}
</button>
);
}document.title is the text in the browser's tab, which <title> in index.html sets at first. Here's what happens:
- React renders
App, and the page shows the button withTickets: 1. - Then React runs the effect, and the tab says
Tickets: 1too. - A click changes the state. React renders
Appagain with 2, and after that, it runs the effect again, which sets the new title.
The effect always sees the values of the render it comes after, so the title and the button agree.
The preview has no tab of its own, so you won't see the title there. To see when the effect runs, print something in it with console.log(): the console under the page shows a line each time.
Typical mistakes:
- Forgetting to import
useEffect: the page stays empty, and the console saysReferenceError: useEffect is not defined. - Changing the title right in the component, outside an effect. It may seem to work, but it happens while React is still working out the page, before the page shows anything. Changes outside React belong in an effect.
Instructions
Add an effect that sets the tab's title to Likes: 0 | Summer Sounds, with the number of likes in place of the 0. Don't forget to import useEffect next to useState.
Print the title in the console too: in the effect, under the line that sets it, add console.log(document.title);. Click the button a few times and look at the console: after each click, the effect runs again and prints the new title.