← Wszystkie tematy W 38% ogłoszeń · 18 z 47 ogłoszeń frontend React

Zarządzanie stanem

Wspólna skrzynia na zabawki

Zarządzanie stanem jest w 18 z 47 ogłoszeń, a „complex client-side state” to typowa fraza przy czatach i dashboardach. Pytania dotyczą wyboru narzędzia i re-renderów.

Opanowane 0 z 4 pytań

Co piszą w ogłoszeniach

Scena · gdzie trzymać stan

Wspólna skrzynia na zabawki

Na samej górze domu mieszka imię właściciela i kolor ścian (motyw). Awatar w pokoju na dole potrzebuje imienia, a Nagłówek i Ustawienia potrzebują koloru. Są trzy sposoby, żeby im to dostarczyć: podawać z rąk do rąk (propsy), postawić jedną wspólną skrzynię (Context) albo zrobić skrytki z imiennymi przegródkami (store z selektorami). Zmień imię albo kolor i patrz, kto się zatrzęsie.

Apprendery: 1
Layoutrendery: 1
Nagłówekrendery: 1
Sidebarrendery: 1
Awatarrendery: 1
Treśćrendery: 1
Ustawieniarendery: 1

Zmień imię w każdym z trzech trybów i porównaj liczbę renderów.

Porównajmy

Ręce, skrzynia czy skrytki?

ContextStore (Redux, Zustand)
Do czego? Rzadko zmieniające się rzeczy dla wielu pokoi.Motyw, język, zalogowany użytkownik, wstrzykiwanie zależności. Często zmieniany, złożony stan aplikacji.Koszyk, filtry, edytor, stan współdzielony przez wiele ekranów.
Kto się trzęsie przy zmianie? Każdy, kto zagląda do skrzyni.Wszyscy konsumenci Contextu, gdy zmieni się value. Tylko ten, czyja przegródka się zmieniła.Selektor: useStore(s => s.user.name) renderuje tylko przy zmianie wyniku.
Jak to poprawić? Kilka mniejszych skrzyń.Podział Contextu, useMemo na value, osobny context dla akcji. Przegródki już są.Memoizowane selektory (reselect), shallow compare.
Narzędzia Wbudowany w Reacta.Zero zależności. Osobna biblioteka.Redux Toolkit (DevTools, time travel, middleware), Zustand (mały, prosty).
A dane z serwera? Nie wkładaj ich do skrzyni. Też nie!To osobny gatunek stanu: TanStack Query / RTK Query (cache, odświeżanie).

Najpierw najbliżej

Trzymaj stan w pokoju, który go używa. Wyżej przenoś dopiero, gdy musisz.

Skrzynia

Context: dobry na rzadkie zmiany. Każda zmiana budzi wszystkich, którzy do niej zaglądają.

Przegródki

Store z selektorami budzi tylko tych, czyja przegródka się zmieniła.

Sprawdź się

Pytania z rozmów

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

  1. Kiedy wystarczy useState / Context, a kiedy potrzebujesz Reduxa lub Zustanda?

    Moja odpowiedź

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

    Pokaż odpowiedź

    Dla przedszkolaka: Zabawki trzymasz w swoim pokoju. Wspólną skrzynię stawiasz, gdy kilka pokoi potrzebuje tych samych rzeczy. Skrytki z przegródkami robisz, gdy zabawek jest dużo i ciągle się zmieniają.

    Na rozmowę: Domyślnie useState/useReducer jak najbliżej miejsca użycia, a przy współdzieleniu podnoszę stan do wspólnego rodzica. Context do rzadko zmieniających się wartości globalnych (motyw, język, user, wstrzykiwanie zależności). Store (Zustand, Redux Toolkit), gdy stan klienta jest duży, często się zmienia, jest współdzielony przez wiele ekranów albo potrzebuję selektorów, middleware i DevTools. Dane z serwera w ogóle nie trafiają do store’a, tylko do TanStack Query lub RTK Query.

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
  2. Dlaczego Context potrafi powodować za dużo re-renderów i jak temu zaradzić?

    Moja odpowiedź

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

    Pokaż odpowiedź

    Dla przedszkolaka: Gdy coś zmieni się w skrzyni, budzą się wszyscy, którzy do niej zaglądają, nawet jeśli szukali innej zabawki.

    Na rozmowę: Każda zmiana value providera renderuje wszystkich konsumentów useContext, niezależnie od tego, której części używają. Do tego nowy obiekt value w każdym renderze providera budzi ich zawsze. Rozwiązania: useMemo na value, podział na kilka kontekstów (dane osobno, akcje osobno, rzadkie osobno), przekazywanie dzieci jako children, żeby re-render providera nie renderował całego drzewa, a przy częstych zmianach store z selektorami (Zustand, use-context-selector).

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
  3. Stan serwerowy a stan klienta: dlaczego warto je rozdzielić?

    Moja odpowiedź

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

    Pokaż odpowiedź

    Dla przedszkolaka: Jedzenie z lodówki ma datę ważności i ktoś inny też może je zjeść. Zabawki w pokoju są tylko Twoje.

    Na rozmowę: Stan serwerowy jest kopią danych, których właścicielem jest backend: może się zestarzeć, wymaga cache, odświeżania, deduplikacji żądań, invalidacji po mutacji, retry, paginacji. Robią to TanStack Query, SWR, RTK Query. Stan klienta (otwarty modal, filtr, szkic formularza) jest w pełni nasz i synchroniczny. Trzymanie danych z API w Reduxie zmusza do ręcznego pisania loading/error/cache i kończy się rozjazdem. Po rozdzieleniu store robi się mały i prosty.

    Umiem?
    Zapytaj Claude RozwińPrzepytaj mniePytania pogłębiające
  4. Jak działa Redux Toolkit: slice, reducer, akcja, selector?

    Moja odpowiedź

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

    Pokaż odpowiedź

    Dla przedszkolaka: Jest jedna wielka skrzynia. Nie wolno jej grzebać rękami. Wrzucasz karteczkę z prośbą (akcja), a opiekun skrzyni (reducer) robi zmianę. Selektor to okienko, przez które patrzysz tylko na swoją przegródkę.

    Na rozmowę: createSlice definiuje fragment stanu z initialState i reducerami. Generuje creatory akcji i reducer, a Immer pozwala pisać „mutujący” kod, który pod spodem jest niemutowalny. configureStore składa slice’y, dodaje DevTools i middleware. Komponent wysyła dispatch(addItem(x)) i czyta useSelector(selectCartTotal), renderując się tylko przy zmianie wyniku selektora. Asynchroniczność: createAsyncThunk albo lepiej RTK Query do danych z API.

    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

Stan współdzielony między mikrofrontendami

Sklep składa się z 4 mikrofrontendów ładowanych przez Module Federation: nagłówek z koszykiem, katalog, karta produktu i checkout. Każdy ma swój zespół i swoje wydania. Koszyk w nagłówku nie aktualizuje się po dodaniu produktu w katalogu, a jeden zespół proponuje wspólny store Reduxa dla wszystkich.

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 rozumiesz koszt sprzężenia między niezależnie wdrażanymi aplikacjami
  • Czy znasz sposoby komunikacji: zdarzenia, kontrakt, źródło prawdy na serwerze
  • Czy myślisz o wersjonowaniu kontraktu

Odpowiedź seniora

Wspólny store to wspólne wdrażanie w przebraniu: zmiana kształtu stanu w jednym zespole psuje pozostałe, a singletony Reduxa w Module Federation łatwo zdublować. Źródłem prawdy dla koszyka jest serwer, a mikrofrontendy komunikują się zdarzeniami.

Katalog po dodaniu produktu wysyła żądanie do API koszyka, a po sukcesie emituje zdarzenie cart:updated (CustomEvent na window albo mały event bus z typami w paczce kontraktów). Nagłówek nasłuchuje i odświeża swój stan, np. invalidateQueries w TanStack Query. Każdy mikrofrontend ma własny, prywatny stan i własną kopię danych z API.

Kontrakt zdarzeń jest w osobnej, wersjonowanej paczce z typami TypeScript i schematem, a zmiana łamiąca oznacza nowe zdarzenie (cart:updated.v2) i okres przejściowy. Dla danych naprawdę globalnych i rzadko zmiennych (zalogowany użytkownik, język) host przekazuje je przez propsy przy montowaniu.

Typowe wpadki

  • Jeden globalny store dla niezależnie wdrażanych aplikacji
  • Komunikacja przez wzajemne importy modułów
  • Brak wersjonowania kontraktu zdarzeń

Dopytają o

  • Co jeśli zdarzenie zostanie wysłane, zanim nagłówek się zamontuje?
  • Jak przetestujesz integrację czterech zespołów?
  • Kiedy mikrofrontendy w ogóle nie mają sensu?
Zapytaj Claude Rozwiń caseZagraj interviewera
Przypadek 2

Synchronizacja między kartami i praca offline

Aplikacja dla przedstawicieli handlowych działa w terenie przy słabym zasięgu. Użytkownicy mają kilka otwartych kart, zbierają zamówienia offline i oczekują, że po powrocie sieci wszystko się wyśle. Teraz zdarzają się zdublowane zamówienia i nadpisane zmiany.

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 znasz narzędzia przeglądarki: IndexedDB, BroadcastChannel, Service Worker
  • Czy projektujesz kolejkę operacji z idempotencją
  • Czy myślisz o konfliktach i ich rozwiązywaniu

Odpowiedź seniora

Lokalnym źródłem prawdy jest IndexedDB (np. przez Dexie), a nie pamięć karty. Każda zmiana trafia do kolejki operacji (outbox) z unikalnym id generowanym na kliencie. Wysyłaniem zajmuje się jeden proces: Service Worker z Background Sync albo karta wybrana jako lider przez Web Locks API, żeby dwie karty nie wysyłały tej samej kolejki.

Karty synchronizują się przez BroadcastChannel: po zapisie w IndexedDB wysyłam komunikat, a pozostałe karty odświeżają widok. Serwer przyjmuje operacje idempotentnie po id, więc ponowne wysłanie po zerwaniu nie tworzy duplikatu.

Konflikty: rekordy mają wersję (updatedAt lub numer wersji). Gdy serwer ma nowszą, zwraca konflikt i pokazuję użytkownikowi obie wersje albo stosuję regułę biznesową ustaloną z produktem. W UI zawsze widać stan synchronizacji: zapisane lokalnie, wysyłanie, wysłane, błąd z możliwością ponowienia.

Typowe wpadki

  • Trzymanie danych offline w localStorage
  • Wysyłanie kolejki z każdej karty osobno
  • Brak idempotencji po stronie serwera
  • Ignorowanie konfliktów zasadą „ostatni wygrywa” bez zgody biznesu

Dopytają o

  • Co jeśli przeglądarka wyczyści IndexedDB z braku miejsca?
  • Jak przetestujesz scenariusze utraty sieci w CI?
  • Kiedy warto sięgnąć po CRDT?
Zapytaj Claude Rozwiń caseZagraj interviewera
Przypadek 3

Zaawansowane filtry w URL

Wyszukiwarka ofert ma 25 filtrów, sortowanie, paginację i widok mapy. Użytkownicy skarżą się, że link wysłany koledze otwiera pustą wyszukiwarkę, przycisk Wstecz nie działa, a analitycy nie mogą odtworzyć wyszukiwań. Filtry siedzą teraz w Reduxie.

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 URL jako właściwe źródło prawdy dla tego stanu
  • Czy myślisz o serializacji, walidacji i domyślnych wartościach
  • Czy pamiętasz o historii, wydajności i SEO

Odpowiedź seniora

Filtry, sortowanie i strona to stan, który ma być udostępniany i przeżyć odświeżenie, więc źródłem prawdy jest URL. Redux zostaje dla stanu ulotnego (otwarty panel filtrów), a dane wyników pobiera TanStack Query z kluczem zbudowanym z parametrów URL.

Parametry parsuję i waliduję schematem (Zod albo biblioteka nuqs z typowanymi parserami), a wartości domyślnych nie zapisuję w URL, żeby linki były krótkie. Zmiana filtra to router.replace przy wpisywaniu tekstu (z debounce) i push przy wyborze z listy, żeby Wstecz cofał sensowne kroki, a nie każdą literę. Zmiana filtra resetuje stronę do 1.

Na serwerze (SSR lub RSC) te same parametry pozwalają wyrenderować wyniki od razu, co pomaga SEO i pierwszemu widokowi. Popularne kombinacje mogą mieć kanoniczne, ładne adresy. Analityka dostaje parametry z URL bez dodatkowego kodu.

Typowe wpadki

  • Synchronizacja Redux z URL w obie strony, która kończy się pętlą
  • Push do historii przy każdej literze
  • Brak walidacji, przez co ręcznie zmieniony link wywraca stronę

Dopytają o

  • Jak obsłużysz filtr z wieloma wartościami i zakresem?
  • Co z bardzo długim URL przy 25 filtrach?
  • Jak uniknąć podwójnego pobrania danych po hydratacji?
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.