[React Basics] Stateful và Stateless Components: Phân biệt và Ứng dụng trong React

Trong thế giới của React, việc hiểu rõ bản chất của Stateful và Stateless components cũng quan trọng như việc một đầu bếp hiểu khi nào cần dùng lửa to và khi nào cần liu riu. Đây không chỉ là những khái niệm lý thuyết suông, mà là nền tảng cốt lõi quyết định cách bạn cấu trúc ứng dụng, tối ưu hóa hiệu năng và viết code sạch sẽ, dễ bảo trì.

Stateful và Stateless Components: Phân biệt và Ứng dụng trong React

Hãy cùng nhau bóc tách từng lớp, từ định nghĩa kinh điển đến cuộc cách mạng mang tên "Hooks" đã thay đổi cuộc chơi như thế nào!

🎨 Stateless Component: "Người trình bày" trung thành

Hãy tưởng tượng một người họa sĩ chỉ nhận nhiệm vụ vẽ lại một bức tranh theo mẫu có sẵn. Bạn đưa cho anh ta màu gì, cọ gì, anh ta sẽ vẽ ra chính xác bức tranh đó. Anh ta không tự ý thêm thắt hay thay đổi chi tiết. Đó chính là Stateless Component.

Stateless Components, hay còn được gọi là Presentational Components (thành phần trình bày) hoặc Dumb Components (thành phần "ngốc"), là những component đơn giản nhất trong React.

Đặc điểm nhận dạng:

  • Không có state của riêng mình: Chúng không lưu trữ bất kỳ dữ liệu nào thay đổi theo thời gian. Cuộc đời của chúng là một đường thẳng, không có ký ức.
  • Nhận dữ liệu qua props: Giống như người họa sĩ nhận "mẫu" (dữ liệu) từ bên ngoài thông qua props và chỉ có một nhiệm vụ duy nhất - hiển thị dữ liệu đó ra giao diện.
  • Dự đoán được: Với cùng một props đầu vào, chúng sẽ luôn luôn trả về cùng một kết quả (UI) đầu ra. Điều này làm cho chúng rất dễ kiểm thử (test).
  • Thường là Function Components: Trước khi Hooks ra đời, đây là cách viết phổ biến nhất cho Stateless Components.

Ví dụ kinh điển: Một component Welcome đơn giản.

// Welcome.js - Một Stateless Function Component điển hình
import React from 'react'

function Welcome(props) {
  return <h1>Chào mừng, {props.name}!</h1>
}

export default Welcome

Trong ví dụ này, Welcome không cần biết name đến từ đâu hay nó sẽ thay đổi như thế nào. Nó chỉ nhận name và hiển thị. Đơn giản, hiệu quả và có khả năng tái sử dụng cực cao.

🧠 Stateful Component: "Bộ não" thông minh

Ngược lại với người họa sĩ ở trên, hãy tưởng tượng một vị quản lý kho hàng. Vị quản lý này không chỉ biết cách trưng bày hàng hóa (render), mà còn phải ghi nhớ trong kho còn bao nhiêu sản phẩm, khi nào cần nhập thêm, khi nào xuất hàng đi. Ông ta có "trí nhớ" và "logic" riêng. Đó chính là Stateful Component.

Stateful Components, hay còn gọi là Container Components (thành phần bao bọc) hoặc Smart Components (thành phần "thông minh"), là bộ não của ứng dụng React.

Đặc điểm nhận dạng:

  • Quản lý state: Chúng sở hữu một đối tượng state để lưu trữ dữ liệu có thể thay đổi theo tương tác của người dùng hoặc các sự kiện khác. Đây là "trí nhớ" của component.
  • Chứa logic nghiệp vụ: Chúng chịu trách nhiệm xử lý các sự kiện, gọi API, và quyết định xem nên hiển thị cái gì và khi nào.
  • Sử dụng setState() để cập nhật UI: Khi state thay đổi, chúng sử dụng phương thức setState() để "ra lệnh" cho React render lại giao diện với dữ liệu mới.
  • Thường là Class Components: Đây là cách duy nhất để tạo ra Stateful Components trước khi có Hooks. Chúng sử dụng các phương thức vòng đời (lifecycle methods) như componentDidMount hay componentDidUpdate.

Ví dụ kinh điển: Một component Counter (bộ đếm).

// Counter.js - Một Stateful Class Component điển hình
import React, { Component } from 'react'

class Counter extends Component {
  constructor(props) {
    super(props)
    // Khởi tạo state ban đầu
    this.state = {
      count: 0,
    }
  }

  // Phương thức để thay đổi state
  increment = () => {
    this.setState({ count: this.state.count + 1 })
  }

  render() {
    return (
      <div>
        <p>Số lượt bấm: {this.state.count}</p>
        <button onClick={this.increment}>Bấm vào tôi</button>
      </div>
    )
  }
}

export default Counter

Component này có statecount. Mỗi khi người dùng bấm nút, nó tự cập nhật state của mình và hiển thị lại giá trị mới.

⚖️ Đặt lên bàn cân: Stateful vs. Stateless

Dưới đây là bảng so sánh nhanh theo các tiêu chí quan trọng nhất:

Tiêu chíStateless Component (Dumb)Stateful Component (Smart)
Mục đíchHiển thị dữ liệu, giao diện (UI).Quản lý dữ liệu, logic nghiệp vụ.
StateKhông có state.state để lưu trữ dữ liệu.
Cú phápFunction Component.Class Component.
Dữ liệuNhận dữ liệu từ props.Quản lý dữ liệu nội bộ bằng state.
Vòng đờiKhông có lifecycle methods.Có các lifecycle methods (componentDidMount...).
Khi nào dùngCác thành phần UI tái sử dụng: Button, Input, Card...Các trang, các khu vực quản lý logic phức tạp.

💥 Cuộc cách mạng mang tên "Hooks" - Khi ranh giới bị xóa nhòa

Mô hình Class Component (Stateful) và Function Component (Stateless) đã phục vụ cộng đồng React rất tốt trong một thời gian dài. Tuy nhiên, nó cũng bộc lộ một số nhược điểm: Class Components khá dài dòng, logic khó tái sử dụng, và khái niệm this đôi khi gây bối rối.

Và rồi, React Hooks ra đời trong phiên bản React 16.8, làm thay đổi mọi thứ.

React Handling Events: Những cách làm hiệu quả và tối ưu

Hooks là những hàm đặc biệt cho phép bạn "móc" các tính năng của React (như state và lifecycle) vào trong Function Components.

Điều này có nghĩa là: Function Components giờ đây cũng có thể trở thành "Stateful"!

Hãy xem lại ví dụ Counter ở trên, nhưng lần này được viết lại bằng Function Component và Hook useState:

// Counter.js - VIẾT LẠI theo phong cách Hooks hiện đại
import React, { useState } from 'react'

function Counter() {
  // Dùng Hook `useState` để tạo ra một "state" trong Function Component
  // `count` là giá trị state, `setCount` là hàm để cập nhật nó
  const [count, setCount] = useState(0)

  const increment = () => {
    setCount(count + 1)
  }

  return (
    <div>
      <p>Số lượt bấm: {this.state.count}</p>
      <button onClick={increment}>Bấm vào tôi</button>
    </div>
  )
}

export default Counter

Kết quả? Code ngắn gọn hơn, dễ đọc hơn, không còn this, và vẫn hoàn toàn là một Stateful Component. Ranh giới giữa "thông minh" và "ngốc" dựa trên cú pháp (Class vs. Function) đã bị xóa nhòa.

💡 Bí kíp tối ưu: Khi nào dùng gì trong kỷ nguyên Hooks?

Với sự xuất hiện của Hooks, cộng đồng React hiện nay ưu tiên sử dụng Function Components cho gần như mọi trường hợp. Tuy nhiên, tư duy phân tách "logic" và "trình bày" vẫn còn nguyên giá trị.

Quy tắc vàng:

  1. Luôn bắt đầu với Function Component. Đây là tiêu chuẩn hiện đại.
  2. Mặc định component là "stateless". Chỉ tập trung vào việc nhận props và hiển thị UI.
  3. Khi cần "trí nhớ", hãy thêm Hooks. Nếu component cần lưu trữ dữ liệu (ví dụ: giá trị của một ô input, trạng thái đóng/mở của một menu), hãy sử dụng Hook useState.
  4. Khi cần xử lý "side effects", hãy thêm Hooks. Nếu component cần tương tác với thế giới bên ngoài (gọi API, thao tác DOM), hãy sử dụng Hook useEffect.
  5. Tách biệt logic phức tạp. Nếu một component trở nên quá "thông minh" với nhiều state và effect, hãy cân nhắc tách phần logic đó ra một Custom Hook để tái sử dụng.

Việc phân chia này không còn là Stateful vs. Stateless một cách cứng nhắc, mà là sự phân tách linh hoạt giữa Container Logic (quản lý state và side effects) và Presentational Logic (hiển thị UI) ngay trong cùng một Function Component hoặc giữa các Function Components khác nhau.

Kết luận: Cần hiểu rõ bản chất của state

Hành trình từ việc phân biệt rạch ròi giữa Stateful (Class)Stateless (Function) đến kỷ nguyên Hooks cho thấy sự phát triển không ngừng của React.

  • Stateless Component: Vẫn là những người hùng thầm lặng, chuyên tâm vào việc hiển thị, giúp ứng dụng của bạn dễ kiểm thử và tái sử dụng.
  • Stateful Component: Là bộ não điều khiển, nơi chứa đựng logic và dữ liệu.
  • React Hooks: Là cuộc cách mạng cho phép chúng ta xây dựng những "bộ não" mạnh mẽ bằng cú pháp Function Component đơn giản, gọn gàng và hiện đại hơn.

Hiểu rõ bản chất của state và cách quản lý nó chính là chìa khóa để bạn chinh phục React và xây dựng nên những ứng dụng tuyệt vời.

Chúc bạn thành công trên con đường coding của mình!

Bài viết liên quan

[React Basics] Quản lý State phức tạp với useReducer Hook trong React

Tìm hiểu useReducer hook - giải pháp mạnh mẽ cho việc quản lý state phức tạp trong React. Bài viết này sẽ giúp bạn hiểu rõ nguyên lý hoạt động và cách áp dụng hiệu quả.

[React Basics] useState Hook: Cách quản lý State hiệu quả trong React

Hướng dẫn cách sử dụng useState Hook để quản lý state trong các function component của React. Tìm hiểu các ví dụ thực tế, từ cơ bản đến nâng cao, giúp bạn làm chủ React Hook quan trọng này.

[React Basics] Thuộc tính key trong React: Hiểu rõ và sử dụng hiệu quả

Bạn đã thực sự hiểu về thuộc tính key trong React? Tìm hiểu vai trò, cách dùng hiệu quả và các ví dụ thực tế giúp code của bạn sạch và tối ưu hơn.

[React Basics] Hướng dẫn thiết lập môi trường phát triển React

Hướng dẫn cách thiết lập môi trường phát triển React cho người mới bắt đầu. Tìm hiểu các bước cài đặt Node.js, npm, và tạo project React đầu tiên với Create React App hoặc Vite.