
React Lifecycle Methods-From Class Components to Hooks
Feb 01, 2025 3 Min Read 999 Views
(Last Updated)
What if you could write cleaner, more readable React code without worrying about class-based lifecycle methods? React has evolved significantly since its early days, and one of the biggest shifts came with the introduction of Hooks in React 16.8. While class components relied on lifecycle methods to manage state and side effects, Hooks offered a more intuitive, streamlined way to handle the same functionality. But does that mean class components are obsolete? Not quite.
In this blog, we’ll break down the key differences between lifecycle methods in class components and the Hook-based approach in functional components. By the end, you’ll have a clear understanding of how React’s evolution has made development more efficient while still maintaining the flexibility to work with both paradigms.
Table of contents
- Lifecycle Methods in Class Components
- Example: Lifecycle Methods in Class Components
- Lifecycle Management with Hooks
- useState: Managing Component State
- useEffect: Handling Side Effects
- Key Differences Between Class Components and Hooks
- Conclusion
Lifecycle Methods in Class Components
In class-based components, React provides lifecycle methods to manage component behavior during different phases of its existence:
- Mounting: The phase when a component is initialized and inserted into the DOM.
- constructor(): Used for initializing state and binding methods.
- componentDidMount(): Called after the component is rendered to the DOM. Ideal for data fetching, subscriptions, or other setup.
- Updating: This phase occurs when a component’s state or props change, causing a re-render.
- shouldComponentUpdate(): Determines if a re-render is needed. Useful for performance optimizations.
- componentDidUpdate(): Runs after the component has been re-rendered due to state or prop changes. You can perform additional operations here, like updating the DOM.
- Unmounting: The phase when a component is removed from the DOM.
- componentWillUnmount(): Allows cleanup, such as removing event listeners or cancelling network requests.
- Error Handling: For catching errors in a component’s rendering or during lifecycle methods.
- componentDidCatch(): Catches and handles errors thrown in a component’s tree.
Example: Lifecycle Methods in Class Components
class ExampleComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
componentDidMount() {
// Perform data fetching or set up subscriptions
console.log(‘Component Mounted’);
}
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
console.log(‘Component Updated’);
}
}
componentWillUnmount() {
// Clean up resources
console.log(‘Component Unmounted’);
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count:
this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}
Want to master Full Stack Development and dive deeper into React, including its lifecycle methods, hooks, and beyond? Our Full Stack Development course is designed to equip you with the skills to build scalable web applications from the ground up. Start your journey in Full Stack Development today!
Lifecycle Management with Hooks
React Hooks introduced a new way to handle state and side effects in functional components, eliminating the need for lifecycle methods. Two key hooks-useState and useEffect-allow developers to manage the same functionality that class-based lifecycle methods do, but in a more intuitive way.
1. useState: Managing Component State
With useState, we can initialize and manage component state directly within a functional component.
const [count, setCount] = useState(0);
This replaces the need for the constructor method in class components. The setCount function allows us to update the state, which will trigger a re-render.
2. useEffect: Handling Side Effects
The useEffect hook serves as a replacement for componentDidMount, componentDidUpdate, and componentWillUnmount. It runs after each render by default, allowing developers to execute side effects like data fetching, subscriptions, or DOM updates.
Example: useEffect for Data Fetching (Similar to componentDidMount)
useEffect(() => {
// This runs after the component mounts
console.log(‘Component Mounted’);
return () => {
// This cleanup function runs when the component unmounts
console.log(‘Component Unmounted’);
};
}, []); // Empty dependency array means it only runs once, similar to componentDidMount
If we need to handle updates, we can add state or props as dependencies to useEffect, and React will re-run the effect when those dependencies change.
useEffect(() => {
console.log(‘Count updated’);
return () => {
console.log(‘Cleanup before next render’);
};
}, [count]); // Runs every time ‘count’ changes
Example: Lifecycle with Functional Components and Hooks
Here’s the same functionality as before, but implemented using functional components and hooks:
import React, { useState, useEffect } from ‘react’;
const ExampleComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(‘Component Mounted’);
return () => {
console.log(‘Component Unmounted’);
};
}, []);
useEffect(() => {
console.log(‘Component Updated: Count changed’);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
In this functional component:
- useState replaces the state initialization from the class constructor.
- useEffect handles the mounting, updating, and unmounting behavior, which were previously managed by different lifecycle methods (componentDidMount, componentDidUpdate, and componentWillUnmount).
Key Differences Between Class Components and Hooks
- Syntax and Structure:
- Class components are often bulkier due to their method structure and this keyword usage.
- Functional components with Hooks are leaner and easier to read, especially for managing state and side effects.
- Separation of Concerns:
- In class components, different lifecycle methods handle distinct phases (mounting, updating, unmounting).
- With Hooks, the useEffect hook consolidates all side effects, making the flow easier to follow and reducing code duplication.
- Reusability:
- Class components often require higher-order components (HOCs) or render props for reusability.
- Hooks can be reused easily through custom hooks, offering greater flexibility and composability.
Conclusion
React’s transition from class-based lifecycle methods to Hooks is more than just a syntax change—it’s a shift towards a more declarative and modular approach to building user interfaces. With Hooks, managing component behavior becomes simpler, reducing the need for boilerplate code while enhancing readability and reusability. However, class components remain relevant, especially in legacy codebases, and understanding both paradigms allows developers to navigate any React project with confidence.
The real takeaway? Instead of seeing this as an either-or choice, think of it as an expansion of your toolkit. Mastering both approaches not only deepens your React expertise but also equips you to write scalable and maintainable applications in any development environment.
Did you enjoy this article?