Loading Now

Vòng đời Component trong React: Class và Functional Component

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

  1. 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.
  2. 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.
  3. render()
    • Bắt buộc phải có, trả về JSX UI.
    • Không chứa side effect.
  4. 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 đương componentDidMount().

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>;
}

🔗 Hooks – useEffect


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

  1. static getDerivedStateFromProps() – Tiếp tục gọi trước mỗi lần render.
  2. shouldComponentUpdate(nextProps, nextState) – Trả về false để ngăn component render lại.
  3. render() – Trả về UI mới dựa trên props/state mới.
  4. getSnapshotBeforeUpdate(prevProps, prevState) – Gọi trước khi cập nhật DOM.
  5. 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]);

🔗 Tìm hiểu sâu về useEffect


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ạnClass ComponentFunctional Component
Mountingconstructor, render, componentDidMountuseEffect(() => …, [])
Updatingrender, componentDidUpdateuseEffect(…, [deps])
UnmountingcomponentWillUnmountreturn 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ặc shouldComponentUpdate để 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

Bạn có thể đã bỏ qua