Trong quá trình phát triển ứng dụng React, việc điều khiển giao diện hiển thị dựa trên trạng thái (state) hoặc thuộc tính (props) là một tác vụ cực kỳ phổ biến. Kỹ thuật này được gọi là render theo điều kiện (Conditional Rendering). Việc áp dụng đúng phương pháp không chỉ giúp mã nguồn sạch sẽ mà còn tối ưu hóa hiệu suất ứng dụng.
1. Các phương pháp thực thi phổ biến
Sử dụng câu lệnh If-Else hoặc biến hỗ trợ
Đây là cách tiếp cận cơ bản nhất, thường được sử dụng bên ngoài khối JSX hoặc để thực hiện "Early Return" (trả về sớm) nhằm giảm độ phức tạp của component.
function AuthStatus({ isAuthenticated }) {
if (isAuthenticated) {
return <button>Đăng xuất</button>;
}
return <button>Đăng nhập ngay</button>;
}
Toán tử ba ngôi (Ternary Operator)
Khi bạn cần quyết định giữa hai khối mã ngay bên trong JSX, toán tử ba ngôi là lựa chọn tối ưu vì tính ngắn gọn.
const ProfileHeader = ({ username }) => {
return (
<header>
{username ? <h1>Chào mừng, {username}!</h1> : <h1>Chào khách!</h1>}
</header>
);
};
Toán tử logic AND (&&)
Phương pháp này cực kỳ hữu ích khi bạn chỉ muốn hiển thị một thành phần nếu điều kiện là đúng, và không hiển thị gì nếu điều kiện sai.
const NotificationBadge = ({ count }) => {
return (
<div>
<i className="icon-bell"></i>
{count > 0 && <span className="badge">{count}</span>}
</div>
);
};
Lưu ý: Hãy cẩn thận với các giá trị như số 0. Nếu count là 0, React vẫn sẽ render số 0 ra giao diện. Để an toàn, hãy ép kiểu về boolean: {!!count && ...}.
2. Kỹ thuật quản lý logic phức tạp
Khi ứng dụng có quá nhiều điều kiện lồng nhau, việc viết trực tiếp trong JSX sẽ khiến mã nguồn trở nên khó đọc. Dưới đây là các cách để làm sạch code:
Sử dụng Object Mapping
Thay vì dùng nhiều câu lệnh if-else hoặc switch-case, bạn có thể sử dụng một đối tượng để ánh xạ các trạng thái.
const STATUS_COMPONENTS = {
loading: <Spinner />,
error: <ErrorMessage />,
success: <DataList />,
};
function Content({ status }) {
return (
<main>
{STATUS_COMPONENTS[status] || <EmptyState />}
</main>
);
}
Tách biệt logic thành hàm hỗ trợ
Việc chuyển logic kiểm tra ra một hàm riêng giúp component chính tập trung vào cấu trúc giao diện.
function renderUserAction(role, onAction) {
switch (role) {
case 'admin':
return <button onClick={onAction}>Quản trị hệ thống</button>;
case 'editor':
return <button onClick={onAction}>Chỉnh sửa bài viết</button>;
default:
return null;
}
}
const ActionBar = ({ userRole, handleEvent }) => (
<div className="toolbar">
{renderUserAction(userRole, handleEvent)}
</div>
);
3. Các lưu ý để tối ưu hóa code
- Hạn chế lồng toán tử ba ngôi: Việc lồng nhiều tầng
condition ? a : b ? c : dlà một "anti-pattern" gây khó khăn cho việc bảo trì. Hãy tách chúng thành các component nhỏ hơn. - Early Return: Nếu một component không cần render gì trong một điều kiện nhất định, hãy trả về
nullngay ở đầu hàm. - Sử dụng biến tạm: Nếu một điều kiện được sử dụng nhiều lần trong JSX, hãy tính toán giá trị đó một lần và lưu vào biến trước khi
return.
4. Ứng dụng Higher-Order Components (HOC)
Trong các dự án lớn, bạn có thể đóng gói logic render theo điều kiện (ví dụ: kiểm tra quyền truy cập) vào một HOC để tái sử dụng ở nhiều nơi.
function withPermission(WrappedComponent) {
return function ProtectedComponent({ isAdmin, ...props }) {
if (!isAdmin) {
return <div>Bạn không có quyền truy cập vào khu vực này.</div>;
}
return <WrappedComponent {...props} />;
};
}
const AdminPanel = ({ data }) => <section>{/* Nội dung quản trị */}</section>;
const RestrictedAdminPanel = withPermission(AdminPanel);