Sådan løser du “Cannot Read Properties of Undefined (Reading map)” i React

React-fejlen Cannot read properties of undefined (reading 'map') betyder, at JavaScript forsøgte at evaluere noget i stil med items.map(...), mens items var undefined. Det vigtige er ikke ordet map; det er værdien umiddelbart før .map().

Nuværende React-dokumentation (React 19.2 på tidspunktet for skrivningen) bruger stadig JavaScripts array-metode map() som den standardmåde at konvertere samlinger til JSX-elementer på. MDN definerer Array.prototype.map() som en metode, der opretter et nyt array ved at anvende en callback på hvert element. Hvis den værdi, du forventer er et array, ikke er initialiseret, ikke er indlæst endnu, eller kommer fra en uventet API-struktur, kan kaldet fejle, før React kan rendere listen. Se Reacts guide til rendering af lister og MDNs reference til Array.prototype.map().

Illustrerende scenarie: en produktliste, der crasher, før API'en er færdig

Dette er et hypotetisk eksempel til forklaring, ikke et reelt testresultat. Forestil dig en lille butikskomponent, der henter produkter, efter at komponenten først er vist. Udvikleren skriver:

function ProductList() {
  const [products, setProducts] = useState();

  useEffect(() => {
    fetch('/api/products')
      .then(response => response.json())
      .then(data => setProducts(data));
  }, []);

  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
}

Ved den første rendering er products undefined, fordi der ikke blev sendt en startværdi til useState. Reacts useState-dokumentation angiver, at state-værdien ved den første rendering svarer til den startstate, du angiver. Fetch-kaldet kører bagefter, så renderingen kan nå products.map(...), før svaret ankommer. React useState reference.

AI-genereret illustration af browserkonsollen, der viser Cannot read properties of undefined reading map i en React-komponent.
AI-genereret illustration af JavaScript-fejlen, der peger på en liste-rendering, der kalder .map() på en udefineret værdi.

Trin 1: Find præcis hvilken værdi der er undefined

Start ved stack-traceet og find linjen, der indeholder .map(). I den illustrerende komponent er det linjen products.map(...), så products er den første værdi at undersøge. I en større komponent kan det fejlede udtryk i stedet være data.items.map(), props.users.map() eller response.results.map().

Brug browserens debugger eller en midlertidig log lige før renderingslogikken:

console.log('products:', products);
console.log('is array:', Array.isArray(products));

Dette adskiller flere fejl, der ligner hinanden i UI'et. Hvis værdien er undefined, skal du undersøge initialisering eller en manglende egenskab. Hvis den er null, bruger din indlæsnings-/datamodel måske eksplicit null. Hvis den er et objekt, læser du måske det forkerte niveau i et API-svar. Hvis den er en streng eller et tal, er den opstrøms datakontrakt anderledes, end komponenten forventer.

Erstat ikke automatisk hvert fejlede udtryk med optional chaining, før du forstår værdien. Det kan undertrykke crashet, mens den forkerte dataflow forbliver på plads.

Trin 2: Initialisér collections-state som en collection, når det passer til din model

For den hypotetiske produktliste er et tomt array en fornuftig startstate, fordi “ingen produkter indlæst endnu” sikkert kan repræsenteres som en samling med nul elementer:

const [products, setProducts] = useState([]);

Nu kan den første rendering køre products.map(...), fordi et tomt array har en map-metode. Når anmodningen senere opdaterer staten, renderer React igen med de returnerede produkter.

AI-genereret illustration af en React useState-deklaration initialiseret med et tomt array.
AI-genereret illustration af initialisering af liste-state med useState([]), så den første rendering har et array.

Dette er en stærk løsning, når staten konceptuelt altid er et array. Det er mindre hensigtsmæssigt, når undefined eller null bærer meningsfuld information, såsom “ikke anmodet om endnu”, mens [] betyder “anmodningen er afsluttet, og der er nul resultater”. I det tilfælde skal du holde statene adskilte og rendere indlæsnings-, fejl- og tomme tilstande eksplicit.

Trin 3: Verificér API-svarets form, før du lægger det i state

Initialisering løser kun den første rendering. Det vil ikke beskytte komponenten, hvis serveren til sidst returnerer en anden struktur. Antag at API'en faktisk returnerer:

{
  "products": [
    { "id": 1, "name": "Keyboard" },
    { "id": 2, "name": "Mouse" }
  ]
}

Så gemmer setProducts(data) et objekt, ikke et array. Den sandsynlige fejl ændres til noget i stil med products.map is not a function. Den korrekte tildeling ville være setProducts(data.products), forudsat at den egenskab er garanteret at være et array.

For data, der krydser en ekstern grænse, skal du validere den:

fetch('/api/products')
  .then(response => response.json())
  .then(data => {
    if (!Array.isArray(data.products)) {
      throw new Error('Expected data.products to be an array');
    }
    setProducts(data.products);
  })
  .catch(error => {
    console.error(error);
    setError(error);
  });
AI-genereret illustration af en React-komponent, der tjekker Array.isArray, før den kalder map.
AI-genereret illustration af at beskytte en liste-rendering med Array.isArray(), før .map() bruges.

Dette er vigtigt, fordi en “sikker standard” ikke bør omdanne fejlbehæftede produktionsdata til en stille tom side. Hvis et array kræves af kontrakten, kan det være mere nyttigt at logge eller vise en fejl end at konvertere hvert uventet svar til [].

Trin 4: Vælg den rigtige renderingsguard for data, der legitimt kan mangle

React understøtter normal JavaScript betinget rendering. De officielle docs viser brug af if, ternære udtryk og && til at bestemme, hvilket JSX der skal returneres. React guide til betinget rendering.

For den hypotetiske produktside er en eksplicit indlæsnings- og fejlflow ofte den tydeligste:

if (error) {
  return <p>Could not load products.</p>;
}

if (products === undefined) {
  return <p>Loading products…</p>;
}

if (products.length === 0) {
  return <p>No products found.</p>;
}

return (
  <ul>
    {products.map(product => (
      <li key={product.id}>{product.name}</li>
    ))}
  </ul>
);

Optional chaining er også gyldigt, når “mangler for nu” blot skal producere intet kortlagt resultat:

{products?.map(product => (
  <ProductCard key={product.id} product={product} />
))}

MDN forklarer, at optional chaining (?.) afbryder (short-circuits), når værdien til venstre for den er null eller undefined, i stedet for at kaste en TypeError. MDN reference til optional chaining.

AI-genereret illustration af optional chaining brugt før map i en React-komponent.
AI-genereret illustration af optional chaining med users?.map(...) for data, der midlertidigt kan være undefined.

Begrænsningen er vigtig: products?.map(...) forhindrer denne specifikke nullish-access-fejl, men det beviser ikke, at products er et array. Hvis products bliver et objekt, vil products?.map stadig løse til en udefineret egenskab, og forsøget på at kalde den kan fejle. Brug skemavalidering eller Array.isArray(), når datatypen i sig selv er usikker.

Hvilken løsning skal du vælge?

SituationBedste første trækHvorfor
Staten skal altid være en listeuseState([])Giver den første rendering den korrekte datatype.
Manglende data har en meningsfuld indlæsningsstateBetinget renderingHolder “ikke indlæst” adskilt fra “indlæst men tom”.
API-formen kan variere eller være fejlbehæftetValidér med Array.isArray() eller et skemaForhindrer dårlige eksterne data i at komme ind i komponentstaten uden at blive opdaget.
Prop er valgfri som designOptional chaining eller en standard prop-værdiUndgår at dereference en legitimt fraværende værdi.
Fejl opstår efter en refactorTjek egenskabs- og prop-navneEt omdøbt felt kan få et tidligere gyldigt array til at blive undefined.

Almindelige tilfælde, der ligner den samme fejl

API'en returnerer { items: [...] }, men komponenten forventer et array

Undersøg Network-svaret og tildel array-egenskaben i stedet for wrapper-objektet. Gæt ikke formen ud fra et gammelt eksempel eller et TypeScript-interface, hvis det live-svar afviger.

En forældrekompotent glemmer at sende prop'en

Dette vil fejle:

function UserList({ users }) {
  return users.map(user => <div key={user.id}>{user.name}</div>);
}

// Parent accidentally omits users:
<UserList />

Hvis en udeladt prop skal betyde en tom liste, gør en standardværdi den kontrakt eksplicit:

function UserList({ users = [] }) {
  return users.map(user => <div key={user.id}>{user.name}</div>);
}

En indlejret egenskab mangler

Med response.data.items.map(...) kan enhver manglende mellemliggende egenskab få det til at fejle. Optional chaining som response?.data?.items er nyttigt til at læse usikre indlejrede værdier, men validér den endelige samling, før du behandler den som et array.

Den første rendering sker, før et fetch Effect er færdigt

React Effects kører efter rendering. Reacts dokumentation bemærker også, at manuel datahentning inde i Effects er almindeligt i klientapplikationer, men kan have ulemper såsom vandfald, manglende server-renderede data og manuelt cache-/race-condition-arbejde. Hvis du bruger et React-framework, kan dets indbyggede dataindlæsningsmekanisme være et bedre arkitektonisk valg. React useEffect reference.

En sikrere endelig version af den illustrerende komponent

import { useEffect, useState } from 'react';

export default function ProductList() {
  const [products, setProducts] = useState(undefined);
  const [error, setError] = useState(null);

  useEffect(() => {
    let ignore = false;

    fetch('/api/products')
      .then(response => {
        if (!response.ok) throw new Error('Request failed');
        return response.json();
      })
      .then(data => {
        if (!Array.isArray(data.products)) {
          throw new Error('Expected products array');
        }
        if (!ignore) setProducts(data.products);
      })
      .catch(error => {
        if (!ignore) setError(error);
      });

    return () => {
      ignore = true;
    };
  }, []);

  if (error) return <p>Could not load products.</p>;
  if (products === undefined) return <p>Loading products…</p>;
  if (products.length === 0) return <p>No products found.</p>;

  return (
    <ul>
      {products.map(product => (
        <li key={product.id}>{product.name}</li>
      ))}
    </ul>
  );
}

Denne version skelner bevidst mellem “ikke indlæst”, “fejlet”, “tom” og “har data”. Det er mere omfattende end et enkelt optional-chain-udtryk, men det giver brugeren et meningsfuldt UI for hver tilstand og gør en fejlbehæftet API-svar synlig under fejlfinding.

Hurtig tjekliste, før du overvejer fejlen løst

  • Identificér den præcise værdi umiddelbart før .map().
  • Bekræft dens værdi og type på den rendering, der fejler.
  • Initialisér liste-state med [], når et tomt array nøjagtigt repræsenterer starttilstanden.
  • Tjek om API'en returnerer et array direkte eller pakker det ind i en objekt-egenskab.
  • Validér eksterne data, før du gemmer dem i state, når kontrakten er vigtig.
  • Brug en indlæsningsstate, hvis undefined betyder “ikke indlæst endnu”.
  • Brug optional chaining, når fravær er legitimt, ikke som en erstatning for at forstå dårlige data.
  • Tjek omdøbte eller udeladte props efter refactoring.
  • Giv renderede liste-elementer stabile nøgler fra dataene, som anbefalet i Reacts dokumentation for liste-rendering.

For den hypotetiske produktliste var den underliggende årsag, at den første rendering modtog undefined, hvor komponenten straks forventede et array. I en reel applikation kan den samme fejlmeddelelse komme fra state-initialisering, props, indlejrede egenskaber eller API-data. Løs datakontrakten først, og vælg derefter en renderingsguard, der nøjagtigt repræsenterer, hvad “mangler” betyder i dit UI.

Efterlad en kommentar

Sådan rettes "ENOSPC: Systemgrænse for filovervågning nået" i Linux

Sådan rettes "ENOSPC: Systemgrænse for filovervågning nået" i Linux

Ret fejl i Linux ENOSPC-filovervågning ved at kontrollere inotify-grænser, finde processer med mange overvågningsbehov, hæve grænser sikkert og gøre ændringer permanente.

Sådan rettes "Tailwind CSS-stilarter opdateres ikke" i en Vite React-app

Sådan rettes "Tailwind CSS-stilarter opdateres ikke" i en Vite React-app

Ret problemer med Tailwind CSS-stilarter, der ikke opdateres i Vite React, ved at kontrollere Tailwind v4-opsætning, CSS-import, kildekodedetektion, dynamiske klasser, HMR og forældede cacher.

Sådan rettes ModuleNotFoundError: Intet modul med navnet 'pip' i Python 3

Sådan rettes ModuleNotFoundError: Intet modul med navnet 'pip' i Python 3

Ret Python 3's ModuleNotFoundError for pip på Windows, macOS og Linux med ensurepip, OS-pakker, virtuelle miljøer og fortolkertjek.

Sådan rettes "Tilladelse nægtet (offentlig nøgle)" i GitHub SSH

Sådan rettes "Tilladelse nægtet (offentlig nøgle)" i GitHub SSH

Ret GitHub SSH-tilladelse nægtet (publickey) ved at kontrollere værten, den aktive SSH-nøgle, GitHub-kontoen, SSO-godkendelsen, den eksterne URL og port 22-adgang.

How to Fix “Git Push Rejected: Non-Fast-Forward” Without Losing Changes

How to Fix “Git Push Rejected: Non-Fast-Forward” Without Losing Changes

Fix a Git non-fast-forward push safely. Protect local work, fetch remote commits, choose merge or rebase, resolve conflicts, and push without losing changes.

Sådan rettes "Nginx 502 Bad Gateway" ved proxy til Node.js

Sådan rettes "Nginx 502 Bad Gateway" ved proxy til Node.js

Ret Nginx 502 Bad Gateway-fejl med en Node.js upstream ved at kontrollere app-porten, NGINX-logfiler, proxy_pass-adresse, containernetværk, timeouts og genindlæsning.

Sådan rettes "Type 'null' kan ikke tildeles til type" i TypeScript

Sådan rettes "Type 'null' kan ikke tildeles til type" i TypeScript

Retter TypeScripts fejl "Type 'null' kan ikke tildeles til type" med foreningstyper, indsnævring, standardværdier og sikre påstande under strictNullChecks.

Sådan retter du fejlen "Prisma Client Has Not Been Generated Yet"

Sådan retter du fejlen "Prisma Client Has Not Been Generated Yet"

Ret fejlen med Prisma Client, der ikke er genereret, ved at kontrollere din generator, schema, output-sti, imports, versioner, monorepo-opsætning og build-trin til deployment.

Sådan rettes "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer

Sådan rettes "ERR_MODULE_NOT_FOUND" i Node.js ESM-importer

Ret Node.js ERR_MODULE_NOT_FOUND i ESM ved at kontrollere importstier, filtypenavne, pakkeinstallation, eksport, ESM-tilstand og rene installationer.

Sådan løser du SSL-certifikatproblemet: Unable to get local issuer certificate i Git

Sådan løser du SSL-certifikatproblemet: Unable to get local issuer certificate i Git

Løs Git-fejlen 'unable to get local issuer certificate' ved at identificere tillidsbackenden, installere den korrekte CA-kæde og holde SSL-verifikation aktiveret.