Wykorzystanie statusu żądania w Redux
Na poprzednich zajęciach za pomocą dodatkowych
reducerów opisaliśmy, co ma zrobić nasza aplikacja,
jeśli fetchProducts wysyła podczas żądania
akcje pending, fulfilled i
rejected. Teraz możemy
pokazać użytkownikowi, na jakim etapie
aktualnie znajduje się ładowanie danych.
Otwórzmy naszą aplikację z
produktami, a w niej plik ProductsList.jsx.
Pierwsze, co zrobimy, to utworzymy osobny
komponent dla karty produktu ProductCard.
Zrobimy to zaraz po linijkach importów przed
funkcją ProductsList. Jako props
przekażemy mu product:
const ProductCard = ({ product }) => {
return ()
}
A teraz w puste okrągłe nawiasy return
przenieśmy cały kod do wyświetlania danych
produktu z dispProducts:
const ProductCard = ({ product }) => {
return (
<div key={product.id} className="product-excerpt">
<h3>{product.name}</h3>
<SellerOfProd sellerId={product.seller} />
<p>{product.desc.substring(0, 100)}</p>
<UserReactions product={product} />
<Link to={`/products/${product.id}`} className="link-btn">
view
</Link>
</div>
)
}
I usuniemy w ProductsList pozostałą linię
kodu. Nie jest nam już potrzebna:
const dispProducts = products.map((product) => ())
A teraz na początku kodu funkcji ProductsList
utwórzmy jeszcze parę zmiennych, error i
content. Pierwsza będzie dla błędu,
do drugiej będziemy zapisywać to lub inne
zawartość w zależności od statusu żądania.
Zróbmy to przed const dataFetch = useRef(false):
const error = useSelector((state) => state.products.error)
let content
Teraz przed komendą return komponentu
ProductsList napiszmy blok kodu
z warunkami, przy których w content będzie
zapisywana ta lub inna zawartość w
zależności od statusu. Pierwszy opiszemy
status 'in progress' - gdy nasze żądanie
zostało wysłane. W tym przypadku poinformujemy
użytkownika, że trwa ładowanie danych:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
}
Jeśli nasze ładowanie przebiegło pomyślnie (oznaczaliśmy
to jako 'success'), to musimy wyświetlić
listę otrzymanych produktów. Wyświetlimy ją
w map przy pomocy komponentu ProductCard,
któremu propsem przekażemy product:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
} else if (productStatus === 'success') {
content = products.map((product) => (
<ProductCard key={product.id} product={product} />
))
}
I ostatni status, który mamy -
to 'fail'. Dodajmy i jego. Wykorzystajmy tutaj
zmienną error, do której wyżej zapisaliśmy
błąd ze stanu:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
} else if (productStatus === 'success') {
content = products.map((product) => (
<ProductCard key={product.id} product={product} />
))
} else if (productStatus === 'fail') {
content = <div>{error}</div>
}
I ostatnim krokiem w bloku kodu dla return
zamienimy stary {dispProducts} na {content}.
Uruchommy naszą aplikację, kliknijmy w menu
'Products'. Wszystko działa. Widzimy,
że około 2 sekund (tak jak
ustawiliśmy na serwerze) pod formularzem
dodania produktu wisi napis
'Products list loading ...',
a potem pojawia się lista produktów.
Otwórz twoją aplikację ze studentami.
Otwórz w niej plik StudentsList.jsx.
Utwórz w nim nowy komponent
StudentCard. Przenieś do niego kod z
dispStudents, jak pokazano na lekcji.
Utwórz w funkcji StudentsList
zmienne error i content. Przypisz
zmiennej content zawartość w
zależności od statusu żądania. Nie
zapomnij zamienić w zwracanym kodzie HTML
starego dispStudents na content.