Jak skutecznie znaleźć i naprawić błąd Cannot read properties of undefined w formularzu React

Marek Radoszewski Marek Radoszewski
Języki i Technologie
03.04.2026 13 min
Jak skutecznie znaleźć i naprawić błąd Cannot read properties of undefined w formularzu React
📑 Spis treści

Jak skutecznie znaleźć i naprawić błąd „Cannot read properties of undefined” w formularzu React?

Błąd „Cannot read properties of undefined” w formularzach React potrafi skutecznie zepsuć dzień. Pojawia się nagle, często w trakcie pracy nad pozornie prostym komponentem, a komunikat w konsoli brzmi jak mało pomocny żart. Zamiast jednak frustrować się kolejną tajemniczą awarią, warto spokojnie zrozumieć, skąd ten błąd się bierze i jak krok po kroku go wyeliminować.

W tym artykule przejdziesz przez cały proces: od wyjaśnienia przyczyny błędu, przez systematyczną diagnostykę, aż po konkretne przykłady rozwiązań w kontekście formularzy React. Znajdziesz tu zarówno podejście „ratunkowe”, jak i dobre praktyki, które pozwolą Ci unikać tego problemu w przyszłości.

Cały nacisk położymy na formularze React, bo to właśnie w nich ten komunikat pojawia się wyjątkowo często. Obejmiemy przypadki z niezainicjowanym stanem, asynchronicznym ładowaniem danych, destrukturyzacją i obsługą zdarzeń, tak abyś mógł od razu zastosować te wskazówki w swoim kodzie.

Zobaczysz, że jeśli podejdziesz do problemu metodycznie, „Cannot read properties of undefined” przestanie być losowym koszmarem, a stanie się przewidywalnym i łatwym do ogarnięcia przypadkiem. Kluczowe będzie użycie konsoli, React DevTools, debuggerów oraz kilku prostych wzorców kodu.

Na koniec zebrane zostaną konkretne nawyki, które pomogą Ci pisać formularze React bezpieczniejsze i odporniejsze na takie niespodzianki, bez konieczności klikania w konsolę przy każdym odświeżeniu strony.

Programista debugujący błąd Cannot read properties of undefined w formularzu React na ekranie IDE, analizujący stan komponentu i strukturę obiektu

Co oznacza błąd „Cannot read properties of undefined” w JavaScript i React?

Komunikat „Cannot read properties of undefined” oznacza, że w danym miejscu w kodzie próbujesz odwołać się do właściwości obiektu, który ma wartość undefined. Silnik JavaScript próbuje odczytać np. user.name, ale w danym momencie user nie jest obiektem – to undefined lub null. Próba dostępu do name kończy się więc rzuceniem błędu.

Można to porównać do sytuacji, w której próbujesz czytać z kartki, która fizycznie nie istnieje. Logicznie zakładasz, że kartka jest na biurku, ale w rzeczywistości masz przed sobą pustą przestrzeń. JavaScript działa podobnie: zmienna jest zadeklarowana, ale nie ma oczekiwanej struktury, więc odczyt właściwości staje się niemożliwy.

W praktyce undefined oznacza, że zmiennej nie przypisano żadnej wartości lub próbujesz sięgnąć po właściwość obiektu, który w tym miejscu nie został jeszcze poprawnie utworzony. W kontekście React często dotyczy to stanu komponentu, danych z API lub niepoprawnie przekazanych propsów.

Dlaczego „Cannot read properties of undefined” tak często pojawia się w formularzach React?

W formularzach React pracujesz na danych, które często są dynamiczne i asynchroniczne. To naturalne środowisko dla błędów związanych z undefined, bo stan i propsy mogą zmieniać się w czasie. Warto przyjrzeć się kilku najczęstszym scenariuszom, które do tego prowadzą.

Niezainicjowany stan komponentu

Typowy przypadek to sytuacja, w której przechowujesz dane formularza jako obiekt w stanie, ale inicjalizujesz go jako null lub pusty obiekt bez wszystkich właściwości. Gdy w JSX próbujesz od razu sięgnąć po zagnieżdżoną właściwość, dostajesz błąd.

Przykład problemu:

  • state = { user: null }, a w renderze używasz user.name
  • user ma wartość null, więc user.name jest równoznaczne z odczytem właściwości z nieistniejącego obiektu.

Rozwiązaniem jest bezpieczna inicjalizacja stanu albo użycie renderowania warunkowego, tak by komponent nie próbował czytać danych, zanim będą dostępne.

Asynchroniczne ładowanie danych z API

W formularzach edycji często pobierasz dane użytkownika z API. Do czasu zakończenia zapytania user może być undefined lub null, natomiast komponent już się renderuje i używa np. user.email. To prosty przepis na „Cannot read properties of undefined”.

Przykładowa sytuacja:

  • const { user } = useQuery('/api/user/123')
  • React od razu renderuje JSX, w którym masz value={user.email}
  • Pierwsze renderowanie: user jest undefined, bo dane jeszcze nie dotarły.

W takich przypadkach konieczne jest warunkowe renderowanie lub użycie operatorów ?. i ??, aby nie wymuszać dostępu do nieistniejących właściwości.

Niepoprawnie przekazane propsy do komponentu formularza

Komponent formularza może oczekiwać np. propsa formData, a w komponencie nadrzędnym zapomnisz go przekazać albo przekażesz w innej strukturze. Wewnątrz formularza trafisz wtedy na coś w stylu formData.email, podczas gdy formData to undefined.

Typowe źródła takiego problemu to:

  • literówki w nazwach propsów,
  • zmiana struktury danych bez aktualizacji komponentów podrzędnych,
  • warunkowe renderowanie komponentu nadrzędnego, które pomija przekazanie wymaganych danych.

Rozwiązaniem jest sprawdzenie struktury propsów w React DevTools oraz dodanie sensownych wartości domyślnych lub fallbacków.

Błędy w obsłudze zdarzeń formularza

W obsłudze zdarzeń, np. onChange, często odwołujesz się do event.target.value. Zdarza się, że przez błędne przekazanie funkcji lub ręczne wywołanie handlera bez zdarzenia, event jest undefined. Wtedy próba odczytu event.target kończy się błędem.

Taka sytuacja występuje głównie wtedy, gdy:

  • wywołujesz handler ręcznie, np. handleChange() bez argumentu,
  • przekazujesz do handlera coś innego niż obiekt zdarzenia.

Aby temu zapobiec, loguj event w handlerze i upewniaj się, że komponenty wywołują funkcje z poprawnymi parametrami.

Destrukturyzacja z pustego lub niezdefiniowanego obiektu

Destrukturyzacja bywa wygodna, ale też bywa źródłem błędów. Jeśli zrobisz const { name, email } = user;, a user jest undefined lub null, to już sam ten wiersz rzuci „Cannot read properties of undefined”.

Problem pojawia się zwłaszcza przy:

  • destrukturyzacji propsów komponentu,
  • destrukturyzacji danych z API podczas pierwszego renderu,
  • braku wartości domyślnych przy destrukturyzacji.

Rozwiązaniem jest stosowanie wartości domyślnych (userData = {}) lub opcjonalnego łańcuchowania (userData?.name).

Jak krok po kroku namierzyć błąd „Cannot read properties of undefined” w formularzu React?

Zamiast chaotycznie poprawiać różne miejsca w kodzie, warto zastosować systematyczne podejście do debugowania. Pozwoli to szybko znaleźć źródło błędu i uniknąć długiego błądzenia po plikach.

1. Dokładnie przeanalizuj komunikat w konsoli

Pierwsze miejsce, do którego powinieneś zajrzeć, to konsola w DevTools. Oprócz samego komunikatu błędu zobaczysz tam stack trace, czyli ścieżkę wywołań funkcji prowadzącą do miejsca awarii.

Skup się na:

  • pierwszej linii stack trace, która prowadzi do Twojego pliku,
  • numerze linii w pliku,
  • nazwie komponentu lub funkcji, z której błąd pochodzi.

To ten fragment kodu jest pierwszym podejrzanym. Tam React próbował odczytać właściwość z undefined.

2. Dodaj celowane console.log() we właściwych miejscach

Gdy już wiesz, gdzie mniej więcej występuje błąd, cofnij się o parę linii w kodzie i wstaw diagnostyczne logi.

Typowe logi debugujące:

  • console.log('user w renderze:', user);
  • console.log('props w DisplayUserInfo:', props);
  • console.log('event w handleChange:', e);

Dzięki temu szybko sprawdzisz, czy:

  • obiekt ma wartość null lub undefined,
  • obiekt istnieje, ale nie ma oczekiwanej właściwości,
  • zdarzenie ma poprawną strukturę (event.target itd.).

Kiedy już zidentyfikujesz, który dokładnie obiekt jest undefined, będziesz mógł cofnąć się jeszcze wcześniej i sprawdzić, gdzie został niepoprawnie zainicjowany lub przekazany.

3. Skorzystaj z React DevTools do inspekcji stanu i propsów

Rozszerzenie React DevTools to bardzo skuteczne narzędzie przy błędach związanych ze stanem i propsami. Możesz w nim przejrzeć drzewo komponentów, ich stan (state) i propsy (props) w czasie rzeczywistym.

Postępuj tak:

  1. Otwórz zakładkę „Components” w React DevTools.
  2. Znajdź komponent formularza, który generuje błąd.
  3. Sprawdź stan komponentu: czy obiekty używane w JSX istnieją i mają poprawną strukturę.
  4. Sprawdź propsy: czy komponent dostał wszystkie dane, których oczekuje.

Jeżeli zobaczysz, że np. user jest null, mimo że zakładałeś, że zawsze będzie obiektem, masz jasną wskazówkę, gdzie należy poprawić inicjalizację lub renderowanie.

4. Ustaw breakpointy i użyj debuggera w przeglądarce

Kiedy logi i DevTools nie wystarczają, dobrym rozwiązaniem jest użycie debuggera i breakpointów. W kodzie możesz dodać instrukcję debugger; albo ustawić breakpoint bezpośrednio w zakładce „Sources” w DevTools.

Taki sposób pracy pozwala:

  • zatrzymać wykonanie kodu dokładnie w miejscu, w którym pojawia się błąd,
  • krok po kroku prześledzić przebieg funkcji,
  • podglądać aktualne wartości zmiennych, stanu i propsów.

To jak prześledzenie sceny błędu klatka po klatce – łatwo zauważysz moment, w którym obiekt, który wcześniej był poprawny, nagle staje się undefined.

Schemat przepływu danych w formularzu React pokazujący stan, propsy i miejsca powstawania błędu Cannot read properties of undefined

Przykłady błędów w formularzach React i konkretne rozwiązania

Aby łatwiej przełożyć teorię na praktykę, zobaczmy kilka typowych scenariuszy z formularzami React, które prowadzą do „Cannot read properties of undefined”, oraz sposoby ich naprawy.

Scenariusz 1: Niezainicjowany stan i asynchroniczne pobieranie danych

Masz formularz edycji profilu użytkownika, a dane są pobierane asynchronicznie. W czasie pierwszego renderu stan jest null, ale komponent od razu próbuje użyć user.name i user.email.

Problematiczny kod:

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

function UserProfileForm({ userId }) {
  const [user, setUser] = useState(null); // Na początku user jest null

  useEffect(() => {
    // Symulacja ładowania danych z API
    setTimeout(() => {
      const fetchedUser = { id: userId, name: 'Jan Kowalski', email: '[email protected]' };
      setUser(fetchedUser);
    }, 1000);
  }, [userId]);

  // PROBLEM: Jeśli user jest null, próba user.name wywoła błąd
  return (
    <form>
      <label>
        Imię:
        <input type="text" value={user.name} onChange={() => {}} />
      </label>
      <label>
        Email:
        <input type="email" value={user.email} onChange={() => {}} />
      </label>
      <button type="submit">Zapisz</button>
    </form>
  );
}

Dopóki user ma wartość null, każdy dostęp do user.name czy user.email skończy się błędem.

Rozwiązanie: renderowanie warunkowe

Najprostsze i bardzo czytelne wyjście to nie renderować formularza, dopóki dane nie zostaną załadowane.

function UserProfileForm({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    setTimeout(() => {
      const fetchedUser = { id: userId, name: 'Jan Kowalski', email: '[email protected]' };
      setUser(fetchedUser);
    }, 1000);
  }, [userId]);

  if (!user) {
    return <p>Ładowanie danych użytkownika...</p>;
  }

  return (
    <form>
      <label>
        Imię:
        <input type="text" value={user.name} onChange={() => {}} />
      </label>
      <label>
        Email:
        <input type="email" value={user.email} onChange={() => {}} />
      </label>
      <button type="submit">Zapisz</button>
    </form>
  );
}

Dzięki temu formularz pojawi się dopiero wtedy, gdy user będzie obiektem z oczekiwanymi polami.

Alternatywa: opcjonalne łańcuchowanie i wartość domyślna

Możesz też zdecydować, że formularz ma być widoczny od razu, a pola będą puste do czasu załadowania danych.

function UserProfileForm({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    setTimeout(() => {
      const fetchedUser = { id: userId, name: 'Jan Kowalski', email: '[email protected]' };
      setUser(fetchedUser);
    }, 1000);
  }, [userId]);

  return (
    <form>
      <label>
        Imię:
        <input type="text" value={user?.name ?? ''} onChange={() => {}} />
      </label>
      <label>
        Email:
        <input type="email" value={user?.email ?? ''} onChange={() => {}} />
      </label>
      <button type="submit">Zapisz</button>
    </form>
  );
}

Zastosowanie user?.name ?? '' sprawia, że nawet gdy user jest null, wartość pola będzie pustym stringiem, a błąd się nie pojawi.

Scenariusz 2: Problemy w obsłudze zdarzeń onChange

Teoretycznie w React syntetyczne zdarzenia zawsze mają event.target. Jednak w praktyce zdarzają się sytuacje, w których handler jest wywoływany błędnie, bez poprawnego obiektu zdarzenia.

Przykładowy kod:

import React, { useState } from 'react';

function MyForm() {
  const [value, setValue] = useState('');

  const handleChange = (e) => {
    // PRZYKŁAD BŁĘDNEGO UŻYCIA (symulacja problemu)
    // W normalnej sytuacji e.target jest dostępne.
    // Ale wyobraźmy sobie, że e.target jest undefined
    // bo np. przekazaliśmy coś innego niż obiekt zdarzenia.
    if (!e || !e.target) { // To jest celowe "zepsucie" dla przykładu
        console.error("Event lub target jest undefined!");
        return;
    }
    setValue(e.target.value);
  };

  return (
    <input type="text" value={value} onChange={handleChange} />
  );
}

W prawdziwych aplikacjach taki problem zwykle wynika z ręcznego wywołania handleChange() bez argumentu lub błędnego przekazania parametru.

Rozwiązanie: upewnij się, że handler zawsze dostaje poprawny event

Aby uniknąć niespodzianek:

  • nie wywołuj handlerów zdarzeń manualnie bez przekazania event,
  • jeśli tworzysz funkcje pośrednie, np. onChange={(e) => handleChange(e, id)}, upewnij się, że pierwszy argument to faktycznie event,
  • w razie wątpliwości loguj e wewnątrz handlera.

Dzięki temu kontrolujesz, że event nie jest undefined, zanim spróbujesz odczytać event.target.value.

Scenariusz 3: Destrukturyzacja z undefined w komponentach prezentacyjnych

Załóżmy, że masz komponent wyświetlający informacje o użytkowniku, a dane trafiają do niego przez propsy. Jeśli userData będzie null lub undefined, destrukturyzacja od razu rzuci błąd.

Problematiczny kod:

import React from 'react';

function DisplayUserInfo({ userData }) {
  // Jeśli userData jest null lub undefined, ten wiersz rzuci błędem
  const { name, email, address } = userData;

  return (
    <div>
      <p>Imię: {name}</p>
      <p>Email: {email}</p>
      <p>Adres: {address.city}</p> {/* Ten też rzuci błąd, jeśli address jest undefined */}
    </div>
  );
}

Tu potencjalne źródła błędów są dwa: userData oraz address.

Rozwiązanie: wartości domyślne przy destrukturyzacji

Możesz zapewnić bezpieczne wartości startowe, nawet gdy userData nie zostanie przekazane.

function DisplayUserInfo({ userData = {} }) { // Ustaw domyślny pusty obiekt
  const { name = 'N/A', email = 'N/A', address = {} } = userData;
  const { city = 'N/A' } = address;

  return (
    <div>
      <p>Imię: {name}</p>
      <p>Email: {email}</p>
      <p>Adres: {city}</p>
    </div>
  );
}

Dzięki temu komponent jest bardziej odporny na braki danych i nadal działa nawet wtedy, gdy userData ma niekompletną strukturę.

Rozwiązanie alternatywne: opcjonalne łańcuchowanie w JSX

Możesz też pominąć destrukturyzację i użyć operatorów ?. oraz ?? bezpośrednio w JSX.

function DisplayUserInfo({ userData }) {
  return (
    <div>
      <p>Imię: {userData?.name ?? 'N/A'}</p>
      <p>Email: {userData?.email ?? 'N/A'}</p>
      <p>Adres: {userData?.address?.city ?? 'N/A'}</p>
    </div>
  );
}

Takie podejście jest bardzo czytelne i bezpieczne, szczególnie w warstwie prezentacyjnej, gdzie często prezentujesz dane opcjonalne.

Dobre praktyki, które pomogą uniknąć błędu w przyszłości

Zamiast za każdym razem gasić pożar, lepiej wdrożyć proste nawyki, które znacząco zmniejszą szansę na pojawienie się „Cannot read properties of undefined” w Twoich formularzach React.

Oto zestaw praktyk, które warto stosować na co dzień:

  • Inicjuj stan sensownymi wartościami startowymi
    Jeśli w stanie trzymasz obiekt, którego właściwości używasz w renderze, inicjuj go jako {} lub pełny obiekt z pustymi polami, a nie jako null. To pozwoli Ci uniknąć odwołań do undefined podczas pierwszego renderu.

  • Stosuj opcjonalne łańcuchowanie (?.) przy zagnieżdżonych właściwościach
    Zamiast pisać user.address.city, użyj user?.address?.city. Kod stanie się zarówno bezpieczniejszy, jak i czytelniejszy. Unikniesz też kaskady ifów sprawdzających istnienie każdego poziomu obiektu.

  • Używaj operatora ?? do nadawania wartości domyślnych
    Jeśli chcesz, by brakująca wartość nie rozbijała komponentu, stosuj ??. Przykład: user?.name ?? 'Anonim'. Jest to bardziej precyzyjne niż ||, które traktuje również 0 i pusty string jako wartości „fałszywe”.

  • Waliduj strukturę danych z zewnętrznych źródeł
    Dane z API, formularzy czy propsów mogą mieć nieoczekiwaną strukturę. Zanim zaczniesz je intensywnie wykorzystywać, upewnij się, że zawierają wszystkie wymagane pola. Możesz to robić prostymi ifami lub korzystając z bibliotek do walidacji schematów.

  • Stosuj konsekwentne renderowanie warunkowe
    Jeżeli komponent zależy od danych ładowanych asynchronicznie, zawsze uwzględnij stan „ładowania” i ewentualnie „błędu”. Nie próbuj renderować docelowego formularza, gdy dane jeszcze nie istnieją. To poprawia zarówno stabilność kodu, jak i komfort użytkownika.

  • Pisz testy jednostkowe i integracyjne dla formularzy
    Nawet proste testy, które sprawdzą renderowanie komponentu przy braku danych lub przy niepełnych propsach, pomogą Ci szybko wykryć, że w kodzie brakuje zabezpieczeń przed undefined.

Stosowanie tych zasad sprawi, że błąd „Cannot read properties of undefined” stanie się rzadkim gościem w Twoich formularzach React, a Ty będziesz mieć większą kontrolę nad tym, co naprawdę dzieje się z Twoimi danymi w trakcie cyklu życia komponentów.

Podsumowanie – jak oswoić „Cannot read properties of undefined” w formularzach React?

Błąd „Cannot read properties of undefined” w formularzu React nie jest magiczną usterką, tylko objawem konkretnego problemu z danymi – najczęściej niezainicjowanym stanem, asynchronicznym ładowaniem, błędną destrukturyzacją lub niepoprawnym przekazaniem propsów. Zrozumienie tego mechanizmu pozwala podejść do naprawy w sposób logiczny, a nie chaotyczny.

Systematyczna diagnostyka oparta na konsoli, React DevTools, debuggerze i celowych console.log() prowadzi prosto do miejsca w kodzie, w którym obiekt staje się undefined. Po znalezieniu źródła możesz zastosować sprawdzone wzorce: renderowanie warunkowe, opcjonalne łańcuchowanie, wartości domyślne i bezpieczną inicjalizację stanu.

Jeśli wyrobisz sobie nawyk ostrożnego obchodzenia się z danymi w stanie i propsach, a także uwzględniania stanów pośrednich (ładowanie, brak danych), formularze React przestaną zaskakiwać Cię tym błędem. Zamiast gaszenia pożarów w konsoli, skupisz się na rozwijaniu logiki biznesowej i poprawianiu doświadczenia użytkownika.

W praktyce oznacza to mniej frustracji, mniej skakania po plikach w poszukiwaniu „znikających” właściwości i bardziej przewidywalne zachowanie komponentów – dokładnie tego potrzebujesz, aby pracować z Reactem skutecznie i bez zbędnych nerwów.

Marek Radoszewski

Autor

Marek Radoszewski

Freelance developer i tech blogger od 7 lat. Pracował przy projektach dla klientów z Polski, UK i USA. Na blogu pisze o praktycznych aspektach programowania, narzędziach i tym, jak skutecznie rozwijać karierę jako niezależny programista.

Wróć do kategorii Języki i Technologie