Vòng đời Component trong React: Class và Functional Component
Hiểu rõ vòng đời của component trong React giúp các lập trình viên quản lý, tối ưu và debug ứng dụng hiệu quả hơn. Bài viết này sẽ trình bày chi tiết từng giai đoạn trong vòng đời component – từ giai đoạn mounting, updating đến unmounting – dành cho cả class component và functional component sử dụng hooks. Mỗi phần đều có ví dụ minh họa cụ thể và liên kết tham khảo.
1. Giai đoạn Mounting (Khởi tạo component)
Giai đoạn mounting xảy ra khi component được tạo và gắn vào DOM lần đầu tiên. Đây là thời điểm để thiết lập dữ liệu ban đầu, gọi API hoặc khởi tạo sự kiện.
Class Component – Các phương thức trong Mounting
constructor(props)
- Gọi khi component được khởi tạo.
- Dùng để khởi tạo state và bind các phương thức.
- Không nên thực hiện side effect trong constructor.
static getDerivedStateFromProps(props, state)
- Gọi trước mỗi lần render.
- Dùng để cập nhật state dựa trên props.
- Trả về object để cập nhật state hoặc
null
nếu không thay đổi.
render()
- Bắt buộc phải có, trả về JSX UI.
- Không chứa side effect.
componentDidMount()
- Gọi sau khi component đã được gắn vào DOM.
- Thích hợp để gọi API, gắn event listener hoặc tương tác với DOM.
Ví dụ:
class UserCard extends React.Component {
constructor(props) {
super(props);
this.state = { userData: null };
}
static getDerivedStateFromProps(props, state) {
return null;
}
render() {
return this.state.userData ? <div>Welcome, {this.state.userData.name}!</div> : <div>Loading...</div>;
}
componentDidMount() {
fetch(`/api/user/${this.props.userId}`)
.then(res => res.json())
.then(data => this.setState({ userData: data }));
}
}
🔗 Tài liệu vòng đời Class Component
Functional Component – Mounting sử dụng Hooks
useState()
để khởi tạo state.useEffect(() => { ... }, [])
tương đươngcomponentDidMount()
.
Ví dụ:
import React, { useEffect, useState } from 'react';
function UserCard({ userId }) {
const [userData, setUserData] = useState(null);
useEffect(() => {
fetch(`/api/user/${userId}`)
.then(res => res.json())
.then(data => setUserData(data));
}, []);
return userData ? <div>Welcome, {userData.name}!</div> : <div>Loading...</div>;
}
2. Giai đoạn Updating (Cập nhật component)
Giai đoạn này xảy ra khi props hoặc state thay đổi và component được render lại.
Class Component – Các phương thức trong Updating
static getDerivedStateFromProps()
– Tiếp tục gọi trước mỗi lần render.shouldComponentUpdate(nextProps, nextState)
– Trả vềfalse
để ngăn component render lại.render()
– Trả về UI mới dựa trên props/state mới.getSnapshotBeforeUpdate(prevProps, prevState)
– Gọi trước khi cập nhật DOM.componentDidUpdate(prevProps, prevState, snapshot)
– Gọi sau khi DOM đã cập nhật.
Ví dụ:
componentDidUpdate(prevProps, prevState) {
if (prevProps.userId !== this.props.userId) {
fetch(`/api/user/${this.props.userId}`)
.then(res => res.json())
.then(data => this.setState({ userData: data }));
}
}
Functional Component – Updating sử dụng Hooks
Sử dụng useEffect(() => { ... }, [deps])
để chạy lại logic khi giá trị phụ thuộc thay đổi.
Ví dụ:
useEffect(() => {
let isCurrent = true;
fetch(`/api/user/${userId}`)
.then(res => res.json())
.then(data => isCurrent && setUserData(data));
return () => {
isCurrent = false;
};
}, [userId]);
3. Giai đoạn Unmounting (Hủy component)
Giai đoạn này xảy ra khi component bị gỡ khỏi DOM. Đây là lúc để dọn dẹp và tránh rò rỉ bộ nhớ.
Class Component
componentWillUnmount()
– Dùng để clear timer, hủy lắng nghe sự kiện, hủy kết nối…
Ví dụ:
componentWillUnmount() {
clearInterval(this.timer);
}
Functional Component – Cleanup với Hooks
Trả về một hàm trong useEffect()
để xử lý cleanup khi unmount.
Ví dụ:
useEffect(() => {
const intervalId = setInterval(() => console.log('Tick'), 1000);
return () => {
clearInterval(intervalId);
console.log('Cleanup');
};
}, []);
🔗 Dọn dẹp hiệu ứng với useEffect
Sơ đồ và tài nguyên học thêm
Tóm tắt
Giai đoạn | Class Component | Functional Component |
---|---|---|
Mounting | constructor, render, componentDidMount | useEffect(() => …, []) |
Updating | render, componentDidUpdate | useEffect(…, [deps]) |
Unmounting | componentWillUnmount | return cleanup trong useEffect |
Gợi ý:
- Luôn giữ
render()
thuần khiết. - Ưu tiên sử dụng functional component và hooks.
- Sử dụng
React.memo
,useMemo
hoặcshouldComponentUpdate
để tối ưu hóa hiệu suất. - Luôn cleanup trong
useEffect
nếu cần.
Hãy thử: Viết lại một component class sang functional component và áp dụng các bước lifecycle tương ứng.
Khi nắm vững vòng đời component trong React, bạn sẽ viết được các ứng dụng dễ kiểm soát, hiệu quả và dễ mở rộng hơn.
Xem thêm:
Các vấn đề cơ bản khi làm web frontend bạn cần biết
Share this content:
Post Comment