How to Avoid “Cannot Read Property ‘map’ of Undefined” in React When State is Initially Undefined? [duplicate]

I’m building a React application where I want to map over an array of items and render them as a list. The issue I’m facing is when the state is initially undefined, the map() function throws the following error:

Uncaught TypeError: Cannot read property ‘map’ of undefined

Here is the simplified version of my code:

import React, { useState, useEffect } from 'react';

function ItemList() {
  const [items, setItems] = useState(); // State initially undefined

  useEffect(() => {
    // Simulating an API call
    setTimeout(() => {
      setItems(['Item 1', 'Item 2', 'Item 3']);
    }, 2000);
  }, []);

  return (
    <div>
      <h1>Item List</h1>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default ItemList;

What I Tried

  • I know the error occurs because the state items is initially undefined, and map() cannot be called on undefined.
  • I tried adding a conditional check (if (items)), but it still causes issues when items is undefined for a short period after the initial render.
  • I also tried initializing the state with an empty array (useState([])), but I would like to understand the best practice for handling such cases where the state might be undefined for a brief moment.

Question

What is the best way to avoid this error while ensuring that the component works smoothly even when the data is being fetched asynchronously? Should I use a default value for the state or apply another method to handle this case efficiently?

New contributor

Lucifer is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

1

Add conditional rendering in case items are not available. you can follow this practice

return (
    <div>
      <h1>Item List</h1>
      {items ? (
        <ul>
          {items.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>
      ) : (
        <p>Loading items...</p>
      )}
    </div>
  );
}
New contributor

Bhavi Shah is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

this is a bit tricky to answer because, in theory, your question is not just a question about technical implementation, but also a consideration about how to approach fetching states in UI.

In short, you could just add a ? to items?.map()... This will make it so that the map call will only be executed if the items are not undefined.

I still would give you some further suggestions, on which you can chew:

Components in react should be as pure as possible (this is called: component-driven development).

So the first step would be to make “items” a prop of the component ItemList. This ensures we can handle the UI and Service layer in separate function calls, being able to maintain the logic for each in a more predictable manner.

One could argue the concern of an ItemsList can be both the rendering of the list itself and also a state indicating that the Items are currently being fetched, in which case you would display some sort of skeleton / loading spinner, whatever you like.

You could also split these two components in: ItemsList and ItemsListLoading (or something along those lines). The decision can be made depending on the complexity of the loading state, which might actually be much more complicated in some cases.

In my opinion its best to keep data-based props always to a “defined” state and assuming the components will only render with a “defined” data set.

function ItemList({items}:{items: string[]}){

  return items.map(...)

}

And then in some sort of DataContainer you could have something like this:


import ItemsList from "..."
import useItemsList from  "..."

function ItemsListDataContainer({items}:{items: string[]}){

  const {isLoading, data} = useItemsList()
  return isLoading ? <p>Is Loading items...</p> : <ItemsList items={data}/>

}

Again this is just a solution, Note that I put the logic for fetching in a hook. That is a best practice in react, try to compute and retrieve state in as much functional ways as possible, i.e. writing functions that have a clear in and output and expose the necessary API from the return of the given function.

Hope that helps you a bit to get some ideas how to approach these kinds of problems 🙂

Best practice is to use the correct initial state. Think about it: “you have no items” => “you have zero items” => “you have a container with zero items”.

A popular example: a shopping cart. You don’t have “an undefined shopping cart”. You have an empty cart.

However, these are “valid” methods:

  1. In your example, the initial state of items should be an empty array, not undefined. So you should use [] as the initial state.
  2. You can also add a conditional rendering as suggested if you want to hide the component completely if there are no items.
  3. Or you can use (items || []) as a fallback (brrr…, not my preferred solution).

example for (1), preferred

import React, { useState, useEffect } from 'react';

function ItemList() {
  const [items, setItems] = useState([]); // (1)

  useEffect(() => {
    // Simulating an API call
    setTimeout(() => {
      setItems(['Item 1', 'Item 2', 'Item 3']);
    }, 2000);
  }, []);

  return (
    <div>
      <h1>Item List</h1>
      <ul>
        {items.map((item, index) => (
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default ItemList;

example for (2)

import React, { useState, useEffect } from 'react';

function ItemList() {
  const [items, setItems] = useState();

  useEffect(() => {
    // Simulating an API call
    setTimeout(() => {
      setItems(['Item 1', 'Item 2', 'Item 3']);
    }, 2000);
  }, []);

  return (
    <div>
      <h1>Item List</h1>
      {(items?.length > 0) && // (2)
        (<ul>
          {items.map((item, index) => (
            <li key={index}>{item}</li>
          ))}
        </ul>)
      }
    </div>
  );
}

export default ItemList;

example for (3)

import React, { useState, useEffect } from 'react';

function ItemList() {
  const [items, setItems] = useState();

  useEffect(() => {
    // Simulating an API call
    setTimeout(() => {
      setItems(['Item 1', 'Item 2', 'Item 3']);
    }, 2000);
  }, []);

  return (
    <div>
      <h1>Item List</h1>
      <ul>
        {(items || []).map((item, index) => ( // (3)
          <li key={index}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

export default ItemList;

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật