Εφαρμογή της κατάστασης αιτήματος στο Redux
Στα προηγούμενα μαθήματα χρησιμοποιήσαμε πρόσθετους
reducers για να περιγράψουμε τι πρέπει να κάνει η εφαρμογή μας,
αν το fetchProducts στέλνει κατά το αίτημα
actions pending, fulfilled και
rejected. Τώρα μπορούμε
να δείξουμε στον χρήστη σε ποιο στάδιο
βρίσκεται τώρα η φόρτωση των δεδομένων.
Ας ανοίξουμε την εφαρμογή μας με
προϊόντα, και σε αυτή το αρχείο ProductsList.jsx.
Το πρώτο πράγμα που θα κάνουμε, είναι να δημιουργήσουμε ένα ξεχωριστό
component για την κάρτα προϊόντος ProductCard.
Θα το κάνουμε αμέσως μετά τις γραμμές εισαγωγής πριν από
τη συνάρτηση ProductsList. Ως props
θα του περάσουμε product:
const ProductCard = ({ product }) => {
return ()
}
Και τώρα στις κενές κυκλικές αγκύλες return
θα μεταφέρουμε όλο τον κώδικα για την εμφάνιση δεδομένων
προϊόντος από το 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>
)
}
Και θα αφαιρέσουμε στο ProductsList την υπόλοιπη γραμμή
κώδικα. Δεν τη χρειαζόμαστε πλέον:
const dispProducts = products.map((product) => ())
Και τώρα στην αρχή του κώδικα της συνάρτησης ProductsList
θα δημιουργήσουμε μερικές ακόμη μεταβλητές, error και
content. Η πρώτη θα είναι για το σφάλμα,
στη δεύτερη θα εγγράφουμε το ένα ή το άλλο
περιεχόμενο ανάλογα με την κατάσταση του αιτήματος.
Θα το κάνουμε πριν από το const dataFetch = useRef(false):
const error = useSelector((state) => state.products.error)
let content
Τώρα πριν από την εντολή return του component
ProductsList θα γράψουμε ένα block κώδικα
με συνθήκες, υπό τις οποίες στο content θα
εισάγεται το ένα ή το άλλο περιεχόμενο
ανάλογα με την κατάσταση. Πρώτα θα περιγράψουμε
την κατάσταση 'in progress' - όταν το αίτημά μας
αποστέλλεται. Σε αυτήν την περίπτωση θα ενημερώσουμε
τον χρήστη, ότι γίνεται φόρτωση δεδομένων:
if (productStatus === 'in progress') {
content = <p>Products list loading ...</p>
}
Αν η φόρτωσή μας πέτυχε (το συμβολίσαμε
ως 'success'), τότε πρέπει να εμφανίσουμε
τη λίστα των προϊόντων που ελήφθησαν. Θα την εμφανίσουμε
σε map με τη βοήθεια του component ProductCard,
στον οποίο ως props θα περάσουμε 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} />
))
}
Και η τελευταία κατάσταση, που έχουμε -
αυτή είναι 'fail'. Θα την προσθέσουμε κι αυτή. Θα χρησιμοποιήσουμε εδώ
τη μεταβλητή error, στην οποία καταγράψαμε παραπάνω
το σφάλμα από το 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>
}
Και ως τελευταίο βήμα στο block κώδικα για return
θα αντικαταστήσουμε το παλιό {dispProducts} με {content}.
Ας εκκινήσουμε την εφαρμογή μας, ας κλικάρουμε στο menu
στο 'Products'. Όλα λειτουργούν. Βλέπουμε,
ότι για περίπου 2 δευτερόλεπτα (όπως
ορίσαμε στον server) κάτω από τη φόρμα
προσθήκης προϊόντος εμφανίζεται η επιγραφή
'Products list loading ...',
και μετά εμφανίζεται η λίστα των προϊόντων.
Ανοίξτε την εφαρμογή σας με τους μαθητές.
Ανοίξτε σε αυτή το αρχείο StudentsList.jsx.
Δημιουργήστε σε αυτό ένα νέο component
StudentCard. Μεταφέρετε σε αυτόν τον κώδικα από
το dispStudents, όπως φαίνεται στο μάθημα.
Δημιουργήστε στη συνάρτηση StudentsList
μεταβλητές error και content. Αναθέστε
στη μεταβλητή content περιεχόμενο
ανάλογα με την κατάσταση του αιτήματος. Μην
ξεχάσετε να αντικαταστήσετε στο επιστρεφόμενο markup
το παλιό dispStudents με content.