Uncaught TypeError: Cannot read properties of undefined (reading 'map')

React map() fails on undefined array props

You're calling .map() on something that's undefined. Usually it's a prop that hasn't arrived yet or a state that starts as undefined.

What's actually happening here

You're rendering a component that calls array.map(...), but array is undefined at the time React tries to render. This almost always means a prop hasn't been passed yet (async data fetch) or it was passed but its initial value is undefined.

I see this most often when people fetch data from an API inside useEffect and try to render the result immediately. The component mounts, data is undefined, and React throws before the fetch completes.

The 30-second fix: Default value in destructuring

This is the one-liner every React dev should know. In the component that receives the array prop, give it a default empty array:

function List({ items = [] }) {
  return items.map(item => <li>{item}</li>);
}

If items is undefined, it falls back to []. .map() on an empty array returns an empty array—no crash. This fix works 80% of the time because the data eventually arrives and React re-renders.

But what if items is passed as null? Then this won't help—null isn't undefined. You'd still get a crash because null = [] doesn't apply. Destructuring defaults only kick in for undefined. For that, use the next fix.

The 5-minute fix: Guard clause or optional chaining

When you can't control the parent component's behavior—maybe a third-party library or legacy code—guard the render yourself.

Option A: Guard clause

function List({ items }) {
  if (!items) return null;
  return items.map(item => <li>{item}</li>);
}

This checks if items is falsy (undefined, null, false, 0, ''). If it is, render nothing. The component stays alive, the parent doesn't break, and when items eventually arrives, React re-renders it.

Option B: Optional chaining + fallback

function List({ items }) {
  return (items ?? []).map(item => <li>{item}</li>);
}

The ?? (nullish coalescing) operator only falls through for undefined or null. Unlike ||, it won't replace false or 0 with an empty array—useful when items might legitimately be an empty array or number.

Use optional chaining items?.map(...) only if you want to silently skip the map entirely when items is undefined. But then you get no output, which might hide the bug.

The 15+ minute fix: Trace the data flow and fix the root cause

Band-aids work, but they rot. The real problem is upstream—something in your data flow doesn't deliver the array before the first render.

Step 1: Check your initial state

If you're using useState to hold fetched data, initialize it as an empty array:

const [data, setData] = useState([]);

Not useState() or useState(null). The initial value is what React uses on the first render. An empty array is safe to map over.

Step 2: Verify the prop is actually being passed

Go to the parent component that renders your List. Does it pass items={someData}? If someData is undefined because it comes from another fetch, you've just pushed the problem up. Check that parent's state initialization too.

Step 3: Use useEffect to sync data correctly

If you're fetching data inside the same component, the structure should be:

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

  useEffect(() => {
    fetch('/api/items')
      .then(res => res.json())
      .then(data => setItems(data));
  }, []);

  return <List items={items} />;
}

Notice: items starts as [], so even before the fetch completes, List gets an empty array. No crash.

Step 4: Handle loading and error states

Once the band-aid is gone, add a loading state:

const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true);

useEffect(() => {
  fetch('/api/items')
    .then(res => res.json())
    .then(data => {
      setItems(data);
      setLoading(false);
    });
}, []);

if (loading) return <p>Loading...</p>;
return <List items={items} />;

This also prevents a flash of empty list before the data arrives.

Why this error is so common in React

React renders synchronously, but data fetching is asynchronous. The first render happens before the fetch resolves. If your state starts as undefined, React will try to call .map() on it and throw. The error message literally says Cannot read properties of undefined (reading 'map')—it's a runtime type error, not a React bug. Your array is missing.

The fix is always: either ensure the array exists at render time (default value, guard clause) or don't render until the data is ready (loading state). Pick whichever fits your situation. The 30-second fix is fine for a prototype, but for production, do the 15-minute fix. Your future self will thank you when you're debugging at 2 AM.

Related Errors in Programming & Dev Tools
0X00000282 Fix ERROR_PORT_NOT_SET (0X00000282) in 3 Steps 0XC0000409 Fix STATUS_STACK_BUFFER_OVERRUN 0xC0000409 Fast 0X000002BE ERROR_SEGMENT_NOTIFICATION (0X000002BE): The Real Fixes 0X000002FF Fixing ERROR_DBG_CONTINUE (0X000002FF) in Visual Studio Debugger

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.