Przewodnik po rozmowach kwalifikacyjnych z React: hooksy, renderowanie i to, o co pytają duże firmy.
Wirtualny DOM, pułapki związane z hooksami, wydajność, zarządzanie stanem, React 18, ćwiczenia z kodowaniem na żywo oraz sposoby wyjaśniania przyczyn ponownego renderowania.
Podczas rozmów rekrutacyjnych z React w dużych firmach rzadko ocenia się umiejętność deklamacji dokumentacji. Zamiast tego sprawdza się, czy kandydat rozumie mechanizmy działania – dlaczego komponent jest renderowany ponownie, dlaczego efekt uruchamia się dwa razy, dlaczego aktualizacja stanu nie pojawia się natychmiast. Kandydaci, którzy potrafią wyjaśnić dlaczego, przewyższają tych, którzy znają tylko jak.
Poniżej przedstawiono typowe tematy, które faktycznie pojawiają się podczas rozmów: podstawy, hooks, wydajność, wzorce projektowe oraz trudne pytania, które pojawiają się wszędzie.
1. Podstawowe zasady
Pytania wprowadzające prawie zawsze dotyczą:
- Virtual DOM – czym jest i dlaczego aktualizacje wydają się szybsze (porównywanie różnic zamiast bezpośrednich zmian w DOM).
- Reconciliation – jak React decyduje, co aktualizować (klucze, sprawdzanie typu elementu).
- JSX – „cukierkowy” język, który kompiluje się do
React.createElement(); trzeba to dobrze znać.
value + onChange); te niekontrolowane odczytują DOM za pośrednictwem refów.Zadanie na podstęp: „Dlaczego nie użyć indeksu tablicy jako klucza?” Odpowiedz konkretnym przykładem przestawienia lub dodania elementu, w którym React przypisuje stan do niewłaściwego wiersza.
2. Hooks (najbardziej złożona część rozmowy kwalifikacyjnej)
useState
- Zaktualizowania są asynchroniczne lub grupowane.
- Zastarzałe zamknięcia: kilka wywołań
setCount(count + 1)w jednym zdarzeniu dzieli się tym samym wartościącount;setCount(prev => prev + 1)rozwiązuje ten problem.
useEffect
- Zależności:
[]raz, pomijane przy każdym renderowaniu, wyświetlane tylko gdy ulegną zmianie. - Czas i cel czyszczenia (wycieki pamięci, anulowanie subskrypcji/pobierania danych).
- Dlaczego efekty działają dwa razy w trybie rozwojowym — Strict Mode w React 18 wywołuje funkcje dwukrotnie, aby ujawnić brakujące czyszczenie. Prawie wszyscy napotykają to problem raz.
useMemo vs useCallback
useMemoprzechowuje w pamięci wartość;useCallbackprzechowuje w pamięci tożsamość funkcji.- Oba zapewniają równość referencyjną dla dzieci funkcji
React.memolub tablic zależności. - Nadużywanie ma swoje konsekwencje; rozmówcy o pracę lubią słyszeć, że memozacja nie jest bezkosztowa.
useRef
- Zmienna wartość pomiędzy renderowaniami bez ponownego renderowania.
- Węzły DOM, poprzednie wartości, identyfikatory timerów.
useContext
- Zakończa wiercenie właściwości dla poddrzewa.
- Uwaga: aktualizacja kontekstu ponownie renderuje każdego konsumenta w poddrzewie, włączając te, które czytają tylko jedno pole.
useReducer
- Należy go preferować, gdy logika jest złożona lub kilka pól aktualizuje się jednocześnie (lokalne reduktory w stylu Redux).
Custom hooks
- Bądź gotowy do pisania funkcji takich jak
useDebounce,useFetchlubuseLocalStorage„na żywo” – to jeden z najczęściej spotykanych praktycznych ćwiczeń.
3. Renderowanie i wydajność
Tutaj osoby o poziomie średnim i wyższym oddzielają się od siebie.
- Dlaczego ponownie renderować? Ponieważ renderuje się element rodzicielski, zmienia się stan, kontekst lub właściwości, które wyglądają tak samo, ale są nowymi referencjami.
- React.memo – porównanie właściwości na poziomie powierzchniowym; bezużyteczne, jeśli za każdym razem przekazuje się nowe obiekty/funkcje (należy je łączyć z
useMemo/useCallback).
React.lazy + Suspense.react-window dla bardzo długich list.Klasyczne pytanie: lista z 10 000 wierszami zwalnia podczas wpisywania zapytania wyszukiwania. Należy oczekiwać funkcji debounce, wirtualizacji oraz wierszy zastosowanych memoizacji.
4. Zarządzanie stanem
- Stan lokalny, globalny i serwerowy — odrębne nazewnictwo stanu serwerowego (cache, revalidate, loading/error) od stanu interfejsu robi dobre wrażenie na ekspertach.
- Context vs Redux/Zustand — Context do rzadko używanych globalnych wartości (temat, autoryzacja); Redux/Zustand, gdy potrzebne są middleware, narzędzia, złożone aktualizacje lub częste zapisy bez problemów związanych z Contextem.
- React Query / SWR / TanStack Query — buforowanie, ponowne pobieranie w tle, usuwanie duplikatów, aby uniknąć ponownego tworzenia mechanizmu pobierania danych z
useEffect. - Podstawy Redux (jeśli stos go używa): akcje, reduktory, magazyn danych, middleware typu thunk/saga, czyste reduktory.
5. Wzorce projektowe
- HOCs — otaczanie komponentu; klasyczny przykład
withAuth. - Render props — współdzielenie logiki za pomocą funkcji jako właściwości; w większości przypadków zastąpione przez haki, ale koncepcja ta nadal jest istotna.
- Komponenty złożone — komponenty siostrzane dzielące się stanem za pośrednictwem kontekstu (
Select/Select.Option). - Komponenty kontenerowe/prezentacyjne — dane vs interfejs użytkownika; z hakami separacja jest mniej sztywna, ale nadal ma znaczenie.
- Kompozycja zamiast dziedziczenia — preferowana metoda ponawnego użycia w React; bądź gotów ją uzasadnić.
6. Życiowy cykl klasy (nadal często pytane)
Firmy, które wciąż preferują hooksy, badają nadal podstawy lub starsze bazy kodu.
componentDidMount≈useEffect(() => {}, [])componentDidUpdate≈ efekt z zależnościamicomponentWillUnmount≈ czyszczenie efektów- Grenice błędów — dostępne tylko dla klas (
componentDidCatch/getDerivedStateFromError); hooksy nie mają odpowiednika, dlatego istnieją takie wrapperzy jakreact-error-boundary.
7. Znajomość React 18+
- Renderyzacja równoległa — możliwość przerwania operacji dla bardziej responsywnego interfejsu.
useTransition— oznaczanie niepilnych aktualizacji, aby pisanie pozostawało szybkie.useDeferredValue— opóźnienie niekrytycznych elementów interfejsu użytkownika.- Automaticzne grupowanie zadań — grupowanie operacji wewnątrz obietnic, timeoutów oraz rdzennych obsług (nie tylko obsług React).
- Suspense dla danych — szczególnie przydatne w architekturach typu Next.js/Remix.
- Komponenty serwerowe — gdzie i co się uruchamia oraz dlaczego pliki klienta są mniejsze.
8. JavaScript, który się zakrada
- Zamknięcia funkcji — przestarzały stan hooków.
- Pętla zdarzeń / zadania mikro i makro — dlaczego grupowanie zadań działa w ten sposób.
- Przypisywanie wartości
this— w przypadku, gdy używane są klasy. - Debounce vs throttle — praktycznie zawsze proponowane jako rozwiązanie na „optymalizację pola wyszukiwania”.
- Porównanie powierzchowne vs głębokie —
React.memo/useMemooraz dlaczego literale obiektów uniemożliwiają memoizację. - Promises / async-await — problemy z jednoczesnym wykonywaniem zapytań, gdy użytkownicy szybko piszą.
- Testing Library — skupienie na zachowaniu aplikacji, a nie na jej wewnętrznej strukturze (zapytania dotyczące ról i tekstu).
- Jest — symulowanie API; znajomość ograniczeń związanych ze zdjęciami stanu aplikacji.
- Testy jednostkowe, integracyjne i end-to-end oraz miejsce, w którym zazwyczaj znajdują się testy komponentów.
- Wyszukiwanie i autodopisywanie z opóźnieniem
- Sprawdzony kod
useFetchz obsługą stanu ładowania, błędów i danych - Przewijanie nieskończone lub paginacja
- Okna modalne za pomocą portalu (
createPortal) oraz powód ich istnienia (unikanie przepełnienia ekranu i problemów z wartością z-index przy jednoczesnym pozostawaniu w drzewie React dla obsługi zdarzeń i kontekstu) - Licznik z funkcjami cofnięcia i przywrócenia za pomocą
useReducer - Zadanie „znajdź błąd” dotyczące przestarzałych zamykaczy funkcji lub brakujących zależności
9. Testowanie
10. Kodowanie na żywo z powtarzaniem
Przykładowe omówienie
„Dlaczego ten useEffect tworzy nieskończony pętlę?”
useEffect(() => {
setData({ ...data, updated: true });
}, [data]);
Odpowiedź na poziomie eksperta: efekt wymienia data jako zależność, a następnie zapisuje do data nowy obiekt, dzięki czemu przy każdym uruchomieniu zmienia się zależność i efekt jest natychmiast ponownie uruchamiany. Rozwiązaniem jest usunięcie data z listy zależności w sytuacjach, gdy nie powinien on powodować ponownego uruchomienia, przeniesienie operacji aktualizacji poza efekt lub użycie funkcjonalnego aktualizatora z ściślejszą listą zależności.
To, co odróżnia dobre odpowiedzi na pytania z React podczas rozmowy kwalifikacyjnej, to wyjaśnienie dlaczego coś się psuje – a nie tylko proponowanie poprawki.
Zakończenie
Głębia zrozumienia przewyższa pamiętanie powierzchni API. Pracodawcy chcą znać zachowanie renderowania, zasady działania zamknięć funkcji oraz kompromisy dotyczące wydajności – te błędy, które pojawiają się w produkcji. Przygotuj się, tworząc małe komponenty, które celowo zawodzą (stare zamknięcia funkcji, brakujące zależności, marnotrawne ponowne renderowanie), i naprawiając je. To właśnie ten instynkt debugowania jest tym, co faktycznie ocenia się podczas rozmowy kwalifikacyjnej.
Gdy ćwiczysz, ogranicz sobie czas tak jak to robi się podczas rozmów kwalifikacyjnych: wyjaśnij zasady działania Virtual DOM w sześćdziesięciu sekundach, następnie napraw błąd związany ze starym zamknięciem funkcji, a potem zaprojektuj mechanizm opóźnionych zapytań. Taka kolejność odpowiada temu, w jaki sposób faktycznie przebiegają takie rozmowy.
Jak zazwyczaj eskalują rozmowy kwalifikacyjne
Rozgrzewki dotyczą Virtual DOM, kontrolowanych wprowadzeń i klawiszy. W środkowej fazie omawiane są hooki: zgrupowane aktualizacje, problem podwójnych efektów w trybie Strict Mode, memo versus callback oraz tworzenie własnego hooka na żywo. W zaawansowanej fazie skupiamy się na kwestiach wydajności – listach z dziesięcioma tysiącami wierszy, problemie context thrash, dowodach uzyskanych za pomocą Profilera – oraz na wyborze architektury pomiędzy Context, Redux/Zustand a TanStack Query do zarządzania stanem serwera.
Zachowaj osobisty repozytorium z elementami „celowo uszkodzonymi”: licznik stale-closure, efekt braku zależności, zmemorizowana lista, która nadal jest renderowana ze względu na obiekty inline, oraz modal typu portal. Wyjaśnienie tych czterech napraw na głos obejmuje zaskakująco dużą część czasu poświęconego na programowanie na żywo i pracę przy tablicy.
Jeśli w opisie stanowiska wspomniano React 18+, bądź przygotowany z jednym zdaniem na temat równoległego renderowania, przejść, wartości odroczonych, automatycznego grupowania aktualizacji oraz Server Components. Głębsza znajomość jednej konkretnej implementacji jest lepsza niż ogólne pojęcie o każdym RFC.
Powiązane materiały
- Dwadzieścia pytań z interviewu o React, które odróżniają użycie od zrozumienia — Virtual DOM, klucze, efekty, memoizacja, Context, SSR i hydratacja — wyjaśnione poprzez trudne kwestie, które faktycznie badają pytający, a nie definicje z podręczników.
- Przestań synchronizować stan z useEffect: bezpieczniejszy wzorzec w React — Dowiedz się, dlaczego używanie useEffect do synchronizacji stanu pochodnego powoduje sytuacje konkurencji i dodatkowe renderowania, oraz jak zastąpić to wyprowadzaniem stanu w czasie renderowania i użyciem atrybutu key.