React Hooks and Their Rules | Lecture 157 | React.JS 🔥
Summary
TLDRReact hooks are special functions that allow developers to tap into React's internal mechanisms, such as managing state and side effects. They expose internal React functionalities and are essential for creating and accessing state in functional components. Hooks must be called in a consistent order at the top level of the component and can only be used within React functions or custom hooks. This structure ensures that React can correctly track and manage the hooks, avoiding confusion and maintaining the integrity of the application's state across renders.
Takeaways
- 📌 React hooks are special functions that allow interaction with React's internal mechanisms.
- 🔑 Hooks expose internal React functionality like state management and side effect registration.
- 🌳 The fiber tree is an internal data structure in React that hooks are linked to.
- 📈 Hooks start with 'use' to differentiate them from regular functions and for ease of identification.
- 🛠 Custom hooks enable developers to reuse non-visual logic across different components.
- 🎯 There are nearly 20 built-in hooks in React, with useState and useEffect being the most commonly used.
- 📋 Hooks must be called at the top level of your code, avoiding conditionals, loops, or nested functions.
- 🔄 Hooks rely on call order to maintain a linked list, which is crucial for React's tracking and management.
- 🚫 Violating the call order can lead to broken references and render issues within the fiber tree.
- 📏 The first rule of hooks ensures that the linked list of hooks remains consistent across renders.
- 🧐 Understanding the 'why' behind React hooks and their rules helps developers write more effective and maintainable code.
Q & A
What are React hooks?
-React hooks are special functions built into React that allow developers to hook into some of React's internal mechanisms, such as creating and accessing state or registering side effects.
What is the fiber tree in React?
-The fiber tree is an internal data structure within React that represents the state of the UI. It is not directly accessible to developers but is used by hooks like `useState` and `useEffect` to manage state and side effects.
Why do all hooks start with the word 'use'?
-All hooks start with the word 'use' to make it easy for developers and React to distinguish hooks from other regular functions.
What are custom hooks in React?
-Custom hooks are developer-created functions that start with 'use' and allow for the reuse of non-visual logic, such as state management and side effects, across different components.
How many built-in hooks does React come with?
-React comes with almost 20 built-in hooks, including widely used ones like `useState`, `useEffect`, `useReducer`, and `useContext`.
What are the two simple rules that must be followed for hooks to work as intended?
-The two rules are: 1) Hooks can only be called at the top level in a function, not inside loops, conditions, or nested functions, and 2) Hooks can only be called from React functions, such as function components or custom hooks, not from regular functions or class components.
Why is it important to call hooks in the same order on every render?
-Calling hooks in the same order ensures that React can correctly associate each hook with its value and maintain the integrity of the linked list of hooks. This is crucial for React to function properly and track state and side effects across renders.
What happens if you break the first rule of hooks by using them conditionally?
-If you use hooks conditionally, the linked list of hooks can get broken between renders, causing React to become confused and unable to correctly manage state and side effects, which can lead to unexpected behavior in the application.
How are hooks enforced to follow the rules?
-React's ESLint rules automatically enforce the hook rules, preventing developers from breaking them and ensuring that hooks are used correctly within the code.
What is the advantage of using a linked list for managing hooks?
-A linked list allows React to associate each hook with its value based on the call order, which simplifies the process for developers as they don't have to manually assign names to each hook, reducing the potential for errors.
Why was the introduction of hooks a significant advancement for React?
-The introduction of hooks allowed function-based components to have their own state and run side effects, which was previously only possible with class-based components. This made React more flexible and popular by simplifying the way state and lifecycle logic are managed.
Outlines
📚 Introduction to React Hooks
This paragraph introduces the concept of React hooks, explaining that they are special functions built into React that allow developers to access and manipulate internal React mechanisms. It emphasizes that hooks are essentially APIs that expose certain functionalities such as state management and side effects. The paragraph also highlights the ability to create custom hooks for reusing non-visual logic and contrasts the new hooks system with the older class-based components, showcasing the benefits of using hooks in functional components.
🔄 The Order of Hooks
This section delves into the importance of calling hooks in a consistent order during every render. It explains that hooks rely on a linked list structure within React's fiber tree, where each hook is linked to the next based on the order of their calls. The paragraph clarifies that conditional or nested hook calls can disrupt this list, leading to issues with state management and side effects. It emphasizes the necessity of following the first rule of hooks to ensure that hooks are always called in the same order at the top level of the component.
🔑 The Simplicity of Call Order
The final paragraph discusses the rationale behind using the call order to associate hooks with their values. It points out that this approach simplifies the process for developers by eliminating the need to manually name hooks, thus avoiding potential problems. The summary underscores the convenience and efficiency of this system, which is central to the functionality of React hooks and the underlying virtual DOM and fiber tree structures.
Mindmap
Keywords
💡React Hooks
💡Fiber Tree
💡useState
💡useEffect
💡Custom Hooks
💡Rules of Hooks
💡Linked List of Hooks
💡Component Lifecycle
💡Virtual DOM
💡Re-rendering
💡ESLint
Highlights
React hooks are special functions built into React that allow us to hook into some of React's internal mechanisms.
Hooks are APIs that expose internal React functionality, such as creating and accessing state from the fiber tree or registering side effects.
The fiber tree is a part of React that is usually not accessible, but hooks like useState and useEffect allow us to interact with it.
Hooks enable manual selection of in-store DOM nodes access context and many other things.
All hooks start with the word 'use' to distinguish them from other regular functions.
Custom hooks can be created, starting with 'use', and they allow for reusing non-visual logic in React applications.
Prior to hooks, components needed to be based on JavaScript classes to have state and access to the component life cycle.
With hooks, function-based components can have their own state and run side effects, which was a significant advancement for React.
React comes with almost 20 built-in hooks, including useState, useEffect, useReducer, and useContext.
Some hooks are less used but still important, like useRef, useCallback, and useMemo.
Hooks must be called at the top level in a component, not inside conditionals, loops, or nested functions.
Hooks must be called in the exact same order on every render to maintain the integrity of the fiber tree and associated hooks.
React's ESLint rules enforce the rules of hooks, preventing developers from breaking them inadvertently.
The linked list of hooks is crucial for React to correctly track and associate each hook with its value based on the call order.
The order of hook calls uniquely identifies each hook, eliminating the need for manual naming and associated complexities.
Understanding the internals of React hooks provides insights into the framework's workings and can help developers write more efficient code.
Transcripts
We have already used a few different React hooks
at this point of the course, but we have never
really learned what a React hook actually is
and how they work.
And so let's now do that in this lecture.
So React hooks are essentially special functions
that are built into React and which allow us
to basically hook into some of React's internal mechanisms,
or in other words, hooks are basically APIs
that expose some internal React functionality,
such as creating and accessing state from the fiber tree,
or registering side effects in the fiber tree, as well.
So again, the fiber tree is somewhere deep inside React,
and usually not accessible to us at all.
But using the useState or the useEffect hook,
we can essentially hook into that internal mechanism.
Now, hooks also allow us to manually select
in-store dom notes access context,
and many, many other things.
Now, what all hooks have in common is that they all start
with the word "use," in order to make it easy for us,
and for React to distinguish hooks
from other regular functions.
And in fact, we can even create our own so-called
custom hooks, which will also start with the word "use."
And this is actually one of the greatest things
about hooks in general, because custom hooks
give us developers an easy way of reusing non-visual logic.
So logic that is not about the UI.
Now, you might be aware of this or not,
but there was a time when we had to use components based
on JavaScript classes if we wanted to give components state
and access to the component life cycle.
However, this came with a few problems,
which led the React team to introduce hooks.
And so now with hooks, our components based
on functions can have their own state,
and also run side effects.
And so this was a huge step forward for React,
and made it even more popular than it already was.
Now we only used two hooks so far,
but React actually comes with almost 20 built-in hooks.
And so let's get a quick overview of them here.
So useState and useEffect are, of course,
some of the most important hooks,
and therefore the most used ones,
along with useReducer and useContext,
that we will actually study pretty soon.
Then we have this huge list of some less used hooks,
but where some of them are actually still quite important,
like useRef, useCallback and useMemo.
So some of these are actually worth learning,
but others are a bit more obscure, I would say.
And so they are not part of the curriculum of this course.
And finally, there are a few hooks that are intended
only for library authors.
And so of course, we will also not bother looking at those.
Now, in order for hooks to actually work as intended,
there are two very simple rules of hooks
that we must follow.
The first rule is that hooks can only be called
at the top level in practice.
This means that we cannot call hooks inside conditionals,
like if statements, and also not inside loops
or functions nested inside the component.
We can also not call hooks after an early return,
because that's also similar to a condition.
But why?
Why is this such an important rule?
Well, it's because hooks only work if they are always called
in the exact same order, which can only be insured
if we only call them at the top level.
And we will look at this in more detail in the next slide.
And now the second rule is actually a bit simpler.
All it says is that hooks can only be called
from React functions.
In practice, this means that hooks can only be called
from function components or from custom hooks,
but not from regular functions or even class components.
Now, the great news is that you actually won't have to worry
about these rules at all if you're using a linter,
because these two rules are automatically enforced
by React's ESLint rules.
So you really won't be allowed to break these rules,
even if you try, like we will in the next video.
So if you want, you can actually just forget about the rules
and finish the video right here.
But if you're curious about the deeper reason
why React needs rule number one, then let's move on
to the final slide of this lecture.
So let's now try to answer the question of
why do hooks need to be called in the same order
on every render?
And let's actually start from the very beginning,
based on all the knowledge that we already have
at this point.
So remember that whenever an application is rendered,
React creates a tree of React elements,
also called the virtual dom.
On the initial render, React also builds a fiber tree
out of the virtual dom, where each element is a fiber.
Now, each of these fibers contains a lot of stuff,
like the received props, a list of work,
and crucially for us, a linked list of all the hooks
that were used in the component instance.
So to understand how hooks work behind the scenes,
let's build ourselves a linked list of used hooks,
based on this hypothetical code example.
And I say hypothetical,
because this code actually doesn't work.
And can you spot why that is?
That's right.
This code actually violates the first rule of hooks,
because it conditionally defines state here.
But by breaking this rule, we will understand why hooks rely
on the order in which they were called.
And speaking of this order, our list will be built based
on the call order of the used hooks.
So first this useState call, then another useState call.
And then finally this useEffect call.
So this is our list of hooks
but it's not a linked list yet.
But what does linked actually mean?
Well, it means that the first list element
contains a reference to the second element,
which in turn, has a link to the third list element.
So all the list elements are linked together,
which is actually a common data structure
in computer science.
But anyway, moving back to our code example,
let's now imagine that a re-render happened,
because state A was updated from 23 to 7,
but this now creates a huge problem.
Notice how state B was only created initially
because the condition A equaled 23 was true, right?
However, after this re-render, the condition is now false,
which means that this useState hook would not be called.
And so state B would then no longer exist
in this linked list of hooks after the render.
But what the problem with that, you might ask?
Well, the problem is that the first hook is still pointing
to the original second hook, so to state B,
but that link is now broken.
So state A is now linking to a hook that no longer exists,
and nothing is pointing to the effect of Z,
meaning that a linked list has been destroyed.
It works this way because fibers
are not recreated on every render.
And so this list is also not recreated.
So if one of the hooks just disappears from the list,
then the order of the list will get completely broken.
So in conclusion, if we conditionally use the hook,
like we did here, that will completely mess up the list
of hooks between renders, which will leave React confused
and unable to correctly track all the hooks that were used.
And so this is the reason why hooks need to be called
in the same order on every single render.
And the only way in which we can assure that
is by only calling hooks at the top level,
which is exactly what the first rule of hooks says.
So following this rule, the code and the list of hooks
would look just like this,
so without any conditionals in the code,
and with the list of hooks always in the same order.
Now of course, this opens up the question
of why even bother having this linked list,
if it requires this strange rule to exist.
Well, the big reason is that a linked list,
which relies on the hook call order,
is the simplest way to associate each hook with its value.
So basically, the order in which the hook is called
uniquely identifies the hook.
For example, React knows that hook number one
has a state of 23, and that hook number two
has a state of empty string.
So the value is associated with the call order.
And this is very convenient because by using the call order,
we developers don't have to manually assign names
to each hook, which would create multiple problems
that we don't need to get into at this point.
Alright, so I hope that you didn't mind
yet another deep dive into some of React's internals.
I personally find these really interesting and fascinating,
which is why I keep getting excited
to share this stuff with you.
But now it's time to get back into writing some code.
5.0 / 5 (0 votes)