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.
Tuy nhiên, khi website có nhiều khu vực như Header, Sidebar, Product List và Footer, việc quản lý toàn bộ giao diện trong một file có thể khiến code khó đọc và khó bảo trì.
React giải quyết vấn đề này bằng cách tổ chức giao diện thành những thành phần nhỏ có thể tái sử dụng. Để bắt đầu làm việc với React, chúng ta cần hiểu ba khái niệm nền tảng: JSX, Components và Props.
2. JSX là gì?
JSX là cú pháp mở rộng của JavaScript, cho phép lập trình viên mô tả giao diện theo cách gần giống HTML ngay trong code JavaScript.
Ví dụ, với HTML thông thường:
<h1>Xin chào Khoa!</h1>
<p>Chào mừng bạn đến với website.</p>
Trong React, chúng ta có thể viết:
const element = (
<div>
<h1>Xin chào Khoa!</h1>
<p>Chào mừng bạn đến với website.</p>
</div>
);
Đoạn code trên sử dụng JSX để mô tả một phần giao diện. JSX không phải HTML nguyên bản; công cụ build sẽ chuyển đổi cú pháp này thành JavaScript mà React có thể xử lý.
2.1. Sử dụng JavaScript trong JSX
Một trong những ưu điểm của JSX là có thể hiển thị dữ liệu từ biến và biểu thức JavaScript bằng cặp dấu ngoặc nhọn {}.
function Welcome() {
const name = "Khoa";
const age = 21;
return (
<div>
<h1>Xin chào, {name}!</h1>
<p>Bạn {age} tuổi.</p>
<p>Năm sau bạn sẽ {age + 1} tuổi.</p>
</div>
);
}
Khi Component được render, React sẽ hiển thị giá trị của name, age và biểu thức age + 1.
Lưu ý rằng {} trong JSX dùng để nhúng biểu thức JavaScript, không phải để viết trực tiếp mọi câu lệnh. Chẳng hạn, bạn không thể đặt một câu lệnh if thông thường trực tiếp vào vị trí biểu thức JSX.
2.2. Một số quy tắc quan trọng của JSX
Quy tắc 1: Phải có một phần tử gốc hoặc sử dụng Fragment.
function App() {
return (
<>
<h1>Trang chủ</h1>
<p>Đây là website của tôi.</p>
</>
);
}
Fragment <>...</> giúp nhóm nhiều phần tử mà không cần tạo thêm một phần tử DOM bao quanh.
Quy tắc 2: Sử dụng className thay cho class.
<div className="container">Hello React</div>
Quy tắc 3: Đóng thẻ đúng cách.
<img src="/avatar.png" alt="Avatar" />
<input type="text" />
Quy tắc 4: Sử dụng tên thuộc tính phù hợp với JSX.
Ví dụ, htmlFor được dùng thay cho for trong thẻ label.
<label htmlFor="email">Email</label>
<input id="email" type="email" />
Những quy tắc này giúp bạn tránh nhiều lỗi cú pháp khi bắt đầu viết giao diện React.
3. Components là gì?
Component là một đơn vị giao diện độc lập có thể được tái sử dụng trong ứng dụng React.
Thay vì viết toàn bộ giao diện trong một khối code lớn, chúng ta có thể chia nó thành các Component nhỏ.
Ví dụ, một website bán hàng có thể được tổ chức như sau:
App
├── Header
├── ProductList
│ ├── ProductCard
│ ├── ProductCard
│ └── ProductCard
└── Footer
Mỗi Component đảm nhận một nhiệm vụ cụ thể. Header hiển thị phần đầu trang, ProductList quản lý khu vực danh sách sản phẩm, còn ProductCard mô tả giao diện của một sản phẩm.
3.1. Cách tạo một Component
Trong React hiện đại, Function Component là cách viết phổ biến.
function Header() {
return (
<header>
<h1>My Shop</h1>
<nav>
<a href="/">Trang chủ</a>
<a href="/products">Sản phẩm</a>
</nav>
</header>
);
}
export default Header;
Trong ví dụ trên:
Headerlà tên Component.- Hàm
Header()trả về JSX mô tả giao diện. export default Headercho phép file khác import Component này làm export mặc định.
Tên Component cần bắt đầu bằng chữ cái viết hoa để React phân biệt Component với các thẻ HTML như header, div hay p.
3.2. Sử dụng Component
Giả sử file Header.jsx chứa Component Header, bạn có thể sử dụng nó trong App.jsx:
import Header from "./Header";
function App() {
return (
<div>
<Header />
<main>
<h2>Chào mừng đến với My Shop</h2>
</main>
</div>
);
}
export default App;
Cú pháp <Header /> cho phép sử dụng Component như một phần của giao diện.
Điều này giúp chúng ta tái sử dụng cùng một Component ở nhiều vị trí thay vì sao chép toàn bộ phần code giao diện.
3.3. Nguyên tắc chia Component
Không phải cứ mỗi thẻ HTML là cần tạo một Component riêng. Việc chia Component nên dựa trên chức năng, khả năng tái sử dụng và độ phức tạp của giao diện.
Một số nguyên tắc hữu ích:
- Mỗi Component nên có nhiệm vụ tương đối rõ ràng.
- Những phần giao diện lặp lại có thể được tách thành Component dùng chung.
- Tránh tạo quá nhiều Component nhỏ nếu chúng không mang lại lợi ích về tổ chức code.
- Đặt tên Component thể hiện đúng chức năng của nó.
4. Props là gì?
Props là viết tắt của Properties, dùng để truyền dữ liệu từ Component cha xuống Component con.
Hãy tưởng tượng một danh sách sản phẩm có nhiều sản phẩm khác nhau. Nếu mỗi ProductCard đều viết cố định tên, giá và hình ảnh, chúng ta sẽ phải sao chép code nhiều lần.
Props giúp giải quyết vấn đề đó bằng cách cho phép một Component nhận dữ liệu khác nhau mỗi khi được sử dụng.
4.1. Truyền Props vào Component
Ví dụ:
function ProductCard(props) {
return (
<div className="product-card">
<h2>{props.name}</h2>
<p>Giá: {props.price} VNĐ</p>
</div>
);
}
function App() {
return (
<div>
<ProductCard name="Bàn phím" price={500000} />
<ProductCard name="Chuột máy tính" price={250000} />
</div>
);
}
Ở đây, App là Component cha, còn ProductCard là Component con.
Khi truyền:
<ProductCard name="Bàn phím" price={500000} />
React cung cấp các giá trị name và price cho Component thông qua đối tượng props.
Kết quả là hai sản phẩm có tên và giá khác nhau nhưng sử dụng chung một cấu trúc giao diện.
4.2. Sử dụng Destructuring với Props
Thay vì viết props.name và props.price nhiều lần, chúng ta có thể sử dụng Destructuring:
function ProductCard({ name, price }) {
return (
<div className="product-card">
<h2>{name}</h2>
<p>Giá: {price} VNĐ</p>
</div>
);
}
Cách viết này ngắn gọn hơn và thường được sử dụng trong các dự án React.
4.3. Truyền nhiều loại dữ liệu qua Props
Props không chỉ dùng để truyền chuỗi. Bạn có thể truyền số, boolean, mảng, object hoặc hàm.
function UserCard({ user, isOnline, onViewProfile }) {
return (
<div>
<h2>{user.name}</h2>
<p>{isOnline ? "Đang trực tuyến" : "Ngoại tuyến"}</p>
<button onClick={onViewProfile}>
Xem hồ sơ
</button>
</div>
);
}
function App() {
const user = {
name: "Khoa",
age: 21,
};
function handleViewProfile() {
console.log("Mở hồ sơ người dùng");
}
return (
<UserCard
user={user}
isOnline={true}
onViewProfile={handleViewProfile}
/>
);
}
Trong ví dụ trên:
userlà object chứa dữ liệu người dùng.isOnlinelà boolean xác định trạng thái trực tuyến.onViewProfilelà hàm được truyền từ Component cha xuống Component con.
Điều này giúp Component con có thể hiển thị dữ liệu và gọi hành vi do Component cha cung cấp.
4.4. Props có thể bị thay đổi trực tiếp không?
Props nên được xem là dữ liệu chỉ đọc bên trong Component nhận chúng.
Ví dụ không nên làm:
function ProductCard({ price }) {
price = price - 10000;
return <p>{price}</p>;
}
Thay vì thay đổi Props, hãy để Component cha quyết định dữ liệu cần truyền xuống hoặc sử dụng State nếu Component thực sự cần quản lý dữ liệu có thể thay đổi.
Đặc biệt, không nên sửa trực tiếp object hoặc mảng nhận qua Props. Việc thay đổi dữ liệu dùng chung có thể dẫn đến những lỗi khó theo dõi.
5. Kết hợp JSX, Components và Props
Ba khái niệm này có mối quan hệ chặt chẽ:
- JSX mô tả cấu trúc giao diện.
- Components chia giao diện thành các phần độc lập và có thể tái sử dụng.
- Props truyền dữ liệu từ Component cha xuống Component con.
Ví dụ tổng hợp:
function ProductCard({ name, price, inStock }) {
return (
<article className="product-card">
<h2>{name}</h2>
<p>Giá: {price.toLocaleString("vi-VN")} VNĐ</p>
<p>{inStock ? "Còn hàng" : "Hết hàng"}</p>
</article>
);
}
function App() {
const products = [
{ id: 1, name: "Bàn phím", price: 500000, inStock: true },
{ id: 2, name: "Chuột", price: 250000, inStock: false },
];
return (
<main>
<h1>Danh sách sản phẩm</h1>
{products.map((product) => (
<ProductCard
key={product.id}
name={product.name}
price={product.price}
inStock={product.inStock}
/>
))}
</main>
);
}
export default App;
Ví dụ này sử dụng JSX để mô tả giao diện, Component ProductCard để tái sử dụng cấu trúc sản phẩm và Props để truyền dữ liệu cho từng sản phẩm.
Thuộc tính key giúp React nhận diện các phần tử trong danh sách. Đây là chủ đề sẽ được tìm hiểu kỹ hơn khi học List Rendering.
6. Bài tập thực hành
Hãy xây dựng giao diện danh sách nhân viên bằng React.
Yêu cầu:
- Tạo Component
EmployeeCard. - Sử dụng Props để truyền tên, chức vụ và mức lương.
- Hiển thị thông tin bằng JSX.
- Tạo ít nhất ba nhân viên với dữ liệu khác nhau.
- Tách Component ra file riêng và import vào
App.jsx. - Thêm một Props boolean để hiển thị trạng thái đang làm việc hoặc đã nghỉ việc.
Bạn có thể mở rộng bài tập bằng cách bổ sung ảnh đại diện và một hàm xử lý khi nhấn nút xem chi tiết nhân viên.
7. Kết luận
JSX, Components và Props là ba nền tảng quan trọng khi bắt đầu học React. JSX giúp mô tả giao diện, Components giúp tổ chức và tái sử dụng code, còn Props cho phép truyền dữ liệu giữa các thành phần.
Khi hiểu rõ cách ba khái niệm này phối hợp với nhau, bạn sẽ dễ dàng chuyển từ những giao diện đơn giản sang các ứng dụng có cấu trúc rõ ràng hơn.
Bài tiếp theo: State, Events và Conditional Rendering – Quản lý trạng thái, xử lý tương tác và cập nhật giao diện trong React.





Khoá học lập trình game con rắn cho trẻ em




