Úvod do thunks v Reduxe

V predchádzajúcej kapitole sme zorganizovali prácu servera, databázy a klienta pre výmenu dát. Teraz potrebujeme vybudovať posledný mostík, ktorý pomôže nej 'synchrónne' organizovanej Redux aplikácii interagovať s asynchrónnym klientom, ktorého sme vytvorili na poslednej lekcii predchádzajúcej kapitoly, na odosielanie požiadaviek a získavanie potrebných dát v odpovedi.

Ako si pamätáme z prvých lekcií predchádzajúcej časti, Redux nevie nič o práci s asynchrónnou logikou a preto budeme používať thunk middleware. Tento middleware umožňuje pracovať s odoslanými actions, používať v kóde nášho thunk dispatch a getState metódy store, a tiež pomáhať metóde dispatch pracovať nielen s bežnými JS objektmi, ale aj s takými entitami, ako funkcie a promises.

Zvyčajne thunk-funkcia je volaná s dvoma argumentami dispatch a getState (pokiaľ je to potrebné), ktorými je možné používať v tele tejto funkcie. S jej pomocou je možné odosielať bežné akcie. Tiež ju je možné odosielať cez store.dispatch. Príklad takejto funkcie je uvedený nižšie:

jsxconst changeColorThunk = (dispatch, getState) => {
  const colorBefore = getState()
  console.log(`Old Color: ${colorBefore.color}`)
  
  dispatch(changeColor())
  
  const colorAfter = getState()
  console.log(`New Color: ${colorAfter.color}`)
}

store.dispatch(changeColorThunk)

Poďme teraz otvoriť našu aplikáciu s produktmi. Prvá vec, ktorú musíme dostať od servera pri spustení aplikácie - to je zoznam produktov. Keďže zvyčajne thunks sa píšu v slice súboroch, tak otvoríme súbor productsSlice.js.

Radosťou správa spočíva v tom, že nemusíme sa trápiť s inštaláciou Redux Thunk, pretože funkcia configureStore z RTK to už urobí za nás. Preto jednoducho pridajme createAsyncThunk do importu v súbore:

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

Pridajme tiež do importu nášho klienta:

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

A teraz pomocou createAsyncThunk vytvorme náš prvý thunk na získanie produktov, urobme to hneď po deklarovaní objektu initialState:

products/productsSlice.jsexport const fetchProducts = createAsyncThunk()

Prvým parametrom createAsyncThunk bude prijímať reťazec pre typ generovaného action, a druhým - callback funkciu pre payload, ktorá v dôsledku vráti buď dáta, alebo promise s chybou (pozrite si súbor client.js). V kóde funkcie sme voláme client.get a odovzdáme mu cestu, ktorú sme uviedli na serveri (pozrite si prijímané parametre 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

Otvorte vašu aplikáciu so študentmi. Otvorte v nej súbor studentsSlice.js. Importujte do neho funkciu createAsyncThunk pre vytvorenie thunk, a tiež client pre odosielanie API požiadavok na server.

Задание 2

Hneď po deklarovaní objektu initialState pomocou createAsyncThunk vytvorte thunk fetchStudents na získanie zoznamu študentov, ktorý bude odosielať GET-požiadavku na adresu /fakeServer/students, uvedenú u vás v súbore server.js, a vráti response.data, ako je ukázané v materiáloch lekcie. Ako prvý parameter pre createAsyncThunk uveďte reťazec students/fetchStudents pre typ action.