Zobrazení výsledků práce thunk v komponentě v Reduxu
V minulé lekci jsme odeslali POST-požadavek
pomocí thunk addProduct. Nyní pojďme
zobrazit výsledky jeho práce v komponentě.
Otevřeme naši aplikaci s produkty a v ní
soubor NewProductForm.jsx, protože tato
komponenta je zodpovědná za přidání nového
produktu. Podívejme se na řádky s importy.
Nahradíme import akce productAdded
importem thunk addProduct:
import { addProduct } from './productsSlice'
Nyní, protože ve slicu nesledujeme stav
'pending' požadavku, udělejme to,
aby uživatel mohl kliknout na tlačítko
uložení produktu pouze jednou, protože
nechceme stejné opakované požadavky.
K tomu zavedeme další lokální stav:
const [requestStatus, setRequestStatus] = useState('idle')
Dále po obslužných funkcích a před funkcí
onSaveProductClick napíšeme kód, ve kterém
zkontrolujeme, zda jsou všechna pole formuláře vyplněna
a zda je stav požadavku 'idle':
const canBeSaved =
[name, desc, price, amount, sellerId].every(Boolean) &&
requestStatus === 'idle'
Poté změníme kód pro onSaveProductClick. Za prvé
to bude asynchronní funkce a bude se provádět,
pokud platí výše uvedená podmínka:
const onSaveProductClick = async () => {
if (canBeSaved) {}
}
Přestože ve slicu nesledujeme stav
'rejected', stejně můžeme vypsat
chybu do konzole, k tomu použijeme
konstrukci try-catch.
Zde také přidáme finally,
abychom po provedení požadavku znovu nastavili
lokální stav na 'idle':
const onSaveProductClick = async () => {
if (canBeSaved) {
try {
} catch (err) {
console.error(save product error: , err)
} finally {
setRequestStatus('idle')
}
}
}
S bloky catch a finally jsme se vypořádali, pojďme
napsat kód pro blok try. Zde nastavíme lokální
stav na 'in pogress', dokud se nám nevrátí
nějaká odpověď jako výsledek práce thunk,
poté odešleme náš thunk addProduct. Použít
konstrukci try-catch v závislosti
na typu odpovědi nám pomůže funkce RTK unwrap,
kterou přidává k vrácenému promisu.
Poté, pokud byl požadavek úspěšný, nastavíme
lokální stavy do jejich výchozích stavů. Úplný
kód pro onSaveProductClick bude vypadat takto:
const onSaveProductClick = async () => {
if (canBeSaved) {
try {
setRequestStatus('in progress')
await dispatch(
addProduct({ name, desc, price, amount, seller: sellerId })).unwrap()
setName('')
setDesc('')
setPrice(0)
setAmount(0)
setSellerId('')
} catch (err) {
console.error('save product error: ', err)
} finally {
setRequestStatus('idle')
}
}
}
Spusťme naši aplikaci a zkusme přidat nový produkt. Jak vidíte, v případě úspěšného požadavku se pole vyčistí a nový produkt se přidá do seznamu produktů. Také se v prohlížeči podívejte do Redux DevTools a projděte si jeho záložky, podívejte se na akce a jak se mění váš stav.
Otevřete vaši aplikaci se studenty.
Otevřete v ní soubor NewStudentForm.jsx.
Přidejte další lokální stav requestStatus,
a nastavte jej zpočátku na 'idle'.
Po seznámení s materiály lekce zaveďte
proměnnou canBeSaved, pomocí které
tlačítko uložení nových dat studenta bude
fungovat/nefungovat, v závislosti na hodnotě
requestStatus a na vyplněnosti polí.
Napište asynchronní kód pro onSaveStudentClick,
který bude měnit hodnotu requestStatus
podle situace, odesílat thunk addProduct
s daty nového studenta, čistit pole
v případě úspěšného požadavku a vypisovat do
konzole chybu v případě neúspěchu,
jak je ukázáno v lekci. Použijte k tomu
konstrukci try-catch a funkci RTK
unwrap.
Spusťte vaši aplikaci, přidejte nového studenta a ujistěte se, že vše funguje.