Utilizzo dello stato della richiesta in Redux
Nelle lezioni precedenti, utilizzando reducer aggiuntivi,
abbiamo descritto cosa deve fare la nostra applicazione
se fetchProducts invia durante la richiesta
le azioni pending, fulfilled e
rejected. Ora possiamo
mostrare all'utente in quale fase
si trova attualmente il caricamento dei dati.
Apriamo la nostra applicazione con i
prodotti, e in essa il file ProductsList.jsx.
La prima cosa che faremo è creare un componente separato
per la scheda del prodotto ProductCard.
Facciamolo subito dopo le righe di importazione prima
della funzione ProductsList. Gli passeremo
product come prop:
const ProductCard = ({ product }) => {
return ()
}
E ora nelle parentesi tonde vuote return
spostiamo tutto il codice per visualizzare i dati
del prodotto da 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>
)
}
E rimuoviamo in ProductsList la riga di codice
rimanente. Non ci serve più:
const dispProducts = products.map((product) => ())
E ora all'inizio del codice della funzione ProductsList
creiamo un altro paio di variabili, error e
content. La prima sarà per l'errore,
nella seconda registreremo l'uno o l'altro
contenuto a seconda dello stato della richiesta.
Facciamolo prima di const dataFetch = useRef(false):
const error = useSelector((state) => state.products.error)
let content
Ora prima del comando return del componente
ProductsList scriviamo un blocco di codice
con le condizioni, in base alle quali in content verrà
inserito l'uno o l'altro contenuto a
seconda dello stato. Per primo descriveremo
lo stato 'in progress' - quando la nostra richiesta
è stata inviata. In questo caso informeremo
l'utente che il caricamento dei dati è in corso:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
}
Se il nostro caricamento è avvenuto con successo (lo abbiamo indicato
come 'success'), allora dobbiamo visualizzare
l'elenco dei prodotti ottenuti. Visualizziamolo
in map tramite il componente ProductCard,
a cui passeremo product come prop:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
} else if (productStatus === 'success') {
content = products.map((product) => (
<ProductCard key={product.id} product={product} />
))
}
E l'ultimo stato che abbiamo è
'fail'. Aggiungiamolo anche. Usiamo qui
la variabile error, in cui sopra abbiamo registrato
l'errore dallo state:
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>
}
E come ultimo passo nel blocco di codice per return
sostituiremo il vecchio {dispProducts} con {content}.
Avviamo la nostra applicazione, clicchiamo nel menu
su 'Products'. Tutto funziona. Vediamo
che per circa 2 secondi (come
abbiamo impostato sul server) sotto il modulo
di aggiunta prodotto compare la scritta
'Products list loading ...',
e poi appare l'elenco dei prodotti.
Apri la tua applicazione con gli studenti.
Apri in essa il file StudentsList.jsx.
Crea in esso un nuovo componente
StudentCard. Sposta in esso il codice da
dispStudents, come mostrato nella lezione.
Crea nella funzione StudentsList
le variabili error e content. Assegna
alla variabile content il contenuto in
base allo stato della richiesta. Non
dimenticare di sostituire nel markup restituito
il vecchio dispStudents con content.