Mounting Phase
Mounting Phase
The mounting phase happens when a component is first rendered to the DOM.
Functional Components
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
// Runs after first render (like componentDidMount)
useEffect(() => {
console.log("Component mounted");
fetchUser(userId).then(setUser);
// Cleanup (like componentWillUnmount)
return () => {
console.log("Component will unmount");
};
}, []); // Empty array = runs once on mount
// Runs after every render (no dependency array)
useEffect(() => {
console.log("Component rendered");
});
if (!user) return <div>Loading...</div>;
return <div>{user.name}</div>;
}
What Happens on Mount
- Component function is called
- JSX is rendered to Virtual DOM
- Virtual DOM is committed to real DOM
- Effects run (useEffect with [])
Common Mount Tasks
- Fetch initial data
- Set up subscriptions
- Add event listeners
- Initialize third-party libraries
function Map({ center }) {
const mapRef = useRef(null);
useEffect(() => {
// Initialize map on mount
const map = new google.maps.Map(mapRef.current, {
center,
zoom: 12
});
// Cleanup on unmount
return () => {
map.destroy();
};
}, []);
return <div ref={mapRef} style={{ height: "400px" }} />;
}
Updating Phase
Updating Phase
The updating phase happens when props or state change.
Functional Components
function Counter({ initialCount }) {
const [count, setCount] = useState(initialCount);
// Runs after every render when dependencies change
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]); // Re-runs when count changes
// Runs when initialCount changes
useEffect(() => {
setCount(initialCount);
}, [initialCount]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
What Triggers Updates
- State changes (useState, useReducer)
- Prop changes
- Parent re-renders
- Context changes
Update Flow
- New props/state received
- Component re-renders
- Virtual DOM is diffed
- Only changed parts are updated in real DOM
- Effects run if dependencies changed
Conditional Effects
function DataComponent({ id, type }) {
const [data, setData] = useState(null);
// Only runs when id changes
useEffect(() => {
fetchData(id).then(setData);
}, [id]);
// Only runs when type changes
useEffect(() => {
logTypeChange(type);
}, [type]);
return <div>{data ? JSON.stringify(data) : "Loading..."}</div>;
}
Unmounting Phase
Unmounting Phase
The unmounting phase happens when a component is removed from the DOM.
Functional Components
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount((prev) => prev + 1);
}, 1000);
// Cleanup runs on unmount
return () => {
clearInterval(interval);
console.log("Timer cleaned up");
};
}, []);
return <p>Count: {count}</p>;
}
What Happens on Unmount
- Component is removed from DOM
- Cleanup functions run
- Effects are cleaned up
Common Cleanup Tasks
- Clear timers/intervals
- Cancel API requests
- Remove event listeners
- Close WebSocket connections
- Unsubscribe from subscriptions
Cleanup Pattern
function useSubscription(topic) {
useEffect(() => {
const unsubscribe = subscribe(topic);
return () => {
unsubscribe();
};
}, [topic]);
}
// Cleanup before next effect
function Component({ userId }) {
useEffect(() => {
const controller = new AbortController();
fetch(`/api/users/${userId}`, { signal: controller.signal });
// Runs when userId changes AND on unmount
return () => controller.abort();
}, [userId]);
}
Conditional Rendering
function App() {
const [show, setShow] = useState(true);
return (
<div>
<button onClick={() => setShow(!show)}>Toggle</button>
{show && <Timer />}
</div>
);
}
// Timer mounts/unmounts as show toggles
// Cleanup runs each time Timer unmounts
Practice Problems
Create a reusable React component implementing React Lifecycle. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for React Lifecycle using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize React Lifecycle for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. When does the mounting phase occur?
2. When does cleanup run in useEffect?
3. What triggers the updating phase?
4. What should you do in cleanup?
Flashcards
Question
When does mounting happen?
Click to reveal answer
Answer
When a component is first rendered to the DOM
Question
When does cleanup run?
Click to reveal answer
Answer
Before the next effect and on unmount
Question
What triggers updates?
Click to reveal answer
Answer
Props or state changes
Question
What is the cleanup function?
Click to reveal answer
Answer
A function returned from useEffect to clean up resources
Question
What is React Lifecycle?
Click to reveal answer
Answer
React Lifecycle is a key concept in frontend development.
Revision Notes
Key Takeaways
- 1.Mounting happens on first render
- 2.Updates happen when props/state change
- 3.Cleanup runs on unmount and before effects
- 4.Empty dependency array means mount only
- 5.Effects handle side effects
Interview Tips
- •Map lifecycle phases to useEffect patterns
- •Explain when cleanup functions run
- •Show how to handle mount, update, and unmount
Cheat Sheet
Cheat Sheet
Mounting
useEffect(() => {
// Mount logic
return () => {
// Cleanup on unmount
};
}, []);
Updating
useEffect(() => {
// Runs when dependency changes
}, [dependency]);
Unmounting
useEffect(() => {
const timer = setInterval(...);
return () => clearInterval(timer); // Cleanup
}, []);
Lifecycle Phases
- Mounting: Component appears
- Updating: Props/state change
- Unmounting: Component removed