React Fundamentals

Mastering JSX

Khám phá sức mạnh của JSX - cú pháp mở rộng JavaScript giúp xây dựng UI React một cách trực quan, hiệu quả và mạnh mẽ

JSX Là Gì?
JavaScript XML - Cú pháp mở rộng mạnh mẽ cho JavaScript

JSX (JavaScript XML) là một extension syntax cho JavaScript được phát triển bởi Facebook. Nó cho phép chúng ta viết markup giống HTML trực tiếp trong JavaScript, tạo ra một cách thức trực quan và mạnh mẽ để mô tả giao diện người dùng một cách declarative.

JSX
const element = <h1>Xin chào, thế giới!</h1>;

Lưu ý quan trọng

JSX không phải là HTML thuần túy. Nó được transpile thành các lệnh gọi hàm JavaScript (React.createElement()) thông qua các công cụ như Babel. Điều này cho phép React tối ưu hóa performance thông qua Virtual DOM và cung cấp các tính năng mạnh mẽ như hot reloading và tree shaking.

Các Ví Dụ Thực Tế

Biểu thức JavaScript trong JSX
Sử dụng ngoặc nhọn để nhúng biểu thức JavaScript phức tạp vào trong JSX
JSX13 dòngNâng cao
const name = "Người dùng";
const age = 25;
const isActive = true;

const element = (
  <div className="user-card">
    <h1>Xin chào, {name}!</h1>
    <p>Tuổi: {age}</p>
    <span className={isActive ? "active" : "inactive"}>
      {isActive ? "Đang hoạt động" : "Không hoạt động"}
    </span>
  </div>
);

Demo component tương tác

Xin chào, Người dùng!

Tuổi: 25

Đang hoạt động
Quy tắc JSX
Những nguyên tắc cần tuân thủ khi viết JSX
  • 1

    Phải có một phần tử gốc duy nhất hoặc sử dụng React.Fragment (<> </>)

  • 2

    Đóng tất cả các thẻ, kể cả self-closing tags như <img />, <br />

  • 3

    Thuộc tính 'class' phải được viết thành 'className'

  • 4

    Thuộc tính 'for' phải được viết thành 'htmlFor'

  • 5

    Sử dụng camelCase cho tất cả thuộc tính HTML (onClick, onMouseOver)

  • 6

    Biểu thức JavaScript phải nằm trong ngoặc nhọn {}

  • 7

    Style inline phải là object JavaScript, không phải string

  • 8

    Tất cả thuộc tính boolean phải được viết đầy đủ hoặc sử dụng {true/false}

CSS → JSX Mapping
Chuyển đổi CSS properties sang JSX style objects
background-colorbackgroundColor
font-sizefontSize
border-radiusborderRadius
margin-topmarginTop
padding-leftpaddingLeft
text-aligntextAlign
box-shadowboxShadow
z-indexzIndex
font-weightfontWeight
line-heightlineHeight

Ví dụ Style Object:

JAVASCRIPT6 dòng
const styles = {
  backgroundColor: "#f1f5f9",
  fontSize: "16px",
  borderRadius: "8px",
  marginTop: "20px"
};
Inline Styles Nâng Cao
Tạo styled components với JavaScript objects và dynamic styling
JSX57 dòngNâng cao
const StyledButton = ({ variant = "primary", size = "medium", children, ...props }) => {
  const baseStyle = {
    padding: size === "large" ? "16px 32px" : "12px 24px",
    borderRadius: "8px",
    border: "none",
    fontWeight: "600",
    cursor: "pointer",
    transition: "all 0.2s ease",
    fontSize: size === "large" ? "16px" : "14px",
    display: "inline-flex",
    alignItems: "center",
    gap: "8px"
  };

  const variantStyles = {
    primary: {
      backgroundColor: "#3b82f6",
      color: "white",
      boxShadow: "0 4px 12px rgba(59, 130, 246, 0.3)"
    },
    secondary: {
      backgroundColor: "#f1f5f9",
      color: "#334155",
      border: "2px solid #e2e8f0"
    },
    danger: {
      backgroundColor: "#ef4444",
      color: "white",
      boxShadow: "0 4px 12px rgba(239, 68, 68, 0.3)"
    }
  };

  const hoverStyles = {
    primary: { backgroundColor: "#2563eb", transform: "translateY(-1px)" },
    secondary: { backgroundColor: "#e2e8f0", transform: "translateY(-1px)" },
    danger: { backgroundColor: "#dc2626", transform: "translateY(-1px)" }
  };

  const [isHovered, setIsHovered] = useState(false);

  const finalStyle = {
    ...baseStyle,
    ...variantStyles[variant],
    ...(isHovered ? hoverStyles[variant] : {})
  };

  return (
    <button
      style={finalStyle}
      onMouseEnter={() => setIsHovered(true)}
      onMouseLeave={() => setIsHovered(false)}
      {...props}
    >
      {children}
    </button>
  );
};

Interactive styled button

React Fragments
Nhóm nhiều elements mà không tạo thêm DOM nodes

React Fragments cho phép bạn return multiple elements từ một component mà không cần wrapper div. Điều này giúp giữ DOM tree sạch sẽ và tránh các vấn đề về CSS layout.

JSX72 dòngNâng cao
import React from 'react';

const UserProfile = ({ user, showActions = true, showBadges = true }) => {
  const formatJoinDate = (date) => {
    return new Date(date).toLocaleDateString('vi-VN', {
      year: 'numeric',
      month: 'long',
      day: 'numeric'
    });
  };

  return (
    <React.Fragment>
      {/* User Avatar & Basic Info */}
      <div className="flex items-center gap-4 mb-6">
        <img 
          src={user.avatar || "/default-avatar.png"}
          alt={user.name}
          className="w-24 h-24 rounded-full border-4 border-white shadow-lg"
        />
        <div>
          <h2 className="text-2xl font-bold text-slate-800">{user.name}</h2>
          <p className="text-slate-600">{user.email}</p>
          <p className="text-sm text-slate-500">
            Tham gia từ {formatJoinDate(user.joinDate)}
          </p>
        </div>
      </div>

      {/* Status Badges */}
      {showBadges && (
        <div className="flex gap-2 mb-4">
          <span className={`px-3 py-1 rounded-full text-xs font-medium ${
            user.isVerified 
              ? "bg-green-100 text-green-800" 
              : "bg-gray-100 text-gray-800"
          }`}>
            {user.isVerified ? "✓ Đã xác minh" : "Chưa xác minh"}
          </span>
          <span className="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-xs font-medium">
            {user.role}
          </span>
          {user.isPremium && (
            <span className="px-3 py-1 bg-gradient-to-r from-purple-500 to-pink-500 text-white rounded-full text-xs font-medium">
              ⭐ Premium
            </span>
          )}
        </div>
      )}

      {/* Bio Section */}
      {user.bio && (
        <div className="mb-6 p-4 bg-slate-50 rounded-lg">
          <h3 className="font-semibold text-slate-700 mb-2">Giới thiệu</h3>
          <p className="text-slate-600 leading-relaxed">{user.bio}</p>
        </div>
      )}

      {/* Action Buttons */}
      {showActions && (
        <div className="flex gap-3">
          <button className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
            Gửi tin nhắn
          </button>
          <button className="px-4 py-2 border border-slate-300 text-slate-700 rounded-lg hover:bg-slate-50 transition-colors">
            Theo dõi
          </button>
        </div>
      )}
    </React.Fragment>
  );
};

Khi nào sử dụng Fragments?

  • • Khi return multiple elements từ component
  • • Tránh wrapper divs không cần thiết
  • • Giữ CSS Grid/Flexbox layout đúng cấu trúc
  • • Cải thiện semantic HTML

Lợi Ích Của JSX

Cú pháp trực quan

Kết hợp HTML và JavaScript một cách tự nhiên, làm cho code dễ đọc và hiểu hơn cho developers

Type Safety

Kiểm tra lỗi tại thời điểm compile với TypeScript, giảm thiểu bugs và tăng độ tin cậy

Developer Experience

IntelliSense tốt hơn, auto-completion, refactoring tools và debugging experience được cải thiện

Component Reusability

Dễ dàng tái sử dụng và compose các UI components, tạo ra kiến trúc modular

Performance Optimization

Tối ưu hóa tự động thông qua Virtual DOM diffing và tree shaking

Ecosystem Integration

Tích hợp mượt mà với các tools như Babel, Webpack, và build systems hiện đại

Tổng Kết

JSX là một công cụ mạnh mẽ giúp developers React viết code một cách trực quan và hiệu quả. Với khả năng kết hợp JavaScript và HTML-like syntax, JSX không chỉ cải thiện developer experience mà còn tạo ra foundation vững chắc cho việc xây dựng các ứng dụng React phức tạp và scalable.

ReactJSXJavaScriptTutorial

Bài viết này cung cấp một cái nhìn toàn diện về JSX, từ các khái niệm cơ bản đến những pattern nâng cao. Hãy thực hành với các ví dụ để master JSX trong React development của bạn.