Redux: wzorzec zarządzania stanem w React Native

Autor: IT Sectr Opublikowano: 2026-02-19 Czas czytania: 8 min

Redux — przewidywalny kontener do zarządzania stanem dla aplikacji JavaScript, stworzony przez Dana Abramova w 2015 roku. Redux implementuje jednokierunkowy przepływ danych oparty na architekturze Flux: stan przechowywany jest w pojedynczym Store, zmieniany tylko przez czyste funkcje Reducer i inicjowany przez Action z Dispatch. Według danych npm Trends, Redux utrzymuje ponad 7 milionów tygodniowych pobrań, pozostając standardem zarządzania stanem w React Native i aplikacjach webowych.

Najważniejsze

  • Store — jedyne źródło prawdy, przechowujące całe drzewo stanu aplikacji
  • Action — obiekt z polem type, opisujący zamiar zmiany stanu
  • Reducer — czysta funkcja (prevState, action) => newState bez efektów ubocznych
  • Dispatch — metoda Store do wysyłania Action do Reducer
  • Middleware — warstwa pośrednia między dispatch a reducer dla operacji asynchronicznych i logowania

Czym jest Redux?

Redux — wzorzec architektoniczny i biblioteka do zarządzania stanem, oparty na trzech zasadach: jedyne źródło prawdy (single source of truth), stan tylko do odczytu (read-only) i zmiany przez czyste funkcje. W przeciwieństwie do MVC, gdzie model może zmieniać stan w nieprzewidywalny sposób, Redux gwarantuje determinizm: przy tych samych danych wejściowych wynik jest zawsze taki sam.

Redux został zainspirowany architekturą Flux od Facebooka i językiem Elm. Główna różnica w stosunku do Flux — pojedynczy Store zamiast wielu. W Redux cały stan aplikacji — obiekty, tablice, flagi ładowania — przechowywany jest w jednym drzewie. Upraszcza to debugowanie, testowanie i przywracanie stanu (time-travel debugging). Deweloper może zapisać cały Store, odtworzyć sekwencję Action i zobaczyć, jak zmieniał się stan na każdym kroku.

Według danych State of JS 2025, 68% respondentów korzystających z zarządzania stanem wybiera Redux lub Redux Toolkit. Narzędzie jest wspierane przez wszystkie nowoczesne frameworki: React, React Native, Angular, Vue, a nawet czysty JavaScript bez frameworków.

Jednokierunkowy przepływ danych

Unidirectional data flow — kluczowa zasada Redux, w której dane poruszają się ściśle w jednym kierunku: View → Action → Dispatch → Reducer → Store → View. Żaden komponent nie może bezpośrednio zmienić Store. View tylko subskrybuje zmiany przez useSelector lub connect i inicjuje zmiany przez dispatch.

Cykl działania Redux: użytkownik naciska przycisk → komponent wywołuje dispatch({ type: 'INCREMENT' }) → Store przekazuje Action do Root Reducer → Reducer oblicza nowy stan → Store powiadamia subskrybentów → View przerysowuje się z nowymi danymi. Ten cykl gwarantuje, że każda zmiana ma wyraźną przyczynę w postaci konkretnego Action.

DevTools — wbudowane narzędzie Redux do monitorowania każdego Action, stanu Store i czasu wykonania. Deweloper widzi listę wszystkich wysłanych Action, różnicę stanu (diff) przed i po, oraz może cofnąć się do dowolnego poprzedniego stanu. To sprawia, że debugowanie złożonych stanów jest dziesiątki razy szybsze w porównaniu do zwykłego logowania.

Kluczowe komponenty Redux

Store — obiekt zawierający pełne drzewo stanu. Tworzony przez configureStore (RTK) lub createStore. Store udostępnia trzy metody: getState() do odczytu, dispatch(action) do zmiany i subscribe(listener) do subskrypcji. W Redux Toolkit Store zawiera już middleware, DevTools i obsługę slice'ów.

TypeScript
import { configureStore } from '@reduxjs/toolkit'

interface CounterState {
  value: number
}

const initialState: CounterState = { value: 0 }

function counterReducer(
  state = initialState,
  action: { type: string }
): CounterState {
  switch (action.type) {
    case 'INCREMENT':
      return { value: state.value + 1 }
    default:
      return state
  }
}

const store = configureStore({ reducer: counterReducer })
store.dispatch({ type: 'INCREMENT' })
console.log(store.getState()) // { value: 1 }

Action i Action Creator — Action to obiekt z obowiązkowym polem type (stała string) i opcjonalnym payload (dane). Action Creator — funkcja zwracająca Action. W Redux Toolkit używa się createAction do generowania Action z automatyczną typizacją.

Reducer — czysta funkcja, otrzymująca bieżący stan i Action, zwracająca nowy stan. Reducer nie powinien: mutować state (zwraca nowy obiekt), wywoływać API, generować losowych liczb ani odwoływać się do Date. Niezmienność zapewniana jest przez operator spread ... lub Immer (wbudowany w RTK).

KomponentObowiązekOgraniczenia
StorePrzechowywanie stanu, dispatch, subscribeJeden na aplikację
ActionOpis zamiaru zmiany stanuMusi mieć type
ReducerObliczanie nowego stanuCzysta funkcja, bez efektów ubocznych
DispatchWysyłanie Action do ReducerSynchroniczny domyślnie
SelectorWydobywanie danych z StoreMemoizacja przez createSelector

Middleware i Redux Thunk

Middleware — łańcuch funkcji wstawiany między wywołanie dispatch a moment, gdy Action dociera do Reducer. Każdy middleware otrzymuje API Store i może logować, modyfikować, opóźniać lub anulować Action. Redux Thunk — standardowy middleware dla operacji asynchronicznych, pozwalający dispatch-ować funkcje zamiast obiektów.

JavaScript
import { createAsyncThunk } from '@reduxjs/toolkit'

export const fetchUser = createAsyncThunk(
  'users/fetchById',
  async (userId: number, { rejectWithValue }) => {
    const response = await fetch(`/api/users/${userId}`)
    if (!response.ok)
      return rejectWithValue('Failed to fetch')
    return await response.json()
  }
)

Popularne middleware: Redux Thunk — dla prostych wywołań asynchronicznych, Redux Saga — dla złożonych scenariuszy z sagami-generatorami (debounce, race, równoległe zapytania), Redux Observable — oparty na RxJS dla reaktywnych strumieni. W Redux Toolkit middleware podłącza się przez parametr middleware w configureStore.

Według danych ankiety State of JS 2025, Thunk jest używany w 72% projektów Redux, Saga — w 18%, Observable — w 5%. Dla większości aplikacji kombinacja Thunk + RTK Query wystarcza, aby pokryć 95% scenariuszy asynchronicznej pracy z danymi.

Redux Toolkit i RTK Query

Redux Toolkit (RTK) — oficjalny, zalecany sposób pisania logiki Redux, wydany w 2019 roku. RTK zawiera configureStore, createSlice, createAsyncThunk i createEntityAdapter, redukując boilerplate Redux o 60-70%. Zamiast ręcznego tworzenia Action Creator, Reducer i typów używa się jednego createSlice.

TypeScript
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment(state) { state.value += 1 },
    incrementByAmount(state, action: PayloadAction<number>) {
      state.value += action.payload
    }
  }
})

export const { increment, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer

RTK Query — wbudowane rozwiązanie do pracy z API oparte na Redux Toolkit. Pozwala definiować endpointy deklaratywnie przez createApi z automatycznym generowaniem hooków, cache'owaniem, unieważnianiem tagów i optymistycznymi aktualizacjami. RTK Query zastępuje ręczne pisanie Thunk, Reducer i Selector dla każdego zapytania API.

Entity Adapter — narzędzie createEntityAdapter do normalizacji kolekcji encji. Dostarcza wbudowane reducery CRUD, selektory i sortowanie dla tablic obiektów. Jeśli w Store przechowywane są listy użytkowników, produktów lub zamówień — Entity Adapter redukuje kod redukcji o 80%.

Redux w React Native

React Native Redux — standardowe połączenie dla aplikacji mobilnych w JavaScript. Redux integruje się przez Provider z react-redux, otaczający główny komponent aplikacji. Hooki useSelector i useDispatch dają komponentom dostęp do stanu bez props drilling. Persistredux-persist zapisuje Store w AsyncStorage lub MMKV, przywracając stan po restarcie aplikacji.

Middleware dla React Native: redux-flipper do debugowania przez Flipper, redux-observable dla reaktywnych strumieni z natywnymi sterownikami, react-native-mmkv dla szybkiego trwałego przechowywania. Wtyczka nawigacyjna redux-first-router łączy ekrany ze Store, umożliwiając przywracanie stanu ekranu po powrocie.

W React Native Redux jest używany razem ze strategią network-first: aplikacja najpierw próbuje załadować dane z serwera, następnie cache'uje w Store przez RTK Query lub redux-persist. Tryb offline osiągany jest przez kombinację Redux + NetInfo + kolejki Action do ponownego wysłania po przywróceniu połączenia.

Często zadawane pytania

Czym Redux różni się od Context API w React?

Redux — pełnoprawne rozwiązanie z Store, DevTools, Middleware i niezmiennym stanem. Context API — wbudowany mechanizm React do przesyłania danych bez props drilling. Context nadaje się do globalnych motywów i lokalizacji, Redux — do złożonego stanu z operacjami asynchronicznymi, cache'owaniem i debugowaniem. W dużych aplikacjach Context powoduje niepotrzebne przerenderowania, Redux z selektorami rozwiązuje ten problem.

Czym jest Immer w Redux Toolkit?

Immer — biblioteka do niezmiennej pracy ze stanem, wbudowana w Redux Toolkit. Immer pozwala pisać reducery tak, jakbyś bezpośrednio mutował state: state.value += 1. Pod maską Immer tworzy obiekt proxy (draft), śledzi zmiany i zwraca nowy niezmienny obiekt. Zmniejsza to objętość kodu reducertów o 50% i eliminuje przypadkowe mutacje.

Jak testować Redux?

Logika Redux jest testowana izolowanie: Reducer — czysta funkcja, wystarczy wywołać z różnymi Action i sprawdzić wynik. Action Creator — sprawdzić zwracany obiekt. Thunk — zamokować API, wywołać dispatch i sprawdzić, które Action zostały wysłane. Komponent z useSelector — użyć Provider z testowym Store w rendererze. Redux DevTools pomagają napisać test, odtwarzając sekwencję Action z rzeczywistej sesji.

Kiedy używać Redux zamiast useState?

useState wystarcza do lokalnego stanu jednego komponentu: tekst pola, otwarty/zamknięty modal. Redux jest potrzebny, gdy stan jest współdzielony między wieloma ekranami, wymaga asynchronicznej synchronizacji (dane z serwera), powinien być zachowany między restartami aplikacji (persist) lub wymaga debugowania time-travel. Dla małych aplikacji Redux jest zbędny — użyj Context + useReducer.

Czym jest normalize w Redux?

Normalizr — biblioteka do normalizacji zagnieżdżonych danych w płaską strukturę Store. Zamiast przechowywania głębokich obiektów typu user.posts[0].comments, normalizacja tworzy słowniki: entities.users, entities.posts, entities.comments z odnośnikami po ID. Upraszcza to aktualizację jednej encji we wszystkich miejscach i przyspiesza selektory. Redux Toolkit zaleca znormalizowane dane dla złożonych modeli.

Podsumowanie

  • Redux — przewidywalny kontener stanu z pojedynczym Store i czystymi Reducer
  • Action — obiekt z type, Reducer — czysta funkcja, Dispatch — mechanizm wysyłania
  • Redux Toolkit — oficjalne API z createSlice, createAsyncThunk i RTK Query
  • Middleware — warstwa pośrednia dla asynchroniczności: Thunk, Saga, Observable
  • React Native integruje się przez Provider, useSelector i redux-persist dla trybu offline
  • DevTools — time-travel debugging z odtwarzaniem każdego Action
  • Normalizr — normalizacja danych dla efektywnych selektorów i aktualizacji

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również