Úvod do thunks v Redux

V předchozí kapitole jsme zorganizovali práci serveru, databáze a klienta pro výměnu dat. Nyní musíme postavit poslední můstek, který pomůže naší 'synchronně' organizované Redux aplikaci interagovat s asynchronním klientem, kterého jsme vytvořili v poslední lekci předchozí kapitoly, aby bylo možné odesílat požadavky a získávat potřebná data v odpovědi.

Jak si pamatujeme z prvních lekcí předchozí části, Redux nic neví o práci s asynchronní logikou a k tomu budeme používat thunk middleware. Tento middleware umožňuje pracovat s odeslanými actions, používat v kódu našeho thunk dispatch a getState metody store, a také pomáhat metodě dispatch pracovat nejen s běžnými JS objekty, ale také s entitami, jako jsou funkce a promise.

Obvykle je thunk-funkce volána se dvěma argumenty dispatch a getState (pokud je to nutné), které lze používat v těle této funkce. S její pomocí lze odesílat běžné akce. Také ji lze odesílat přes store.dispatch. Příklad takové funkce je uveden níže:

jsxconst changeColorThunk = (dispatch, getState) => {
  const colorBefore = getState()
  console.log(`Stará barva: ${colorBefore.color}`)
  
  dispatch(changeColor())
  
  const colorAfter = getState()
  console.log(`Nová barva: ${colorAfter.color}`)
}

store.dispatch(changeColorThunk)

Nyní otevřeme naši aplikaci s produkty. První věc, kterou musíme získat od serveru při spuštění aplikace - je seznam produktů. Protože thunks se obvykle píší v slice souborech, otevřeme soubor productsSlice.js.

Radostná zpráva spočívá v tom, že nám není třeba se zabývat instalací Redux Thunk, protože funkce configureStore z RTK to již udělá za nás. Proto jednoduše přidáme createAsyncThunk do importu v souboru:

products/productsSlice.jsimport { createSlice, nanoid, createAsyncThunk } from '@reduxjs/toolkit'

Přidejme také do importu našeho klienta:

products/productsSlice.jsimport { client } from '../../api/client'

A nyní pomocí createAsyncThunk vytvoříme náš první thunk pro získání produktů, uděláme to ihned po deklaraci objektu initialState:

products/productsSlice.jsexport const fetchProducts = createAsyncThunk()

První parametr createAsyncThunk bude přijímat řetězec pro typ generované action, a druhým - callback funkci pro payload, která ve výsledku vrátí buď data, nebo promise s chybou (vizte soubor client.js). V kódu funkce voláme client.get a předáme mu cestu, kterou jsme uvedli na serveru (podívejte se na přijímané parametry http.get v server.js):

products/productsSlice.jsexport const fetchProducts = createAsyncThunk(
  'products/fetchProducts',
  async () => {
    const response = await client.get('/fakeServer/products')
    return response.data
  }
)
Задание 1

Otevřete vaši aplikaci se studenty. Otevřete v ní soubor studentsSlice.js. Importujte do něj funkci createAsyncThunk pro vytvoření thunk, a také client pro odesílání API požadavků na server.

Задание 2

Ihned po deklaraci objektu initialState pomocí createAsyncThunk vytvořte thunk fetchStudents pro získání seznamu studentů, který bude odesílat GET-požadavek na adresu /fakeServer/students, uvedenou ve vašem souboru server.js, a vracet response.data, jak je ukázáno v materiálech lekce. Jako první parametr pro createAsyncThunk uveďte řetězec students/fetchStudents pro typ action.