useState() function is a hook:
let state = useState(1)
React comes with a whole set of built-in hooks, including
useRef(). Unlike components, these hook functions are designed to be called manually. And since they’re just functions, they can accept arguments and return values.
But what do all these hooks actually do? Well, you’ve already seen what
useState() does — it makes it possible to use component state within function components. As for
useEffect() it makes it possible to use effects within component functions. We’ll cover what exactly this means in the next lesson, but for now, I want to focus on one part of this:
Hooks let you use special features within component functions.
This is important to understand, as it leads to the first rule of hooks:
Hooks must only be called within function components, or within custom hook functions.
One of the fun things about hooks is that you don’t have to think about how you’ll fit all that state into a single object. Instead, if you have multiple stateful values… you just call
useState() twice. Or three times, or however many times you need.
For example, this comes in handy when creating small forms. You just call
useState() once for each field.
Being able to call
useState() multiple times like this is super convenient, but it’s also a little odd. How does React know which
useState() call should return which value? That’s a great question! I’m assuming you want to know the answer, because I sure as hell did when I first saw hooks.
The secret is in the order in which you call
If you call
useState() twice within the same component, then React will keep track of two values:
To demonstrate this, let’s do a little experiment, and add a condition to this form. In particular, I’ve set up the form below to hide the state field when you pick a country other than the US. Probably because of tax or something.
Did you try changing the country? If not, go ahead — I’ll wait for you.
What happened? It went kaboom. React detected that the number of hooks has changed, and it threw an error. And when you think about this, it actually makes a lot of sense.
Imagine what would happen if there was a third call to
useState(). In this case, if the second call to
useState() suddenly disappeared, then the third
useState() would become the second
useState() — and then there’d be a glitch in the space-time continuum and then all hell would break loose. That’s why there’s a second rule of hooks:
Hooks must only be called at the Top Level.
What this means is that hooks cannot be called within:
This rule ensures that hooks will always be executed in the same order, and that each call to
useEffect(), and other order-dependent hooks behaves exactly as you’d expect it to. And that’s all well and good, but it does raise the question:
If you can’t use hooks inside conditions, then how do you implement conditional logic in hook-based components?
I’m going to let you try and figure this one out for yourself, as an exercise:
Your task is to fix the above example so that it works as expected, with the state hidden for non-US countries.
Once you’re done, you can check the solution above — and view my explanation below.
While you must call each hook on each render, you don’t have to actually use the returned state!
It’s perfectly acceptable to call hooks like
useState() and then conditionally ignore the output in some situations. So if you need conditional logic — just place the conditions after the hooks. For an example, check the solution for the above demo.
Okay, you’re getting the hang of this — so let’s take a look at one more hook while you’re on a roll.