← Wszystkie tematy W 15% ogłoszeń · 42 z 286 wszystkich ofert JS

Biblioteki stanu

Sześć sposobów na pudełko z zabawkami

Nazwy bibliotek stanu (TanStack Query, Redux Toolkit, Zustand, Jotai, MobX, XState) padają w 42 z 286 ofert JS. Senior powinien umieć powiedzieć, który rodzaj stanu czym obsłużyć i dlaczego, a nie tylko „używałem Reduxa”.

Opanowane 0 z 5 pytań

Co piszą w ogłoszeniach

Scena pierwsza · rodzaje stanu

Każda zabawka do swojego pudełka

Zanim wybierzesz bibliotekę, sprawdź, jaki to rodzaj stanu. Jedzenie z cudzej lodówki (dane z serwera) ma datę ważności i trzeba je odświeżać. Zabawki całego domu (koszyk) są wspólne. Zabawka jednego pokoju (otwarte okienko) nikogo poza nim nie obchodzi. Kliknij rzecz, a potem pudełko, do którego pasuje.

0 / 8

Kliknij rzecz z góry, potem pudełko.

Scena druga · ta sama funkcja, różne biblioteki

Koszyk zbudowany osiem razy

Ta sama funkcja: przycisk „Do koszyka” w liście produktów i licznik w nagłówku. Zobacz, jak wygląda w każdej bibliotece, jaki ma model myślenia i kto się przerenderuje po kliknięciu.

Kto się obudzi po „Do koszyka”?
Nagłówek (licznik) Lista produktów Filtry
 

Wybierz bibliotekę i kliknij „Do koszyka”.

Scena trzecia · pomocnik wyboru

Którą wybrać w nowym projekcie?

Odpowiedz na trzy pytania o swój projekt. Dostaniesz zestaw, który da się obronić na rozmowie, razem z uzasadnieniem.

Porównajmy

Redux Toolkit czy Zustand?

Redux ToolkitZustand
Model Jedna skrzynia z opiekunem i karteczkami.Flux: store, akcje, reducery (Immer), middleware. Mała skrzynka, do której sięgasz wprost.Store na hookach: create((set) => ({...})), bez providera.
Ile pisania Więcej, ale wszystko według reguł.Slice, typy akcji, provider, konwencje dla dużych zespołów. Mało.Kilka linijek na store, akcje to zwykłe funkcje.
Kto się budzi Tylko ci, których selektor zwrócił coś nowego.useSelector z porównaniem referencji, reselect do wyliczeń. Tak samo.useStore(s => s.count), useShallow dla obiektów.
Dane z serwera RTK Query w zestawie.Cache, invalidacja tagami, generowane hooki. Nie jego zadanie.Łączy się z TanStack Query.
Kiedy? Duża aplikacja, wiele zespołów, złożona logika i DevTools z time travel. Mały i średni stan klienta, szybki start, mało ceremonii.

Najpierw rodzaj

Serwer, klient, UI, URL, formularz, proces. Biblioteka to druga decyzja.

Lodówka osobno

Dane z API do TanStack Query albo RTK Query. W store zostaje wtedy niewiele.

Budź tylko potrzebnych

Selektory, atomy albo obserwacja. Context tylko na rzadkie zmiany.

Sprawdź się

Pytania z rozmów

Najpierw odpowiedz na głos, dopiero potem rozwiń odpowiedź.

  1. Jakie rodzaje stanu są we frontendzie i czym obsługujesz każdy z nich?

    Moja odpowiedź

    Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

    Pokaż odpowiedź

    Dla przedszkolaka: Są zabawki z cudzej lodówki (dane z serwera), zabawki całego domu (koszyk), zabawki jednego pokoju (otwarte okienko), kartka na drzwiach (adres strony) i plan zabawy krok po kroku (kreator). Każda ma swoje pudełko.

    Na rozmowę: Stan serwerowy (lista produktów, profil): TanStack Query, RTK Query lub SWR, bo potrzebuje cache, odświeżania i invalidacji. Globalny stan klienta (koszyk, preferencje): Zustand, Redux Toolkit, Jotai. Lokalny stan UI (modal, hover): useState. Stan w URL (filtry, paginacja, zakładka): search params, bo da się go udostępnić i przeżywa odświeżenie. Formularz: React Hook Form. Złożone przepływy z wieloma krokami i niedozwolonymi przejściami: XState albo reducer z jawnymi stanami. Najczęstszy błąd to wrzucanie wszystkiego do jednego globalnego store’a.

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
  2. Redux Toolkit vs Zustand vs Jotai: czym się różnią w modelu i kiedy który?

    Moja odpowiedź

    Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

    Pokaż odpowiedź

    Dla przedszkolaka: Redux to jedna wielka skrzynia z opiekunem, który przyjmuje karteczki z prośbami. Zustand to mała skrzynka bez formalności. Jotai to dużo malutkich pudełeczek, które można ze sobą łączyć.

    Na rozmowę: Redux Toolkit to model flux: jeden store, akcje, reducery, middleware, DevTools z time travel. Daje przewidywalność i konwencje dla dużych zespołów, kosztem ceremonii. Zustand to minimalny store na hookach z selektorami, bez providera i akcji, idealny dla średnich aplikacji. Jotai jest atomowy: stan składa się z małych atomów i atomów pochodnych, a renderuje się tylko to, co używa zmienionego atomu, co sprawdza się przy dużo niezależnego, drobnego stanu (edytory, formularze z wieloma polami). MobX to obserwowalne obiekty z automatycznym śledzeniem zależności.

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
  3. Czy TanStack Query zastępuje Reduxa?

    Moja odpowiedź

    Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

    Pokaż odpowiedź

    Dla przedszkolaka: Nie do końca. Lodówka (dane z serwera) i pudełko z zabawkami (stan aplikacji) to dwie różne rzeczy. Gdy dane z serwera trafią do lodówki, w pudełku zostaje bardzo mało.

    Na rozmowę: Zastępuje tę część, która w Reduxie zwykle była największa: dane z API wraz z loading/error, cache, deduplikacją, odświeżaniem w tle, paginacją i optimistic updates. Po migracji globalny stan klienta często kurczy się do kilku wartości, które obsłuży Zustand albo nawet Context. Jeśli projekt i tak stoi na Reduxie, naturalnym odpowiednikiem jest RTK Query. Redux nadal ma sens przy złożonej logice klienta, middleware, undo/redo i wymaganiu jednego przewidywalnego źródła zdarzeń.

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
  4. Kiedy sięgnąć po maszynę stanów (XState)?

    Moja odpowiedź

    Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

    Pokaż odpowiedź

    Dla przedszkolaka: Gdy zabawa ma ścisłe zasady: najpierw to, potem tamto, a niektórych ruchów nie wolno zrobić. Wtedy rysujesz plan zabawy i robot pilnuje, żeby nikt nie oszukiwał.

    Na rozmowę: Gdy logika ma wiele stanów i zdarzeń, a część przejść jest niedozwolona: kreator checkoutu, płatność z 3DS, upload z ponawianiem, odtwarzacz wideo, czat ze streamingiem (idle → waiting → streaming → done / error / stopped). Maszyna wyklucza niemożliwe kombinacje flag (isLoading && isError), daje diagram do rozmowy z produktem i testy przejść. Koszt to krzywa nauki i więcej kodu. Przy prostszych przypadkach wystarczy useReducer z discriminated union.

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
  5. Jak zmigrować dużą aplikację z Reduxa (z sagami) na TanStack Query + Zustand bez big bangu?

    Moja odpowiedź

    Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

    Pokaż odpowiedź

    Na rozmowę: Migracja przyrostowa ekran po ekranie. Najpierw inwentaryzacja: co w store to cache API, a co prawdziwy stan klienta. Nowe ekrany od razu na TanStack Query. Stare przenoszę po jednym zasobie: query zamiast sagi i slice’a, a w przejściu synchronizuję dane do starego store’a (setQueryData / dispatch), dopóki ktoś z nich czyta. Wspólny klient HTTP i obsługa błędów. Metryki: liczba sag, rozmiar store’a, błędy. Stan klienta przenoszę na końcu albo zostawiam w RTK, jeśli działa. Najważniejsze, żeby każdy krok był wdrażalny osobno.

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
Poziom wyżej

Wersja dla seniora

Tak wyglądają pytania na seniora i leada: nie ma jednej dobrej odpowiedzi, liczy się to, jak ważysz kompromisy i czy mówisz o skali, ryzyku i ludziach.

Przypadek 1

Monolit na Reduxie z sagami, który nikt nie chce dotykać

Panel dla sprzedawców ma 4 lata. Cały stan, łącznie z danymi z 60 endpointów, siedzi w Reduxie, a pobieranie danych robi 120 sag. Nowe funkcje powstają wolno, testy sag są kruche, a przy przełączaniu ekranów migają stare dane. Masz zaproponować kierunek na najbliższe pół roku.

Zanim rozwiniesz: powiedz na głos, jak byś to rozwiązał, i nazwij co najmniej jeden kompromis.

Moje rozwiązanie

Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

Pokaż, czego szuka rekruter, i modelową odpowiedź

Co sprawdza rekruter

  • Czy rozróżniasz stan serwerowy od stanu klienta
  • Czy proponujesz migrację przyrostową zamiast przepisywania
  • Czy umiesz zmierzyć postęp i ryzyko
  • Czy myślisz o zespole: konwencje, review, wdrożenie ludzi

Odpowiedź seniora

Zaczynam od inwentaryzacji: dzielę zawartość store’a na cache danych z API i prawdziwy stan klienta. Zwykle okazuje się, że 80% to cache, a migające dane biorą się z ręcznie pisanego loading/error i braku kluczy zależnych od parametrów.

Decyzja: dane z API przenoszę do TanStack Query, a jeśli zespół chce zostać w ekosystemie Redux, do RTK Query. Stan klienta zostaje w Redux Toolkit albo trafia do Zustanda, jeśli zostanie go niewiele. Nowe ekrany od pierwszego dnia powstają w nowym podejściu. Stare migruję zasobami: jedno query zastępuje sagę i slice, a dopóki stary kod czyta dane ze store’a, zapisuję je tam w onSuccess. Każdy krok jest osobnym, wdrażalnym PR-em za feature flagą.

Mierzę liczbę sag i slice’ów z danymi API, błędy w Sentry i czas dostarczania funkcji. Zespołowi daję wzorcowy moduł, ADR z uzasadnieniem i regułę ESLint blokującą nowe sagi. Ryzyka to dwa źródła prawdy w okresie przejściowym i niespójna invalidacja, więc mutacje od razu dostają invalidateQueries po kluczach.

Typowe wpadki

  • „Przepiszmy wszystko na Zustanda w sprincie”
  • Przeniesienie danych z API do Zustanda, czyli zmiana biblioteki bez zmiany modelu
  • Brak planu na okres, w którym działają oba światy
  • Mówienie tylko o technologii, bez metryk i ludzi

Dopytają o

  • Jak zaprojektujesz klucze zapytań, żeby invalidacja była przewidywalna?
  • Co zrobisz z logiką, która w sagach orkiestruje kilka żądań po kolei?
  • Jak przekonasz zespół, który dobrze zna Reduxa?
Zapytaj Claude Rozwiń caseZagraj interviewera
Przypadek 2

Edytor dokumentu z setkami pól i zacinaniem przy pisaniu

Budujecie edytor oferty: 300 pól, wyliczane sumy, walidacja zależna od innych pól, autozapis co kilka sekund i podgląd PDF obok. Przy szybkim pisaniu interfejs zacina się, a profiler pokazuje, że każda litera renderuje cały formularz.

Zanim rozwiniesz: powiedz na głos, jak byś to rozwiązał, i nazwij co najmniej jeden kompromis.

Moje rozwiązanie

Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

Pokaż, czego szuka rekruter, i modelową odpowiedź

Co sprawdza rekruter

  • Czy wiesz, skąd biorą się re-rendery w dużym stanie
  • Czy znasz modele: atomowy, store z selektorami, niekontrolowane pola
  • Czy oddzielasz pilne aktualizacje od kosztownych obliczeń

Odpowiedź seniora

Problem to jeden duży obiekt stanu w useState lub Context, więc każda zmiana tworzy nowy obiekt i budzi wszystkich. Mierzę w React Profilerze, które poddrzewa renderują się przy jednej literze.

Rozwiązanie zależy od charakteru danych. Dla formularza z niezależnymi polami najtańsza jest zmiana na pola niekontrolowane z React Hook Form, gdzie pisanie nie renderuje Reacta, a watch subskrybuje tylko potrzebne pola. Jeśli wartości są współdzielone przez wiele widoków (sumy, podgląd), stosuję model atomowy (Jotai): każde pole to atom, sumy to atomy pochodne, więc zmiana pola renderuje tylko to pole i zależne od niego wyliczenia. Alternatywa to Zustand z wąskimi selektorami i shallow compare.

Podgląd PDF i autozapis oznaczam jako mniej pilne: useDeferredValue albo debounce, a ciężkie generowanie w Web Workerze. Autozapis wysyła diff z wersją dokumentu, żeby nie nadpisać zmian z innej karty.

Typowe wpadki

  • Dokładanie memo do wszystkich komponentów bez zmiany modelu stanu
  • Trzymanie 300 pól w Context
  • Autozapis na każdą literę

Dopytają o

  • Jak obsłużysz konflikt, gdy dwie osoby edytują tę samą ofertę?
  • Gdzie trzymasz walidację: w schemacie, w atomach czy na serwerze?
  • Jak przetestujesz, że wydajność nie wróci po kolejnych zmianach?
Zapytaj Claude Rozwiń caseZagraj interviewera
Przypadek 3

Checkout z płatnością, 3DS i powrotem z banku

Proces zakupu ma 5 kroków, kilka metod płatności, weryfikację 3D Secure w osobnym oknie, timeouty i możliwość powrotu z banku na inny adres. Obecny kod to useState z flagami isLoading, isPaying, isError, is3ds i stepIndex. Zdarzają się podwójne obciążenia i ekrany „zawieszone” po powrocie z banku.

Zanim rozwiniesz: powiedz na głos, jak byś to rozwiązał, i nazwij co najmniej jeden kompromis.

Moje rozwiązanie

Zapisuje się samo w tej przeglądarce. Kopię zrobisz na stronie Notatki.

Pokaż, czego szuka rekruter, i modelową odpowiedź

Co sprawdza rekruter

  • Czy rozpoznajesz problem niemożliwych kombinacji stanów
  • Czy znasz maszyny stanów i wiesz, kiedy się opłacają
  • Czy myślisz o idempotencji i odtworzeniu stanu po przeładowaniu

Odpowiedź seniora

Pięć niezależnych flag daje 32 kombinacje, z których większość jest niemożliwa, a kod i tak musi je jakoś obsłużyć. Modeluję proces jako maszynę stanów (XState albo useReducer z discriminated union): stany koszyk, dane, płatność, oczekiwanie na 3DS, potwierdzone, odrzucone, z jawnymi przejściami. W stanie płatności zdarzenie ZAPŁAĆ jest ignorowane, więc podwójne kliknięcie nie wyśle dwóch płatności.

Po stronie API każda płatność ma idempotency key generowany przy wejściu w krok płatności. Po powrocie z banku stan odtwarzam z serwera (status zamówienia po id z URL), a nie z pamięci przeglądarki, bo karta mogła zostać przeładowana. Diagram maszyny służy też do rozmowy z produktem i QA, a przejścia testuję jednostkowo bez renderowania UI.

Typowe wpadki

  • Dokładanie kolejnej flagi isRedirecting
  • Trzymanie stanu płatności tylko w pamięci przeglądarki
  • Blokowanie przycisku jako jedyna ochrona przed podwójną płatnością

Dopytają o

  • Co pokażesz, gdy bank nie odpowie przez 2 minuty?
  • Jak przetestujesz wszystkie przejścia?
  • Czy cała aplikacja powinna być na XState? Dlaczego nie?
Zapytaj Claude Rozwiń caseZagraj interviewera

Skróty klawiszowe

/
szukaj tematu
Enter
w wyszukiwarce: otwórz pierwszy wynik
N
notatki do tematu
[ ]
poprzedni / następny temat
G potem T
lista tematów
G potem P
powtórka
G potem N
wszystkie notatki
D
jasny / ciemny motyw
?
ta ściąga
Spacja, 1, 2, 3
w powtórce: pokaż, oceń

Pod każdym pytaniem są też skróty do Claude: rozwinięcie tematu, próbna rozmowa i ocena Twojej odpowiedzi z notatki.