JSX là một khái niệm cốt lõi trong React – nếu bạn đang hoặc sẽ học React, hiểu rõ JSX là bắt buộc. Dưới đây là bài viết tổng hợp chi tiết về JSX trong React, bao gồm định nghĩa, lý do sử dụng, cú pháp, ví dụ và các lưu ý quan trọng.
JSX (JavaScript XML) là một cú pháp mở rộng của JavaScript, cho phép bạn viết HTML bên trong JavaScript. JSX được sử dụng trong React để mô tả giao diện người dùng một cách trực quan và dễ hiểu hơn.
Ví dụ:
const element = <h1>Hello, world!</h1>;
Dòng trên không phải là HTML thuần, mà là JSX. Trình biên dịch như Babel sẽ chuyển JSX thành JavaScript gọi hàm React.createElement
.
JSX giúp viết cấu trúc giao diện (UI) dễ hiểu hơn, gần giống HTML.
Bạn có thể nhúng các biến, biểu thức, hàm JavaScript vào JSX bằng cú pháp {}
.
const name = 'John';
const element = <h1>Hello, {name}!</h1>;
JSX giúp phát hiện lỗi cú pháp sớm hơn trong quá trình build.
// Sai ❌
return (
<h1>Title</h1>
<p>Subtitle</p>
);
// Đúng ✅
return (
<div>
<h1>Title</h1>
<p>Subtitle</p>
</div>
);
{}
để nhúng biểu thức JavaScriptconst age = 25;
return <p>Tuổi: {age}</p>;
className
thay vì class
return <div className="container">Nội dung</div>;
htmlFor
thay vì for
trong thẻ <label>
<label htmlFor="email">Email</label>
<input id="email" />
const isLoggedIn = true;
return <p>{isLoggedIn ? 'Welcome' : 'Please login'}</p>;
.map()
const items = ['Táo', 'Cam', 'Chuối'];
return (
<ul>
{items.map((item, index) => <li key={index}>{item}</li>)}
</ul>
);
<div>
bọc ngoàireturn (
<>
<h1>Tiêu đề</h1>
<p>Mô tả</p>
</>
);
Lưu ý | Giải thích |
---|---|
JSX phải có thẻ cha bao ngoài | Vì mỗi component chỉ return được một phần tử gốc |
key là bắt buộc khi render list | Để React xác định và cập nhật chính xác |
Không dùng if trực tiếp trong JSX | Thay vào đó dùng && , ? : hoặc viết logic trước return |
JSX chỉ cho phép biểu thức, không cho phép câu lệnh | Không thể dùng if , for trong JSX trực tiếp |
Dưới đây là ví dụ JSX và JavaScript tương đương:
const element = <h1 className="title">Hello</h1>;
Sẽ được Babel biên dịch thành:
const element = React.createElement('h1', { className: 'title' }, 'Hello');
function Welcome(props) {
return <h1>Xin chào, {props.name}</h1>;
}
function UserCard({ user }) {
return (
<div className="card">
<h2>{user.name}</h2>
<p>Email: {user.email}</p>
</div>
);
}
Thuộc tính | JSX |
---|---|
Tên đầy đủ | JavaScript XML |
Dùng trong | React |
Ưu điểm | Dễ đọc, trực quan, gắn liền JavaScript |
Nhược điểm | Cần trình biên dịch (như Babel) để chạy trên trình duyệt |
Không bắt buộc | Bạn có thể dùng React mà không cần JSX, nhưng sẽ rất rối |
JSX không phải là HTML – nó chỉ giúp bạn viết code giống HTML trong JavaScript. Khi build, JSX sẽ được biên dịch thành React.createElement
:
const element = <h1>Hello</h1>;
Sẽ được Babel chuyển thành:
const element = React.createElement(
'h1',
null,
'Hello'
);
Mỗi phần tử JSX tạo ra một React Element – là một object đơn giản mô tả những gì sẽ xuất hiện trên UI.
HTML | JSX |
---|---|
<div tabindex="0"> | <div tabIndex={0}> |
<input maxlength="5"> | <input maxLength={5}> |
onClick
, onChange
, onMouseEnter
,...function handleClick() {
alert('Đã click!');
}
<button onClick={handleClick}>Click me</button>
Không thể dùng if/else
trực tiếp trong JSX, nhưng có 3 cách phổ biến để render có điều kiện:
? :
{isLoggedIn ? <p>Chào mừng!</p> : <p>Vui lòng đăng nhập.</p>}
&&
{hasError && <p style={{ color: 'red' }}>Có lỗi xảy ra</p>}
let content;
if (loading) {
content = <p>Đang tải...</p>;
} else {
content = <p>Dữ liệu đã tải.</p>;
}
return <div>{content}</div>;
map()
React thường xuyên hiển thị danh sách, như danh sách bài viết, sản phẩm, bình luận,... JSX không hỗ trợ for
, thay vào đó bạn dùng .map()
:
const fruits = ['Táo', 'Cam', 'Chuối'];
return (
<ul>
{fruits.map((fruit, index) => (
<li key={index}>{fruit}</li>
))}
</ul>
);
key
?Key giúp React nhận diện phần tử nào thay đổi, thêm hoặc xóa để cập nhật hiệu quả mà không render lại toàn bộ DOM.
Lưu ý: Không nên dùng
index
làm key trong danh sách có thể thay đổi thứ tự.
Bạn có thể thêm style trực tiếp bằng object JavaScript:
const style = {
color: 'blue',
fontSize: '20px'
};
return <p style={style}>Chữ màu xanh</p>;
⚠️ Tên thuộc tính CSS cũng viết camelCase:
backgroundColor
,fontSize
,...
function Card({ title, children }) {
return (
<div className="card">
<h3>{title}</h3>
<div>{children}</div>
</div>
);
}
function App() {
return (
<Card title="Giới thiệu">
<p>Đây là nội dung bên trong thẻ Card.</p>
</Card>
);
}
children
là tất cả nội dung nằm giữa cặp thẻ<Card>...</Card>
Thói quen xấu ❌ | Cách tốt ✅ |
---|---|
JSX dài dòng trong return | Tách component nhỏ |
Không đặt key khi dùng .map() | Luôn thêm key |
Inline function phức tạp | Tách ra ngoài |
Quá nhiều điều kiện lồng nhau | Viết logic ngoài return |
Fragment
khi không muốn tạo thêm thẻ HTML<>
<h1>Tiêu đề</h1>
<p>Mô tả</p>
</>
Tương đương với:
<React.Fragment>
<h1>Tiêu đề</h1>
<p>Mô tả</p>
</React.Fragment>
function Welcome() {
return <h1>Xin chào!</h1>;
}
// Đúng
<Welcome />
// Sai - sẽ bị React hiểu là thẻ HTML <welcome>
<welcome />
JSX
├── Là gì: JavaScript XML
├── Viết UI giống HTML
├── Ưu điểm: dễ đọc, kết hợp logic JS
├── Cần Babel để compile
├── Dùng props, sự kiện, render có điều kiện
├── Duyệt mảng với map() + key
├── Dùng Fragment để tránh thẻ thừa
├── Clean code: tách component, hạn chế logic phức tạp trong JSX