Vì JSX dịch thành lời gọi hàm, và một hàm JavaScript chỉ trả về được một giá trị. Ràng buộc này không phải luật riêng của React — nó là ràng buộc của chính ngôn ngữ.
// Bạn viết
return (
<h1>Tiêu đề</h1>
<p>Nội dung</p>
)
// Compiler nhìn thấy: hai giá trị đứng cạnh nhau, không có phép nối
return (
React.createElement('h1', null, 'Tiêu đề')
React.createElement('p', null, 'Nội dung')
)Đoạn thứ hai là lỗi cú pháp JavaScript thuần, không liên quan gì tới React. Vì vậy lỗi báo ra ở dạng "Adjacent JSX elements must be wrapped in an enclosing tag".
Muốn trả nhiều phần tử thì phải gom chúng thành một giá trị. Có ba cách:
// 1. Thẻ bọc thật — khi lớp thẻ đó có ý nghĩa với layout hoặc CSS
return <div className="card">...</div>
// 2. Fragment — khi không muốn thêm node nào vào DOM
return <>...</>
// 3. Mảng — hiếm dùng, và mỗi phần tử phải có key
return [<h1 key="t">Tiêu đề</h1>, <p key="b">Nội dung</p>]Chọn giữa cách 1 và cách 2 là câu hỏi thiết kế thật: thẻ bọc thừa làm phình DOM, phá vỡ ràng buộc cha–con của HTML (<div> không đặt được giữa <table> và <tr>), và biến nhiều phần tử thành một item duy nhất trong Flexbox hay Grid. Không cần thẻ thì dùng Fragment.
Lưu ý: Từ React 16 trở đi, component còn được phép trả về null, chuỗi, số hoặc mảng — nên "chỉ trả về một element" nói chính xác phải là "chỉ trả về một giá trị".