Understanding React Component Lifecycles: Class-Based vs. Functional Components with Hooks
Adrian Birta
React Front-end Developer | 5+ Years in React & Scalable Web Apps | I Build High-Performance UIs That Scale
In the vast sea of React development, mastering component lifecycles is akin to navigating through turbulent waters. In this exploration, we'll delve into the lifecycles of both class-based components and functional components with hooks, providing a comprehensive guide to React's heartbeat.
Class-Based Component Lifecycle
Mounting Phase
The Counter class-based component demonstrates the Mounting phase:
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
componentDidMount() {
console.log('Component mounted!');
}
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Increment
</button>
</div>
);
}
}
In this example, componentDidMount is used to log a message to the console when the component is successfully mounted.
Updating and Unmounting Phases
Consider a UserProfile component using both updating and unmounting phases:
import React, { Component } from 'react';
class UserProfile extends Component {
componentDidUpdate(prevProps, prevState) {
console.log('Component updated!', prevProps, prevState);
}
componentWillUnmount() {
console.log('Component will unmount!');
}
render() {
return <p>User Profile: {this.props.username}</p>;
}
}
Here, componentDidUpdate logs details about the previous props and state when an update occurs, and componentWillUnmount logs a message before the component is unmounted.
领英推荐
Functional Component Lifecycle with Hooks
Mounting and Updating Phase
The Timer functional component demonstrates the Mounting and Updating phase:
import React, { useState, useEffect } from 'react';
const Timer = () => {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setSeconds(prevSeconds => prevSeconds + 1);
}, 1000);
return () => {
clearInterval(interval);
console.log('Timer component unmounted!');
};
}, []); // Empty dependency array triggers effect on mount
return <p>Seconds: {seconds}</p>;
};
Here, the useEffect hook manages the interval, incrementing seconds every second. The cleanup function within useEffect logs a message when the component is unmounted.
Fetching Data on Mount
Consider a UserData functional component that fetches data on mount:
import React, { useState, useEffect } from 'react';
const UserData = () => {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://api.example.com/user');
const result = await response.json();
setData(result);
};
fetchData();
return () => {
console.log('UserData component unmounted!');
};
}, []);
return <p>User Data: {data ? data.name : 'Loading...'}</p>;
};
This example uses useEffect to fetch data when the component mounts. The cleanup function logs a message when the component is unmounted.
Comparing Lifecycles: A Symbiotic Dance
Understanding the lifecycles of both class-based components and functional components with hooks is akin to learning a choreographed dance. Whether you choose the explicit steps of class components or the fluid movements of hooks, precise management of component behavior and side effects is attainable.