Vấn đềAi cũng từng gặp phải trường hợp này. Bạn đang xây dựng một component đơn giản—có lẽ là một tiêu đề và một đoạn văn bản phụ—và bạn cố gắng trả về chúng nằm cạnh nhau. Bạn nhấn lưu, nhưng thay vì giao diện người dùng mới xuất hiện, một lỗi đỏ rực làm treo terminal hoặc console trình duyệt của bạn:
Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?
Đây là một trong những rào cản đầu tiên mà mọi lập trình viên React đều gặp phải. Nó không phải là lỗi logic; mà là một yêu cầu bắt buộc về cách JSX được xử lý ở phía sau.
Tại sao lỗi này xảy raJSX có vẻ giống HTML, nhưng thực chất nó là một lối viết tắt cho JavaScript. Các công cụ như Babel hoặc Vite chuyển đổi mọi thẻ bạn viết thành các lệnh gọi React.createElement(). React cần biết chính xác gốc (root) của component của bạn là gì.
Hãy xem xét đoạn mã không hợp lệ sau:
function MyComponent() {
return (
<h1>Hello World</h1>
<p>This is a description.</p>
);
}
Trình biên dịch cố gắng chuyển đoạn mã đó thành như thế này:
function MyComponent() {
return (
React.createElement('h1', null, 'Hello World')
React.createElement('p', null, 'This is a description.')
);
}
Trong JavaScript, một hàm không thể trả về hai giá trị cùng một lúc. Nó chỉ có thể trả về một đối tượng, chuỗi hoặc phần tử duy nhất. Bởi vì hai lệnh gọi createElement đó nằm cạnh nhau mà không có phần tử cha, JavaScript engine đơn giản là sẽ báo lỗi.
Quy trình gỡ lỗiIDE là người bạn tốt nhất của bạn trong trường hợp này. VS Code thường sẽ gạch chân đỏ dưới phần tử thứ hai ngay khi bạn vừa gõ xong. Nếu bạn đang tìm lỗi trong một tệp lớn, hãy làm theo các bước sau:
- Kiểm tra câu lệnh
returnxem có nhiều phần tử ở cấp cao nhất hay không.- Xác định xem bạn có thiếu thẻ đóng nào ở phía trên vị trí lỗi hay không.- Xem xét các hàm.map()nơi bạn có thể đang trả về hai phần tử cùng cấp mà không có thẻ bao bọc.## Các giải pháp từng bước### 1. Bao bọc bằng một phần tử chứaCách khắc phục nhanh nhất là bao bọc các phần tử của bạn trong một thẻ HTML tiêu chuẩn như<div>hoặc<section>.
function MyComponent() {
return (
<div className="container">
<h1>Hello World</h1>
<p>This is a description.</p>
</div>
);
}
Khi nào nên sử dụng: Chọn cách này nếu bạn cần một phần tử thực tế trong DOM để áp dụng CSS Flexbox, Grid hoặc các class định dạng cụ thể.
2. Sử dụng React FragmentsViệc thêm các thẻ <div> dư thừa có thể dẫn đến tình trạng "div soup" (quá nhiều thẻ div lồng nhau), làm rối DOM và có thể phá vỡ bố cục CSS. React Fragments cho phép bạn nhóm các phần tử mà không cần thêm một node thừa vào cây HTML của trình duyệt.
import { Fragment } from 'react';
function MyComponent() {
return (
<Fragment>
<h1>Hello World</h1>
<p>This is a description.</p>
</Fragment>
);
}
3. Cú pháp viết tắt (Được khuyến nghị)React hiện đại cung cấp một cách viết Fragments gọn gàng hơn nhiều. Hãy sử dụng các thẻ trống: <>...</>. Đây là tiêu chuẩn công nghiệp cho 90% các trường hợp.
function MyComponent() {
return (
<>
<h1>Hello World</h1>
<p>This is a description.</p>
</>
);
}
Mẹo nhỏ: Bạn không thể sử dụng cú pháp viết tắt này nếu cần truyền thuộc tính key (ví dụ: bên trong một vòng lặp). Trong trường hợp cụ thể đó, bạn phải sử dụng cú pháp tường minh <Fragment key={item.id}>.
4. Trả về một mảngMặc dù ít phổ biến hơn, bạn có thể trả về một mảng các phần tử. Cách này hữu ích khi cấu trúc giao diện của bạn là động, nhưng nó yêu cầu một key duy nhất cho mỗi mục.
function MyComponent() {
return [
<h1 key="header">Hello World</h1>,
<p key="desc">This is a description.</p>
];
}

