Sửa lỗi "Objects are not valid as a React child" trong React

beginner⚛️ React2026-03-22| React 16+, Next.js, Create React App — bất kỳ môi trường JavaScript nào render JSX

Error Message

Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.
#react#render#object#json

Lỗi Gặp Phải

Component của bạn ném ra lỗi này trong console trình duyệt:

Objects are not valid as a React child. If you meant to render a collection of children, use an array instead.

Ứng dụng bị crash hoặc hiển thị trắng tinh. Stack trace trỏ vào đâu đó bên trong JSX — nhưng thủ phạm thực sự thường nằm vài dòng phía trên đó.

Nguyên Nhân Gốc Rễ

React biết cách render chuỗi, số, boolean, mảng và các React element. Còn plain JavaScript object và Promise? Nó không biết phải xử lý thế nào. Truyền một trong những thứ đó làm JSX child là React sẽ dừng lại với lỗi này.

Những nguyên nhân thường gặp:

  • Render cả một object {user} thay vì một trường cụ thể như {user.name}
  • Render một object Datenew Date() không phải là chuỗi, dù trông có vẻ giống
  • Render một Promise — bạn quên await cho lời gọi async đó
  • Đưa thẳng response API thô vào JSX mà chưa trỏ vào giá trị cụ thể
  • Gọi Object.keys() hoặc Object.entries() rồi quên .map() qua kết quả

Cách Tìm Nguyên Nhân Chính Xác

Kiểm tra toàn bộ thông báo lỗi trong console trình duyệt. React khá hữu ích trong trường hợp này:

Error: Objects are not valid as a React child (found: object with keys {id, name, email}).

Những key đó chính là manh mối. Tìm trong component của bạn bất kỳ chỗ nào mà object có dạng đó được đưa vào JSX.

Vẫn chưa rõ ràng? Thêm một dòng log nhanh ngay trước phần return:

console.log(typeof someVariable, someVariable);

Nếu typeof trả về "object" và biến đó được dùng làm child — bạn đã tìm ra thủ phạm.

Cách Sửa 1 — Truy Cập Thuộc Tính, Không Phải Cả Object

Chín phần mười, đây là vấn đề. Bạn truyền cả object trong khi chỉ cần một trường duy nhất.

// ❌ Sai — render toàn bộ object user
function UserCard({ user }) {
  return {user}
;
}

// ✅ Đúng — render một thuộc tính cụ thể
function UserCard({ user }) {
  return {user.name}
;
}

Cách Sửa 2 — Chuyển Object Date Thành Chuỗi

Object Date không thể render được. Hãy dùng một phương thức chuỗi: .toLocaleDateString(), .toISOString(), hoặc .toLocaleString() tùy theo định dạng bạn muốn hiển thị.

// ❌ Sai
const createdAt = new Date(post.createdAt);
return {createdAt};

// ✅ Đúng
return {createdAt.toLocaleDateString()};

Cách Sửa 3 — Await Promise Trước Khi Render

Hàm async trả về Promise. Gọi mà không có await thì bạn nhận lại một object Promise — không phải dữ liệu bên trong nó.

// ❌ Sai — fetchUser trả về Promise, không phải user
function Profile() {
  const user = fetchUser();
  return {user.name}
;
}

// ✅ Đúng — useEffect + useState xử lý vòng đời async
function Profile() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser().then(setUser);
  }, []);

  if (!user) return Đang tải...
;
  return {user.name}
;
}

Cách Sửa 4 — Stringify JSON Để Debug

Muốn xem thử dữ liệu API thô trong quá trình phát triển? Dùng JSON.stringify(). Truyền thẳng object vào sẽ không hoạt động.

// ❌ Sai — render cả object
return ```
{data}
```;

// ✅ Đúng — chuỗi JSON dễ đọc, có thụt lề
return ```
{JSON.stringify(data, null, 2)}
```;

Hãy xóa đoạn này trước khi đưa lên production — đây là công cụ debug, không phải UI thực sự.

Cách Sửa 5 — Map Qua Collection Đúng Cách

Object.entries() trả về mảng các cặp [key, value]. Mảng đó không tự render được — bạn vẫn cần .map() nó thành các JSX element.

// ❌ Sai — Object.entries trả về mảng của mảng, không phải JSX
const settings = { theme: 'dark', lang: 'en' };
return {Object.entries(settings)};

// ✅ Đúng — mỗi entry trở thành một list item
return (
  
    {Object.entries(settings).map(([key, value]) => (
      - {key}: {value}
    ))}
  
);

Cách Sửa 6 — Bảo Vệ Khỏi Kiểu Dữ Liệu Không Xác Định

Đôi khi bạn không kiểm soát được dữ liệu trả về có dạng gì — đặc biệt với API của bên thứ ba. Hãy thêm kiểm tra kiểu dữ liệu trước khi render.

// ❌ Sai — crash nếu response là object, không phải chuỗi
return {response}
;

// ✅ An toàn — chỉ render nếu thực sự là chuỗi hoặc số
return {typeof response === 'string' ? response : null}
;

Kiểm Tra Sau Khi Sửa

Sau khi sửa, ba điều sau phải đúng:

  • Overlay lỗi trong trình duyệt đã biến mất
  • Component render bình thường không bị crash
  • Bộ test của bạn pass: npm test hoặc pnpm test

Nếu lỗi vẫn còn, object có thể đang đến từ phần khác trong cây component. Hãy theo dõi các key được liệt kê trong thông báo lỗi — chúng sẽ dẫn bạn đến đúng chỗ.

Mẹo Phòng Tránh

TypeScript phát hiện lỗi này ngay lúc biên dịch. Khai báo kiểu cho prop là string và TypeScript sẽ không cho phép bạn vô tình truyền vào một object User. Điều này loại bỏ hoàn toàn nhóm lỗi này trước khi trình duyệt nhìn thấy.

interface Props {
  name: string; // người gọi phải truyền chuỗi, không phải object
}

function Label({ name }: Props) {
  return {name};
}

Destructure response API ngay tại điểm nhận dữ liệu. Lấy ra những trường bạn thực sự cần ngay tại nơi dữ liệu đi vào ứng dụng — trước khi nó lan ra các component. Với JSON lồng sâu hoặc không quen thuộc, hãy paste response vào JSON Formatter & Validator để hiển thị trực quan cấu trúc và xác định chính xác các key cần dùng. Mọi thứ chạy trên trình duyệt; không có gì bị tải lên.

Không dùng TypeScript? Hãy dùng PropTypes để validate nhẹ tại runtime:

import PropTypes from 'prop-types';

UserCard.propTypes = {
  user: PropTypes.shape({
    name: PropTypes.string.isRequired,
  }).isRequired,
};

Related Error Notes