Series 4 – React Fundamentals

 

Bài 2: State, Events và Conditional Rendering – Cách React xử lý tương tác người dùng

1. Mở đầu

Một giao diện website không chỉ hiển thị nội dung cố định. Khi người dùng nhấn nút, nhập dữ liệu, đăng nhập hoặc thêm sản phẩm vào giỏ hàng, giao diện cần phản hồi tương ứng.

Ví dụ, khi xây dựng một ứng dụng Todo List, chúng ta cần xử lý những tình huống như:

  • Người dùng nhập công việc mới.
  • Nhấn nút để thêm công việc.
  • Đánh dấu công việc đã hoàn thành.
  • Hiển thị thông báo khi danh sách chưa có công việc nào.

Trong React, ba khái niệm giúp xử lý những tương tác này là State, Events và Conditional Rendering.

2. State là gì?

State là dữ liệu mà một component cần ghi nhớ và có thể thay đổi trong quá trình hoạt động.

Ví dụ, một component có thể lưu số lượt nhấn nút, nội dung ô nhập liệu hoặc trạng thái bật/tắt của một giao diện.

Sử dụng useState

React cung cấp Hook useState để khai báo và cập nhật state trong Function Component.

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Số lần nhấn: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Tăng
      </button>
    </div>
  );
}

export default Counter;

Trong ví dụ trên:

  • count: giá trị state hiện tại.
  • setCount: hàm yêu cầu React cập nhật state.
  • useState(0): khởi tạo state với giá trị ban đầu là 0.

Khi người dùng nhấn nút, setCount(count + 1) được gọi. React cập nhật state và render lại component để hiển thị giá trị mới.

Vì sao không nên thay đổi state trực tiếp?

Không nên viết:

count = count + 1;

Hoặc khi state là một object:

user.name = "Khoa";

Thay vào đó, hãy sử dụng hàm cập nhật state. Với object, có thể tạo một object mới:

setUser({
  ...user,
  name: "Khoa",
});

React dựa vào cơ chế cập nhật state để xác định khi nào cần render lại giao diện. Việc thay đổi dữ liệu trực tiếp có thể khiến giao diện không cập nhật như mong muốn.

Cập nhật state dựa trên giá trị trước đó

Nếu giá trị mới phụ thuộc vào giá trị hiện tại, nên dùng dạng callback:

setCount((previousCount) => previousCount + 1);

Cách này hữu ích khi có nhiều lần cập nhật state liên tiếp, vì mỗi lần cập nhật sẽ nhận giá trị trước đó theo cơ chế của React.

3. Events là gì?

Event là sự kiện xảy ra khi người dùng hoặc trình duyệt thực hiện một hành động, chẳng hạn như nhấn nút, nhập văn bản hoặc gửi biểu mẫu.

Trong React, chúng ta có thể gắn hàm xử lý sự kiện trực tiếp vào JSX.

function WelcomeButton() {
  function handleClick() {
    alert("Xin chào!");
  }

  return (
    <button onClick={handleClick}>
      Nhấn vào đây
    </button>
  );
}

Một số event thường gặp:

Event Chức năng
onClick Khi người dùng nhấn vào phần tử
onChange Khi giá trị của input thay đổi
onSubmit Khi biểu mẫu được gửi
onMouseEnter Khi con trỏ đi vào phần tử
onKeyDown Khi người dùng nhấn phím

Lưu ý khi truyền hàm xử lý sự kiện

Đúng:

<button onClick={handleClick}>Nhấn</button>

Không đúng với mục đích chờ người dùng nhấn:

<button onClick={handleClick()}>Nhấn</button>

Ở ví dụ thứ hai, handleClick() được gọi ngay trong quá trình render thay vì truyền hàm để React gọi khi sự kiện xảy ra.

Nếu cần truyền tham số, có thể sử dụng arrow function:

<button onClick={() => deleteItem(10)}>
  Xóa
</button>

4. Conditional Rendering là gì?

Conditional Rendering là cách hiển thị giao diện dựa trên một điều kiện.

Ví dụ:

  • Đã đăng nhập: hiển thị thông tin tài khoản.
  • Chưa đăng nhập: hiển thị nút đăng nhập.
  • Danh sách trống: hiển thị thông báo.
  • Đang tải dữ liệu: hiển thị trạng thái loading.

Cách 1: Sử dụng toán tử ba ngôi

function LoginStatus({ isLoggedIn }) {
  return (
    <div>
      {isLoggedIn ? (
        <p>Chào mừng bạn quay trở lại!</p>
      ) : (
        <p>Vui lòng đăng nhập.</p>
      )}
    </div>
  );
}

Cú pháp:

condition ? expressionA : expressionB

Nếu điều kiện đúng, React hiển thị expressionA; nếu sai, React hiển thị expressionB.

Cách 2: Sử dụng toán tử &&

Khi chỉ muốn hiển thị một phần tử nếu điều kiện đúng:

function Notification({ hasMessage }) {
  return (
    <div>
      {hasMessage && <p>Bạn có thông báo mới.</p>}
    </div>
  );
}

Lưu ý: Tránh viết trực tiếp count && <p>...</p> nếu count có thể bằng 0, vì React có thể hiển thị số 0 trên giao diện. Có thể viết count > 0 && <p>...</p> để rõ ràng hơn.

Cách 3: Sử dụng if

Khi logic có nhiều nhánh, dùng if trong phần thân component để xác định nội dung cần trả về.

function UserGreeting({ user }) {
  if (!user) {
    return <p>Vui lòng đăng nhập.</p>;
  }

  return <p>Xin chào, {user.name}!</p>;
}

5. Kết hợp cả ba khái niệm

Xây dựng một component cho phép người dùng bật hoặc tắt thông báo.

import { useState } from "react";

function NotificationToggle() {
  const [isVisible, setIsVisible] = useState(false);

  function handleToggle() {
    setIsVisible((previous) => !previous);
  }

  return (
    <div>
      <button onClick={handleToggle}>
        {isVisible ? "Ẩn thông báo" : "Hiện thông báo"}
      </button>

      {isVisible && (
        <p>Bạn có một thông báo mới!</p>
      )}
    </div>
  );
}

export default NotificationToggle;

Luồng hoạt động:

  1. useState(false) khởi tạo trạng thái ẩn thông báo.
  2. Người dùng nhấn nút, onClick gọi handleToggle.
  3. setIsVisible cập nhật state sang trạng thái ngược lại.
  4. React render lại component.
  5. Conditional Rendering quyết định có hiển thị thông báo hay không.

Đây là một ví dụ nhỏ nhưng thể hiện rõ cách React kết hợp dữ liệu, sự kiện và giao diện.

6. Những lỗi người mới thường gặp

  • Quên import useState: cần import Hook từ react.
  • Gọi hàm ngay khi render: viết onClick={handleClick()} thay vì onClick={handleClick} khi muốn chờ sự kiện.
  • Thay đổi state trực tiếp: sử dụng hàm cập nhật state thay vì sửa biến hoặc object tại chỗ.
  • Nhầm && với điều kiện Boolean thuần túy: giá trị 0 có thể xuất hiện trên giao diện.
  • Cho rằng component render lại đồng nghĩa toàn bộ DOM đều bị tạo lại: React sẽ so sánh kết quả render và chỉ cập nhật những phần DOM cần thiết.

8. Kết luận

State, Events và Conditional Rendering là ba nền tảng quan trọng giúp xây dựng giao diện React có tính tương tác.

  • State quản lý dữ liệu có thể thay đổi.
  • Events tiếp nhận và xử lý hành động.
  • Conditional Rendering quyết định giao diện cần hiển thị theo dữ liệu hoặc điều kiện.

Khi đã nắm vững ba khái niệm này, bước tiếp theo là tìm hiểu cách hiển thị danh sách dữ liệu và xây dựng biểu mẫu — những công việc xuất hiện thường xuyên trong các dự án React thực tế.

Bài viết khác

OpenAPI và Swagger là gì?

1. OpenAPI và Swagger là gì? Khi xây dựng Backend, lập trình viên không chỉ cần triển khai API mà còn phải mô tả cách API hoạt động để những người khác có thể sử dụng và kiểm thử. Ví dụ, một ứng dụng quản lý sản phẩm cung cấp các endpoint: GET /products: lấy […]

Series 4 – React Hooks – State: Hooks, useState và useEffect

Series 4 – React Hooks – State   Bài 1 : Hooks, useState và useEffect – Quản lý dữ liệu và side effects trong React 1. React Hooks là gì? Hooks là những hàm do React cung cấp để Function Component sử dụng các khả năng như quản lý state, đồng bộ với hệ thống bên […]

Series 4 – React Fundamentals: List Rendering, Forms, Form Handling

Series 4 – React Fundamentals   Bài 3: List Rendering, Forms và Form Handling – Hiển thị danh sách và xử lý biểu mẫu trong React   1. Mở đầu Trong một ứng dụng thực tế, dữ liệu thường được hiển thị dưới dạng danh sách: danh sách sản phẩm, bài viết, người dùng hoặc công việc […]

Series 4 — React Fundamentals : JSX, Components và Props – Ba nền tảng đầu tiên khi học React

Series 4 – React Fundamentals   Bài 1:JSX, Components và Props – Ba nền tảng đầu tiên khi học React 1. Mở đầu Khi xây dựng một website bằng HTML, CSS và JavaScript, chúng ta thường tạo cấu trúc giao diện bằng HTML, sau đó sử dụng JavaScript để xử lý dữ liệu và tương tác. […]

Series 3 – JavaScript Fundamentals: Async → API

Series 3 — JavaScript Fundamentals   JavaScript → DOM → Async → API   Bài 2. Asynchronous JavaScript & API – Xử lý bất đồng bộ và giao tiếp với Server 1. Vì sao cần Asynchronous JavaScript? Trong các website hiện đại, nhiều thao tác cần thời gian để hoàn thành, chẳng hạn như gọi API lấy […]

Transactions & ACID

1. Transaction là gì? Transaction (giao dịch) là một nhóm thao tác trên database được xem như một đơn vị xử lý logic. Mục tiêu là bảo đảm những thay đổi liên quan được thực hiện theo cách nhất quán: nếu giao dịch thành công thì các thay đổi cần thiết được xác nhận; nếu […]

Leave a Reply

Your email address will not be published. Required fields are marked *