Hello and welcome to your first lesson! I'm excited to start this journey with you to deepen your understanding of React Native.
Given your background as a CTO and your experience with building apps, you're already familiar with the 'what' of React. This course is designed to focus on the 'why' and the 'how'—the foundational, under-the-hood mechanics that are crucial for building truly high-performance applications.
In this first lesson, we'll begin our "React Fundamentals Refresher" module by tackling a core concept: the component lifecycle. We'll explore how React functional components are born (mount), how they live and change (update), and how they are removed (unmount), all within the context of the Hooks API. Understanding this sequence is the first step toward diagnosing and optimizing rendering performance.
The Three Phases of a Component's Life
At a high level, every interaction with a React component, from its first appearance to its last update, can be broken down into three phases: Trigger, Render, and Commit.
To get a solid grasp of this model, please read the following section from an article that explains these phases clearly.
React Component Lifecycle: A Deep Dive for Beginners
This reading, from 'React Component Lifecycle: A Deep Dive for Beginners' by Zach Gollwitzer, provides an excellent conceptual framework for the component lifecycle.
Please read the section titled 'Chapter 2: A Component's Lifecycle (trigger, render, commit)'. Focus on what initiates each phase and what React does during the 'Render' and 'Commit' stages.
To summarize the key ideas from the reading:
- Trigger: A render is triggered either by the component mounting for the first time or by a change in its state or props.
- Render: In this phase, React calls your component function. It's a "pure" calculation step where React determines what the UI should look like. Nothing has been changed on the screen yet. The result of this phase is a new "snapshot" of the UI, often called the Virtual DOM.
- Commit: React takes the snapshot from the render phase, compares it to what's currently on the screen (the DOM), and applies only the necessary changes. This is the phase where the user actually sees the update.
This Trigger -> Render -> Commit sequence is the fundamental process behind every visual change in a React application.
The Lifecycle in Action: Mount, Update, and Unmount
Now, let's map this conceptual model onto the three concrete stages of a component's life: mounting, updating, and unmounting.
The following video provides a fantastic visual walkthrough of these stages. We'll watch it in three parts.
1. Mounting: The Initial Render
The first time a component is displayed, it goes through the mount phase. This is its very first Trigger -> Render -> Commit cycle.
The React Lifecycle: Simply Explained!
Let's watch the first part of 'The React Lifecycle: Simply Explained!' to see what happens when a component mounts.
Watch from 06:27 to 11:42. Pay close attention to the sequence: the function body runs, values are initialized, the DOM is painted, and then side effects (useEffect) are scheduled.
During the mount phase:
- React runs the code in your component function from top to bottom.
useStateis called, and its initial value is set.- React renders the JSX and commits it to the DOM, making it visible (this is often called "painting the screen").
- Finally, after the component is visible, React runs the code inside
useEffecthooks that have an empty dependency array ([]) or no dependency array at all.
2. Updating: Responding to Change
After mounting, a component can update many times in response to changes in its state or props. Each update is a new Trigger -> Render -> Commit cycle.
The React Lifecycle: Simply Explained!
Now, let's see what happens during an update.
Watch from 11:42 to 17:29. Notice that the entire function body runs again, and how React efficiently updates the DOM.
During an update:
- A state change (e.g., via a
setCounterfunction) or a prop change triggers a new render. - React runs your component function again to calculate the new UI snapshot.
useStatenow returns the current state value, not the initial one. - React compares the new snapshot to the old one and commits only the differences to the DOM.
- If you have a
useEffecthook with dependencies, its cleanup function from the previous render runs first. Then, if any dependencies have changed, the effect function runs again after the commit.
3. Unmounting: Cleaning Up
When a component is no longer needed (e.g., the user navigates to a different screen), it enters the unmount phase. This is its final moment.
The React Lifecycle: Simply Explained!
Finally, let's look at the unmount phase.
Watch from 17:55 to 23:06. The key event here is the execution of the useEffect cleanup function.
During unmounting:
- React removes the component from the DOM.
- The cleanup function returned from
useEffectis executed. This is critical for preventing memory leaks by stopping timers, unsubscribing from data sources, or removing event listeners.
Here is a diagram that visually summarizes how hooks fit into these lifecycle phases.
Under the Hood: How Do Hooks Actually Work?
You expressed a keen interest in understanding the mechanics, so let's dig into a question that puzzles many developers: How does React keep track of a useState value between renders? The answer explains why there are strict rules for using hooks.
The core idea is that for each component, React maintains an internal array of hooks. It relies on the call order of your hooks being identical on every single render to retrieve the correct state for each hook.
This next video does a brilliant job of explaining this by reverse-engineering a simplified useState.
How Do React Hooks Actually Work? React.js Deep Dive #3
This clip from 'How Do React Hooks Actually Work?' demystifies useState by showing you how it could be implemented with a simple array and an index.
Watch from 00:45 to 06:33. The key insight is understanding that state is stored in an array outside the component and accessed by an index that increments with each hook call. This is why you can't call hooks inside conditions or loops.
Because hooks are just array entries, if you were to call useState inside a conditional, you could change the number of hooks and their order between renders. This would cause React to retrieve the wrong state from its internal array, leading to unpredictable bugs.
- On first render:
[stateA, stateB] - On second render (if a condition is false):
[stateB]-> Now calling the second hook actually retrieves the value ofstateA!
This principle of stable call order is the most important rule of hooks.
For a deeper textual explanation with code you can analyze, this article reinforces the same concepts.
How React Hooks Work Under the Hood: Recreating useState ...
This article, 'How React Hooks Work Under the Hood', provides a similar explanation with code snippets, which may appeal to your programming background.
Read the sections 'How Hooks Are Added and Updated' and 'Simplified Implementation of useState'. This will solidify your understanding of the internal hookStates array and index mechanism.
Key Takeaways
- A component's life consists of three main stages: Mounting (initial creation), Updating (re-rendering due to state/prop changes), and Unmounting (removal and cleanup).
- Each mount or update follows a Trigger -> Render -> Commit sequence. The 'Render' phase is a pure calculation, while the 'Commit' phase is when the DOM is physically changed.
- Side effects, managed by
useEffect, run after the component has rendered and been committed to the screen. - The cleanup function from
useEffectis crucial. It runs before the component unmounts and before the effect runs again on a subsequent update. - React tracks hook data using an internal array. The stable call order of hooks on every render is essential for React to function correctly.
This lesson provided the "big picture" of the component lifecycle. With this foundation, you're now equipped to understand not just what hooks do, but when and why they do it.
In our next lesson, we will dive deeper into the most common hook, useState, and its more powerful alternative, useReducer, to manage component state of varying complexity.