Home/Blog/Cannot read properties of undefined (reading 'map') ? React/JS Fix Guide
??
javascriptreactfrontend

Cannot read properties of undefined (reading 'map') ? React/JS Fix Guide

This error means .map() was called on a value that isn't an array. Learn the five root causes ? async timing, API shape mismatches, null returns ? and the guards that fix each one.

May 22, 20264 min readby ToolNinja

The Exact Error

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

Or in older JavaScript:

TypeError: Cannot read property 'map' of undefined
TypeError: Cannot read property 'map' of null

Quick summary: .map() is an Array method. You called it on a value that is undefined or null instead of an array. The data either hasn't loaded yet, the API returned an unexpected shape, or a default value is missing.


Why This Error Happens

.map() is only defined on arrays. When you write data.map(item => ...), JavaScript looks up the map property on data. If data is undefined or null, there is no map property.

Five common root causes:

1. Async timing ? React renders the component immediately but the fetch hasn't completed. Your initial state is null or undefined.

2. API shape mismatch ? You expect { items: [...] } but the API returns { data: { items: [...] } } (one level deeper).

3. API returns null on empty ? Some backends return null instead of [] when there are no results.

4. Wrong destructuring ? const { items } = response.data when response.data is undefined.

5. Race condition ? A re-render happens after data is cleared but before new data arrives.


Step-by-Step Diagnosis

Step 1 ? Add console.log just before the error

console.log('data value:', data);
console.log('data type:', typeof data);
console.log('is array:', Array.isArray(data));
data.map(item => item.name); // Error is on this line

Step 2 ? Check the Network tab in DevTools

Open DevTools ? Network tab ? find your API request ? Response tab. Compare the actual JSON to what your code expects.

Step 3 ? Check your initial state

// WRONG:
const [users, setUsers] = useState(null);

// RIGHT:
const [users, setUsers] = useState([]);

Solutions

Solution 1 ? Initialize state as an empty array

const [items, setItems] = useState([]);

Solution 2 ? Use optional chaining with a fallback

{(data?.items ?? []).map(item => (
  <div key={item.id}>{item.name}</div>
))}

Solution 3 ? Normalize API response at fetch time

async function fetchUsers() {
  const response = await fetch('/api/users');
  const json = await response.json();
  const users = Array.isArray(json) ? json
    : Array.isArray(json?.users) ? json.users
    : Array.isArray(json?.data) ? json.data
    : [];
  setUsers(users);
}

Solution 4 ? Guard with a loading state

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

if (loading) return <Spinner />;
return items.map(item => <ItemCard key={item.id} item={item} />);

Solution 5 ? TypeScript to catch at compile time

const [users, setUsers] = useState<User[]>([]);
users.map(u => u.name); // TypeScript knows users is always User[]

Quick Reference

SymptomLikely CauseFix
Error on first render onlyInitial state is null/undefineduseState([])
Error for some users, not othersConditional data fetchingGuard with ?? []
Works in dev, fails in prodDifferent API response in prodLog raw response
API returns null for empty resultsBackend null vs empty arrayNormalize: data?.items ?? []

Prevent This Error in the Future

1. Always initialize array state with [] ? never null or undefined.

2. Add a normalization layer between your API calls and state. All data entering your app should be validated and defaulted to safe values.

3. Use TypeScript with strict null checks (strictNullChecks: true).


Use ToolNinja to Debug Faster

When the actual API response doesn't match what your code expects, the JSON Formatter helps you quickly understand the structure. Paste the raw API response to see it formatted with proper indentation.

?? JSON Formatter ? toolninja.io/tools/json-formatter

Share:𝕏 Twitterin LinkedIn

Frequently Asked Questions

Why does this error happen in React but not in plain JavaScript?

React renders synchronously but data fetches are asynchronous. When a component first renders, state is in its initial value (often undefined or null) because the API call hasn't completed yet. The fix is to initialize state as an empty array ([]) instead of null/undefined.

What is optional chaining and does it fix this error?

Optional chaining (?.) short-circuits to undefined instead of throwing when a property doesn't exist. data?.map(fn) returns undefined instead of throwing if data is undefined. However, this often just silently produces no output. The better fix is to ensure data is always initialized as an empty array.

How do I handle API responses that sometimes return null instead of an empty array?

Normalize at the point of data ingestion: const items = response.data?.items ?? []. The nullish coalescing operator (??) returns the right-hand value when the left side is null or undefined.

Can TypeScript prevent this error at compile time?

Yes. TypeScript will catch this if you type your state correctly: const [items, setItems] = useState<Item[]>([]). If you later try to call .map() on a value typed as Item[] | undefined, TypeScript will error at compile time.

🥷 ToolNinja