·
Pytania i odpowiedzi React
React — interview Q&A
40 Pytań
0 Znanych
Zestaw 40 pytań rekrutacyjnych z React pogrupowanych w 5 kategorii: podstawy, hooks, state management, performance oraz wzorce i architektura. Kliknij pytanie, by zobaczyć odpowiedź.
🔍
40 pytań
🔍
Brak wyników dla podanej frazy
1 Czym jest React i na czym polega jego model deklaratywny?

React to biblioteka JavaScript do budowania interfejsów użytkownika, stworzona przez Meta. Nie jest pełnym frameworkiem — odpowiada wyłącznie za warstwę widoku (V w MVC).

Model deklaratywny polega na tym, że opisujesz jaki ma być stan UI, a nie jak do niego dojść. React sam optymalnie oblicza i aplikuje różnicę (diffing). W modelu imperatywnym (np. vanilla JS) sam manipulujesz DOM-em krok po kroku — React to ukrywa za warstwą abstrakcji Virtual DOM.

Podstawy
2 Czym jest Virtual DOM i jak działa reconciliation?

Virtual DOM to lekka, in-memory reprezentacja drzewa DOM w JavaScript. Przy każdym renderze React tworzy nowe drzewo VDOM i porównuje je z poprzednim.

Reconciliation to algorytm obliczający minimalny zestaw zmian (diff) potrzebny do aktualizacji prawdziwego DOM. React stosuje heurystyki: różne typy elementów = pełne zastąpienie; ta sama lista = użyj key do identyfikacji. Wynik diff trafia do Reacta DOM (renderer), który aplikuje zmiany w jednej sekwencji — minimalizując kosztowne operacje na DOM.

Podstawy
4 Czym jest JSX i jak jest przetwarzany?

JSX (JavaScript XML) to rozszerzenie składni JS pozwalające pisać markup podobny do HTML wewnątrz kodu JavaScript. Nie jest częścią standardu JS — transpilowany przez Babel/SWC.

Każdy tag JSX jest zamieniany na wywołanie React.createElement(type, props, ...children) (przed React 17) lub importowany transform jsx() (React 17+, automatyczny import). JSX to cukier składniowy — absolutnie nic magicznego; to zwykłe wywołania funkcji zwracające obiekty opisujące węzły VDOM.

// JSX const el = <Button color="blue">Kliknij</Button>; // Po transpilacji const el = jsx(Button, { color: "blue" }, "Kliknij");
Podstawy
5 Czym są props i jak działają w React?

Props (properties) to dane przekazywane od komponentu-rodzica do komponentu-dziecka. Są immutable z perspektywy dziecka — komponent nie powinien modyfikować własnych props.

Przepływ danych w React jest jednokierunkowy (one-way data flow): dane płyną w dół przez props. Dziecko może komunikować się z rodzicem przez przekazane callback functions (props będące funkcjami). Props mogą być dowolnym typem JS: string, number, object, tablica, funkcja, a nawet inny komponent React.

Podstawy
6 Dlaczego key jest ważny przy renderowaniu list?

key to specjalny prop pomagający Reactowi identyfikować, które elementy listy zmieniły się, zostały dodane lub usunięte podczas reconciliation.

Bez stabilnych kluczy React porównuje elementy pozycyjnie — gdy kolejność się zmieni (np. element dodany na początku), React niepotrzebnie niszczy i odtwarza wszystkie węzły poniżej. Z kluczem React wie dokładnie który element jest który. Czego unikać: index tablicy jako key przy listach, które mogą być sortowane/filtrowane (prowadzi do bugów ze stanem komponentów). Używaj stabilnych, unikalnych ID z danych.

Podstawy
7 Co to jest lifting state up i kiedy go stosować?

Lifting state up (wynoszenie stanu w górę) polega na przeniesieniu współdzielonego stanu do najbliższego wspólnego przodka komponentów, które go potrzebują.

Stosuj gdy: dwa rodzeństwa muszą mieć zsynchronizowany stan, formularz w wielu komponentach operuje na tych samych danych, komponent-dziecko musi zmienić dane widoczne w rodzeństwie. Alternatywą przy głębokim drzewie jest Context API lub zewnętrzny state manager (Zustand, Redux), żeby uniknąć prop drilling.

Podstawy
8 Czym jest React StrictMode i do czego służy?

StrictMode to narzędzie deweloperskie (nie wpływa na produkcję). Owija część lub całość drzewa komponentów i aktywuje dodatkowe sprawdzenia.

Co robi: podwójnie wywołuje funkcje komponentów, useState settery i useReducer reducery (w React 18 — aby wykryć efekty uboczne w renderze); montuje i odmontowuje efekty dwukrotnie (aby wykryć brakujące cleanup w useEffect); ostrzega o przestarzałych API. Bardzo przydatny przy migracji do React 18 i wykrywaniu nieoczekiwanych side effects.

Podstawy
9 Jak działa useState i dlaczego aktualizacje stanu są asynchroniczne?

useState zwraca parę: aktualną wartość stanu i funkcję setter. Wywołanie settera planuje (schedules) re-render — React nie aktualizuje zmiennej natychmiast w bieżącej funkcji.

Aktualizacje są wsadowane (batched): React grupuje wiele setterów wywołanych w jednym handlerze zdarzeń w jeden re-render (React 18 rozszerzył batching na asynchrniczne operacje). Dlatego zaraz po setCount(count + 1) zmienna count ma stare wartości. Gdy nowy stan zależy od poprzedniego, używaj formy funkcyjnej: setCount(prev => prev + 1).

Hooks
10 Jak działa useEffect i co oznacza tablica zależności?

useEffect synchronizuje komponent z zewnętrznym systemem: API calls, subskrypcje, timery, manipulacja DOM. Uruchamia się po malowaniu ekranu.

Tablica zależności kontroluje kiedy efekt się ponawia: brak tablicy → po każdym renderze; pusta tablica [] → tylko przy montowaniu; z wartościami [dep1, dep2] → gdy zmieni się którakolwiek zależność. Funkcja zwrócona z useEffect to cleanup — React wywołuje ją przed następnym efektem lub odmontowaniem (anuluj subskrypcje, clearTimeout itp.). Brakujący cleanup = memory leak.

Hooks
11 Czym różni się useCallback od useMemo?

useMemo zapamiętuje wynik wywołania funkcji i zwraca tę samą wartość dopóki zależności się nie zmienią. Używany do kosztownych obliczeń:

const sortedList = useMemo(() => items.sort(...), [items]);

useCallback zapamiętuje samą funkcję (referencję). Przydatny gdy przekazujesz callback do zoptymalizowanego komponentu dziecka (React.memo) — bez useCallback przy każdym renderze rodzica powstaje nowa referencja funkcji, co powoduje re-render dziecka.

const handleClick = useCallback(() => doSomething(id), [id]);

Ważne: oba mają koszt — nie używaj ich wszędzie, tylko gdy masz mierzalny problem z wydajnością.

Hooks
12 Do czego służy useRef i kiedy go używać?

useRef zwraca mutowalny obiekt { current: initialValue }. Kluczowa właściwość: zmiana ref.current nie powoduje re-renderu.

Dwa główne zastosowania: 1. Dostęp do węzła DOM<input ref={inputRef} />, potem inputRef.current.focus(); 2. Przechowywanie wartości między renderami bez wywoływania re-renderu — np. poprzednia wartość propsa, ID timeoutu, flaga czy komponent zamontowany. Używaj useRef gdy potrzebujesz "zmiennej instancji" — czegoś trwałego między renderami, ale nie powodującego renderów.

Hooks
13 Kiedy użyć useReducer zamiast useState?

useReducer sprawdza się gdy: stan to złożony obiekt z wieloma polami aktualizowanymi razem, kolejna wartość stanu zależy od wielu poprzednich wartości jednocześnie, logika aktualizacji jest skomplikowana lub chcesz ją testować w izolacji.

Pattern: const [state, dispatch] = useReducer(reducer, initialState). Reducer to czysta funkcja (state, action) => newState — łatwa do unit testowania. Dobra zasada: gdy masz 3+ powiązanych useState, które zmieniają się razem, rozważ konsolidację do useReducer. Połączony z Context zastępuje podstawowe potrzeby Redux.

Hooks
14 Czym są custom hooks i jakie są zasady rządzące hookami?

Custom hook to funkcja JS zaczynająca się od use, która może wywoływać inne hooki. Służy do ekstrakcji i reużycia logiki stanowej między komponentami (np. useFetch, useLocalStorage, useDebounce).

Zasady hooków (Rules of Hooks): 1. Wywołuj hooki tylko na poziomie top-level — nigdy wewnątrz pętli, warunków lub zagnieżdżonych funkcji; 2. Wywołuj hooki tylko z komponentów React lub custom hooków — nie z czystych funkcji JS. Zasady te są wymuszane przez ESLint plugin eslint-plugin-react-hooks. Naruszenie powoduje błędy związane z kolejnością hooków między renderami.

Hooks
15 Co to jest useLayoutEffect i kiedy go używać zamiast useEffect?

useLayoutEffect ma identyczną sygnaturę jak useEffect, ale uruchamia się synchronicznie po mutacjach DOM, ale przed malowaniem ekranu. Blokuje browser paint do czasu zakończenia efektu.

Kiedy używać: gdy efekt musi odczytać layout DOM (np. zmierzyć element, getBoundingClientRect) i od razu zmodyfikować DOM, zanim użytkownik cokolwiek zobaczy — unikasz migotania (flash). Przykłady: tooltips, popovers pozycjonowane względem elementu, animacje wejścia bazujące na rozmiarze. Domyślnie używaj useEffectuseLayoutEffect tylko gdy widzisz migotanie UI.

Hooks
16 Co nowego przynosi React 19 w kwestii hooków?

React 19 wprowadził kilka nowych hooków upraszczających wzorce, które wcześniej wymagały dużo boilerplate:

  • useActionState — zarządza stanem i pending/error formularzy opartych na Server Actions lub zwykłych funkcjach async
  • useFormStatus — dostęp do statusu (pending) formularza nadrzędnego bez prop-drilling
  • useOptimistic — optymistyczne aktualizacje UI: natychmiast wyświetl zaktualizowany stan, cofnij przy błędzie
  • use(promise) — czytanie Promise lub Context wewnątrz render z obsługą Suspense

Dodatkowo React Compiler (RC) automatycznie memoizuje komponenty — w przyszłości useMemo / useCallback staną się zbędne.

Hooks
17 Czym jest Context API i jakie ma ograniczenia?

Context API pozwala przekazywać dane przez drzewo komponentów bez ręcznego prop drilling na każdym poziomie. Tworzysz kontekst (createContext), owijasz drzewo Providerem z wartością, konsumentujesz przez useContext.

Ograniczenia wydajnościowe: każda zmiana wartości Providera powoduje re-render wszystkich konsumentów tego kontekstu — nawet jeśli używają tylko fragmentu wartości. To sprawia, że Context słabo nadaje się do często zmieniającego się stanu globalnego (np. pozycja kursora). Rozwiązania: dzielenie kontekstu na mniejsze, useMemo na wartości, lub biblioteki jak Zustand/Jotai obsługujące selektywne subskrypcje.

State Management
18 Czym jest Redux i jaki jest jego podstawowy przepływ danych?

Redux to biblioteka do przewidywalnego zarządzania stanem oparta na 3 zasadach: jedno źródło prawdy (single store), stan jest read-only (zmiana tylko przez actions), zmiany opisane czystymi funkcjami (reducers).

Przepływ: UI dispatch → Action → Reducer (czysta funkcja state + action → new state) → Store → UI re-render. Dziś standardem jest Redux Toolkit (RTK), który eliminuje boilerplate: createSlice generuje actions i reducer razem, createAsyncThunk obsługuje async, RTK Query zastępuje react-query dla cache API. Redux warto stosować przy złożonym, współdzielonym stanie w dużych teamach.

State Management
19 Czym jest Zustand i dlaczego zyskał popularność?

Zustand to minimalistyczna biblioteka stanu (~1KB). API oparte na jednej funkcji create — nie ma Provider, boilerplate, ani skomplikowanych reducerów.

const useStore = create((set) => ({ count: 0, increment: () => set((s) => ({ count: s.count + 1 })), }));

Kluczowa zaleta: selektywne subskrypcje — komponent re-renderuje się tylko gdy zmieni się ta część store, którą konsumuje (np. useStore(s => s.count)). Nie ma problemu z wydajnością Context. Popularność wynika z prostoty, małego rozmiaru i braku Provider hell. Dobry wybór dla małych-średnich aplikacji bez potrzeby DevTools Redux.

State Management
20 Co to jest server state i czym różni się od client state?

Client state to dane żyjące tylko w przeglądarce: stan UI (czy modal otwarty), dane formularzy, preferencje użytkownika. Właścicielem jest aplikacja frontendowa.

Server state to dane przychodzące z serwera: listy użytkowników, produkty, posty. Są asynchroniczne, wspólne (inni użytkownicy mogą je zmieniać) i outdate'ują się. Wymaga zarządzania: cache, refetching, loading/error states, stale-while-revalidate. Biblioteki jak TanStack Query (react-query), SWR lub RTK Query zarządzają server state — Redux/Zustand są złym wyborem dla danych serwerowych, bo nie mają wbudowanego caching/invalidation.

State Management
21 Czym jest TanStack Query (react-query) i jakie problemy rozwiązuje?

TanStack Query to biblioteka zarządzająca server state: fetching, caching, synchronizacja i aktualizacja danych asynchronicznych. Zastępuje ręczne useEffect + useState do fetch.

Rozwiązuje: automatyczne cachowanie (deduplika requestów), background refetching (dane świeże przy powrocie na tab), stale-while-revalidate, loading/error/success states out-of-box, invalidacja i refetch po mutacji, infinite scroll, optimistic updates, retry logic. Hook useQuery(key, fetcher) + useMutation to dziś standard dla zapytań API w React bez SSR frameworka.

State Management
22 Dlaczego nie należy mutować stanu bezpośrednio w React?

React wykrywa zmiany stanu przez porównanie referencji (Object.is). Jeśli bezpośrednio zmutuj obiekt/tablicę, referencja pozostaje ta sama — React nie widzi zmiany i nie re-renderuje komponentu.

Poprawne podejście: zawsze tworzyć nowe obiekty/tablice: setState([...prev, newItem]), setState({...prev, field: value}). Dla głęboko zagnieżdżonych struktur pomocna jest biblioteka Immer (używana wewnętrznie przez Redux Toolkit) — pozwala pisać "mutujący" kod, który w rzeczywistości produkuje nową immutable kopię.

State Management
23 Co to jest prop drilling i jak go unikać?

Prop drilling to przekazywanie props przez wiele poziomów drzewa komponentów tylko po to, żeby dotarły do głęboko zagnieżdżonego komponentu — pośrednie komponenty nie korzystają z tych props, tylko je "przesyłają".

Rozwiązania: Context API — dla rzadko zmieniających się danych (theme, locale, auth user); Zustand/Jotai/Redux — globalny store z selektywnymi subskrypcjami; Component composition — przekazywanie komponentów jako children lub props zamiast danych; renderowanie bliżej źródła — czy na pewno stan musi żyć tak wysoko? Często prop drilling można naprawić, przenosząc stan niżej lub kolocując komponent bliżej danych.

State Management
24 Czym jest Jotai i kiedy wybrać go zamiast Zustand?

Jotai to atomowy model stanu inspirowany Recoilem. Zamiast jednego store definiujesz atomowe jednostki stanu (atom), które komponenty konsumują niezależnie — każdy atom to osobna subskrypcja.

Kiedy Jotai vs Zustand: Jotai lśni przy wielu niezależnych, granularnych jednostkach stanu (np. każda komórka w arkuszu kalkulacyjnym, każdy węzeł w edytorze); model atomowy jest naturalny gdy stan ma zależności między atomami (derivedAtom). Zustand lepiej gdy masz jeden zintegrowany store z wieloma akcjami i wyraźną strukturą — bardziej zbliżony do Redux, prostszy mental model dla teamów znających Redux.

State Management
25 Czym jest React.memo i kiedy go stosować?

React.memo to HOC, który opakowuje komponent funkcyjny i zapobiega jego re-renderowi jeśli props nie zmieniły się (shallow comparison). Odpowiednik PureComponent dla klas.

Kiedy używać: komponent renderuje się często, a rodzic re-renderuje się często; komponent jest kosztowny do renderowania; props rzadko się zmieniają. Czego unikać: owijania każdego komponentu (overhead memoizacji może być większy niż koszt re-renderu dla lekkich komponentów); pamiętaj że inline functions i object literals jako props tworzą nowe referencje przy każdym renderze rodzica — para React.memo + useCallback/useMemo jest często potrzebna razem.

Performance
26 Co to jest code splitting i lazy loading w React?

Code splitting to podział bundle JS na mniejsze chunki ładowane na żądanie. Bez niego cały kod aplikacji trafia do jednego dużego pliku — nawet strony nigdy nie odwiedzone przez użytkownika.

W React: React.lazy(() => import('./Component')) + <Suspense fallback={...}>. Webpack/Vite automatycznie tworzą osobny chunk dla dynamicznie importowanych modułów. Strategie: route-based splitting (każda trasa = osobny chunk — najpopularniejsze), component-based splitting (ciężkie komponenty jak edytory, wykresy), vendor splitting (osobny chunk dla bibliotek). Narzędzie: @loadable/component dla SSR.

Performance
27 Czym jest windowing / virtualizacja list?

Windowing (wirtualizacja) polega na renderowaniu tylko tych elementów listy, które są aktualnie widoczne w viewporcie. Zamiast 10 000 węzłów DOM — renderujesz np. 20-30 i zmieniasz ich zawartość przy scrollowaniu.

Bez wirtualizacji długa lista (tysiące pozycji) = tysiące węzłów DOM = wolny render, wolny scroll, duże zużycie pamięci. Biblioteki: react-window (lżejsza, API prostsze), react-virtual / TanStack Virtual (bez DOM headless, elastyczniejsze), react-virtuoso (obsługuje zmienną wysokość wierszy out-of-box). Niezbędne przy listach >500 elementów z danymi dynamicznymi.

Performance
28 Co to jest React Profiler i jak debugować wolne rendery?

React Profiler to narzędzie dostępne w React DevTools. Nagrywa sesję renderów i pokazuje: które komponenty renderowały się, ile razy i jak długo. Pozwala zidentyfikować "expensive renders" i zbędne re-rendery.

Proces debugowania: 1. Nagraj sesję w DevTools Profiler; 2. Znajdź komponenty renderujące się często lub długo (czerwone/żółte bary); 3. Sprawdź dlaczego się renderują (zmieniony state/context/props); 4. Zastosuj React.memo, useMemo, useCallback lub podziel kontekst. Komponent <Profiler onRender={callback}> pozwala mierzyć wydajność programowo w produkcji.

Performance
29 Czym jest React Concurrent Mode i co to są Transitions?

Concurrent Mode (React 18+) pozwala Reactowi przerwać, wznowić i porzucić rendery. Zamiast blokowania głównego wątku na duży render, React może go "pauzować" aby obsłużyć pilniejsze zdarzenia (np. kliknięcia).

startTransition / useTransition oznaczają aktualizację stanu jako niepilną (low-priority). React może opóźnić tę aktualizację jeśli przychodzą pilniejsze zdarzenia. Przykład: wpisywanie w wyszukiwarce — aktualizacja inputa jest pilna, filtrowanie 10 000 wyników to transition. useDeferredValue — podobny efekt dla wartości z zewnątrz.

Performance
30 Czym jest Suspense i jak obsługuje stany ładowania?

Suspense pozwala deklaratywnie określić co wyświetlić gdy komponent "czeka" na coś (lazy import, dane). Komponent dziecko rzuca Promise — React łapie go i wyświetla fallback aż do rozwiązania.

Zastosowania: Lazy loading komponentów (React.lazy + Suspense); Data fetching (React 19 use(promise), Next.js 13+ Server Components, Relay, TanStack Query v5 z experimentalSuspense). Zagnieżdżone Suspense boundary pozwalają pokazywać skeleton UI na różnych poziomach granularności — zamiast jednego globalnego spinnera, każda sekcja ładuje się niezależnie.

Performance
31 Czym jest Server-Side Rendering (SSR) i jak różni się od CSR?

CSR (Client-Side Rendering): przeglądarka pobiera pusty HTML + JS bundle, JS renderuje całą aplikację w przeglądarce. Wolniejszy FCP (First Contentful Paint), słabszy SEO, ale szybka nawigacja po pierwszym ładowaniu.

SSR: serwer renderuje HTML przy każdym żądaniu i wysyła gotową stronę. Szybszy FCP, dobre SEO, ale każde żądanie wymaga pracy serwera. SSG (Static Site Generation): HTML generowany w build time — ultra-szybki, idealny dla blogów/dokumentacji. ISR (Incremental Static Regeneration, Next.js): SSG z możliwością regeneracji strony w tle co N sekund. Nowoczesne frameworki (Next.js, Remix) mieszają te podejścia per-route.

Performance
32 Co to są React Server Components?

React Server Components (RSC, React 18+/Next.js 13+) to komponenty renderowane wyłącznie po stronie serwera — ich kod nigdy nie trafia do klienta. Mogą bezpośrednio czytać z bazy danych, systemu plików, wywoływać API bez fetch po stronie klienta.

Kluczowe cechy: zero bundle size (kod pozostaje na serwerze), brak dostępu do hooków (useState, useEffect) — są statyczne; mogą zawierać Client Components oznaczone "use client". Korzyści: mniejszy bundle, dane bliżej źródła, naturalny waterfall fetching. Granica: RSC → Client Component można przekraczać przez props, ale tylko z serializable values (nie funkcje).

Performance
33 Co to są Higher-Order Components (HOC) i kiedy je stosować?

HOC to funkcja przyjmująca komponent i zwracająca nowy, ulepszony komponent. Pattern reużycia logiki poprzedni generacji Reacta — dziś częściowo zastąpiony przez custom hooks.

Przykłady: withAuth(Component) (redirect jeśli nie zalogowany), withLogger(Component) (logowanie props), connect() z Redux. HOC nadal ma sens gdy: dodajesz logikę do komponentu, który nie możesz modyfikować (biblioteki zewnętrzne); potrzebujesz wstrzyknąć props na podstawie kontekstu. Wady: wrapper hell (głęboka hierarchia HOC), nieintuicyjne debugowanie, konflikty nazw props. Custom hooks są preferowane gdy to możliwe.

Wzorce i architektura
34 Co to jest Compound Components Pattern?

Compound Components to wzorzec, w którym rodzic i dzieci komunikują się przez niejawny, wspólny stan — bez prop drilling. Komponenty "wie" o sobie nawzajem przez Context.

Przykład: komponent <Select> z dziećmi <Select.Option>. Select zarządza stanem (który option wybrany), każde Option przez useContext wie o stanie rodzica i może je zmieniać. Użytkownik API (developer) ma pełną kontrolę nad strukturą HTML i stylami — elastyczność bez utraty funkcjonalności. Używany w: Radix UI, Headless UI, Reach UI, własne design systemy.

Wzorce i architektura
35 Czym jest Error Boundary i jak obsługiwać błędy w React?

Error Boundary to komponent klasowy implementujący componentDidCatch i getDerivedStateFromError. Łapie błędy JS w poddrzewie komponentów i wyświetla fallback UI zamiast crashować całą aplikację.

Ważne: Error Boundaries nie łapią błędów w: event handlers (tam użyj try/catch), asynchronicznym kodzie (setTimeout, promises), SSR, samej Error Boundary. React 19 planuje wsparcie dla funkcyjnych Error Boundaries. Biblioteka react-error-boundary daje wygodne API z reset capabilities: <ErrorBoundary FallbackComponent={Error} onReset={resetApp}>. Stosuj granularnie — różne boundary dla różnych sekcji UI.

Wzorce i architektura
36 Co to są React Portals i kiedy ich używać?

Portals pozwalają renderować dziecko komponentu w innym węźle DOM niż rodzic — najczęściej bezpośrednio w document.body. Tworzone przez ReactDOM.createPortal(child, container).

Kiedy używać: modals/dialogi — unikają problemów z overflow: hidden i z-index rodziców; tooltips/popovers — muszą wychodzić poza scrollowalny kontener; floating notifications. Ważne: portal jest poza DOM-em rodzica, ale nadal wewnątrz drzewa React — eventy bąbelkują przez drzewo React normalnie, nie przez drzewo DOM.

Wzorce i architektura
37 Czym jest Controlled vs Uncontrolled component?

Controlled component: wartość formularza jest zarządzana przez React state. Każda zmiana pola → handler → setState → re-render z nową wartością. React jest "jedynym źródłem prawdy". Pełna kontrola: walidacja w locie, formatowanie, zablokowane znaki.

Uncontrolled component: DOM sam zarządza wartością, React czyta ją przez ref (inputRef.current.value) na żądanie (np. przy submit). Mniej kodu, lepsza wydajność dla bardzo dużych formularzy. Biblioteka React Hook Form używa modelu uncontrolled z ref-based approach dla maksymalnej wydajności przy minimalnym kodzie — dlatego ogranicza re-rendery do minimum.

Wzorce i architektura
38 Co to jest React Router i jak działa client-side routing?

React Router v6 to najpopularniejsza biblioteka routingu dla React. Client-side routing działa przez History API przeglądarki — zmiana URL nie powoduje przeładowania strony, React renderuje odpowiedni komponent.

Kluczowe elementy: <BrowserRouter>, <Routes> + <Route path="" element={} />, useNavigate(), useParams(), useSearchParams(), useLocation(). React Router v6.4+ dodaje Data API: loader (fetch danych przed renderem), action (obsługa form submit) — upodabniając do Remix. TanStack Router zyskuje popularność jako type-safe alternatywa z pełną inferencją TypeScript.

Wzorce i architektura
39 Jak testować komponenty React?

Ekosystem testowania React: Vitest/Jest — test runner; React Testing Library (RTL) — renderowanie i interakcja z komponentami w sposób zbliżony do użytkownika (getByRole, userEvent.click); MSW (Mock Service Worker) — mockowanie API na poziomie sieciowym; Playwright/Cypress — testy E2E.

Filozofia RTL: "Test the way users use your software" — nie testuj implementacji (nazwy stanów, nazwy metod), testuj zachowanie (tekst wyświetlony, dostępność elementu, reakcja na kliknięcie). Priorytet selektorów: role > label > text > testId. Custom hooks testuje się osobno przez renderHook() z RTL.

Wzorce i architektura
40 Czym jest Next.js i jaką wartość dodaje nad czystym React?

Next.js to pełnoprawny framework oparty na React. Dodaje: file-based routing (folder = route), SSR/SSG/ISR/RSC out-of-box, API routes (backend w tym samym projekcie), Image Optimization, font optimization, built-in bundler (Turbopack), middleware, deployment na Vercel bez konfiguracji.

App Router (Next.js 13+) to podejście oparte na Server Components domyślnie — komponenty są SC chyba że oznaczymy "use client". Pozwala colocować Server Actions (server-side mutations) bezpośrednio z komponentami. Next.js wybrałbyś dla: aplikacji produkcyjnych wymagających SEO, aplikacji fullstack z jedną bazą kodu, gdy chcesz najlepsze możliwe Core Web Vitals out-of-box.

Wzorce i architektura