Sửa lỗi 'TypeError: data.map is not a function' trong React

beginner⚛️ React2026-06-05| React (mọi phiên bản), Node.js, các trình duyệt web hiện đại

Error Message

TypeError: data.map is not a function
#react#javascript#frontend#debugging#api

Phân tích lỗi màn hình trắngTất cả chúng ta đều từng gặp trường hợp này. Bạn vừa viết xong một component danh sách sạch đẹp, trình duyệt tải lại, và thay vì thấy dữ liệu, bạn lại đối mặt với một màn hình trắng tinh. Bạn mở console và tìm thấy thủ phạm: TypeError: data.map is not a function.

Điều này xảy ra vì phương thức .map() của JavaScript chỉ tồn tại duy nhất trên prototype của Array. Nếu biến của bạn là một object, một chuỗi, null, hoặc undefined, engine sẽ không biết phải xử lý thế nào. Trong hệ sinh thái React, lỗi này thường ám chỉ sự đứt gãy trong luồng dữ liệu từ state hoặc từ một API bên ngoài.

Thông báo lỗi chính xác```

TypeError: data.map is not a function


## Tại sao lỗi này xảy raTheo kinh nghiệm của tôi, 90% các trường hợp crash này rơi vào một trong ba tình huống sau:
- **Khởi đầu trống rỗng:** Bạn khởi tạo state là `null` hoặc để trống, nhưng JSX của bạn đã cố gắng render nó trước khi lần gọi API đầu tiên kết thúc.- **Object bao bọc:** API trả về một response như `{ "users": [1, 2, 3] }`, nhưng bạn lại cố gắng map trên object cấp cao nhất thay vì mảng `users`.- **Kết quả đơn lẻ:** Backend trả về một object đơn lẻ thay vì một mảng khi chỉ tìm thấy một mục duy nhất.## Cách khắc phục### 1. Khởi tạo State đúng cáchCác component React thường render ít nhất một lần trước khi hook `useEffect` của bạn bắt đầu lấy dữ liệu. Nếu bạn khởi tạo state là `undefined`, lần render đầu tiên đó sẽ cố gắng gọi `undefined.map()`, gây ra lỗi crash ngay lập tức.
**Vấn đề:**

const [items, setItems] = useState(); // Mặc định là undefined

return (

Cách khắc phục: Luôn để mặc định là một mảng rỗng []. Điều này cho phép lần render đầu tiên hoàn tất thành công, không hiển thị gì cho đến khi dữ liệu thực sự được tải về.

const [items, setItems] = useState([]); // An toàn và dễ dự đoán

2. Sử dụng Optional ChainingNếu bạn không thể đảm bảo dữ liệu của mình luôn là một mảng, toán tử optional chaining (?.) là người bạn đồng hành tốt nhất. Nó đóng vai trò như một van an toàn. Nếu biến là nullish, biểu thức sẽ ngắt mạch và trả về undefined thay vì gây ra lỗi.

return (
  <ul>
    {data?.map(user => (
      <li key={user.id}>{user.username}</li>
    ))}
  </ul>
);

3. Truy cập sâu vào API ResponseNhiều lập trình viên mặc định rằng response.data là mảng họ cần. Tuy nhiên, các API hiện đại thường bao bọc kết quả trong metadata. Giả sử bạn mong đợi 50 sản phẩm, nhưng API gửi về { "count": 50, "products": [...] }. Việc map trực tiếp trên response sẽ thất bại vì response là một JSON object.

Cách khắc phục: Kiểm tra cấu trúc dữ liệu ngay sau khi fetch. Sử dụng giá trị dự phòng (fallback) để ngăn state bị biến thành null.

useEffect(() => {
  axios.get('/api/products').then(res => {
    // Đảm bảo chúng ta đang set mảng, không phải object bao bọc
    setProducts(res.data.products || []); 
  });
}, []);

4. Thêm kiểm tra kiểu dữ liệu phòng vệKhi làm việc với các hệ thống cũ không thể dự đoán trước, đôi khi bạn cần một câu lệnh bảo vệ nghiêm ngặt. Sử dụng Array.isArray() đảm bảo mã của bạn chỉ cố gắng lặp nếu dữ liệu thực sự là một mảng.

if (!Array.isArray(data)) {
  return <p>Đang tải hoặc định dạng dữ liệu không hợp lệ...</p>;
}

return data.map(item => <div>{item.title}</div>);

Các bước xác minhSau khi áp dụng bản sửa lỗi, hãy xác minh bằng các bước sau:

  • Kiểm tra Console: Mở Chrome DevTools (F12) và đảm bảo dòng chữ lỗi màu đỏ đã biến mất sau khi tải lại trang.- React DevTools: Kiểm tra phần "Hooks" cho component của bạn. Xác nhận rằng state bắt đầu bằng một mảng rỗng [].- Giới hạn băng thông mạng: Sử dụng cài đặt "Slow 3G" trong tab Network. Điều này giúp kiểm tra xem UI của bạn có xử lý tốt "khoảng thời gian chờ" trước khi mảng dữ liệu đổ về mà không bị crash hay không.## Chủ động phòng ngừa- TypeScript: Định nghĩa kiểu dữ liệu cho state một cách chặt chẽ (ví dụ: useState<User[]>([])). Điều này giúp phát hiện các lỗi map tiềm ẩn trong quá trình phát triển thay vì lúc runtime.- Giá trị mặc định cho Prop: Nếu một component con nhận một danh sách, hãy sử dụng giá trị mặc định khi destructuring: const List = ({ items = [] }) => { ... }.- Làm sạch dữ liệu: Luôn coi dữ liệu API bên ngoài là không đáng tin cậy. Hãy map hoặc lọc nó về định dạng bạn cần trước khi lưu vào state cục bộ.

Related Error Notes